emaildata.cpp
来自「funambol window mobile客户端源代码」· C++ 代码 · 共 296 行
CPP
296 行
/*
* Funambol is a mobile platform developed by Funambol, Inc.
* Copyright (C) 2003 - 2007 Funambol, Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*
* You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
* 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License
* version 3, these Appropriate Legal Notices must retain the display of the
* "Powered by Funambol" logo. If the display of the logo is not reasonably
* feasible for technical reasons, the Appropriate Legal Notices must display
* the words "Powered by Funambol".
*/
#include "base/fscapi.h"
#include "base/Log.h"
#include "base/util/XMLProcessor.h"
#include "base/quoted-printable.h"
#include "syncml/formatter/Formatter.h"
#include "spds/EmailData.h"
#include "base/globalsdef.h"
USE_NAMESPACE
#define EMAIL_READ "read"
#define EMAIL_FORW "forwarded"
#define EMAIL_REPL "replied"
#define EMAIL_TREC "received"
#define EMAIL_TCRE "created"
#define EMAIL_TMOD "modified"
#define EMAIL_DELE "deleted"
#define EMAIL_FLAG "flagged"
#define EMAIL_ITEM "emailitem"
#define EMAIL_ITEM_START "<emailitem"
#define EMAIL_ITEM_END "</emailitem>"
static inline bool checkFlag(const char *xml, const char *field)
{
unsigned int start = 0, end = 0;
bool ret = false;
if( XMLProcessor::getElementContent(xml, field, NULL, &start, &end) ) {
ret = ( strncmp(xml+start, "true", end-start) == 0 ) ;
}
return ret;
}
EmailData::EmailData()
{
read = false;
forwarded = false;
replied = false;
deleted = false;
flagged = false;
remainingBodySize = 0;
remainingAttachNumber = 0;
remainingAttachments = NULL;
extMailData = NULL;
totalEmailSize = 0;
isMailPartial = false;
}
EmailData::~EmailData()
{
if (extMailData) {
delete extMailData;
extMailData = NULL;
}
if (remainingAttachments) {
remainingAttachments->clear();
delete remainingAttachments;
remainingAttachments = NULL;
}
}
/*
* The parse method returns:
* -1: it means the <emailitem> doesn't containt CDATA section. This could be right
* if the <email> is an update from server of flags only, as <read>, <forwarded>...
The rightness must be choosen by the caller. It could be or not an error
*
* -2: it means there is an error into the format of the <emailitem>. It must be treated as an error
*
*/
int EmailData::parse(const char *msg, size_t /* len */)
{
int ret = 0;
unsigned int start = 0, end = 0;
isMailPartial = false;
// Get attributes
read = checkFlag(msg, EMAIL_READ);
forwarded = checkFlag(msg, EMAIL_FORW);
replied = checkFlag(msg, EMAIL_REPL);
deleted = checkFlag(msg, EMAIL_DELE);
flagged = checkFlag(msg, EMAIL_FLAG);
if( XMLProcessor::getElementContent (msg, EMAIL_TREC, NULL, &start, &end) ) {
received = StringBuffer(msg+start, end-start);
}
else received = "";
if( XMLProcessor::getElementContent (msg, EMAIL_TCRE, NULL, &start, &end) ) {
created = StringBuffer(msg+start, end-start);
}
else created = "";
if( XMLProcessor::getElementContent (msg, EMAIL_TMOD, NULL, &start, &end) ) {
modified = StringBuffer(msg+start, end-start);
}
else modified = "";
// Get content
StringBuffer itemtmp(msg);
start = itemtmp.find(EMAIL_ITEM_START);
end = itemtmp.rfind(EMAIL_ITEM_END);
if (start != StringBuffer::npos && end != StringBuffer::npos) {
totalEmailSize = itemtmp.length(); // the size of the current piece of mail
itemtmp = NULL;
//if( XMLProcessor::getElementContent(msg, EMAIL_ITEM, NULL, &start, &end) ) {
StringBuffer item(msg+start, end-start);
unsigned int startAttr=0, endAttr=0;
//currently emailitem is not escaped so false!!
if(XMLProcessor::getElementAttributes(msg, EMAIL_ITEM, &startAttr,
&endAttr, false)) {
StringBuffer attrlist(msg+startAttr, endAttr-startAttr);
if(attrlist.ifind("quoted-printable") != StringBuffer::npos) {
char *decoded = qp_decode(item);
item = decoded;
delete [] decoded;
}
}
// item must start with CDATA
size_t item_start = item.find("![CDATA");
if(item_start > 50){ // it could be <emailitem ENC="QUOTED-PRINTABLE"><![CDATA[
LOG.error("EMailData: can't find inner CDATA section.");
return -1;
}
size_t item_end = item.rfind("]]>");
// In emailitem the last > close the CDATA of emailitem tag and is escaped, so it is needed
// to be found the follow. Usually the first is skipped
//
if(item.length() - item_end > 10){
item_end = item.rfind("]]>");
if(item.length() - item_end > 10){
LOG.error("EMailData: can't find CDATA end tag.");
return -2;
}
}
// okay, move the start pointer to the end of
item_start += strlen("![CDATA[");
ret=emailItem.parse( item.c_str()+item_start, item_end - item_start );
}
else {
LOG.info("EMailData: no <emailitem> tag.");
// It is not an error, just log it for info.
}
/*
char tmpExt[] = "<Ext><XNam>x-funambol-body</XNam><XVal>15000</XVal></Ext> \
<Ext><XNam>x-funambol-attach-n</XNam><XVal>1</XVal></Ext> \
<Ext><XNam>x-funambol-attach</XNam><XVal>att1.txt</XVal><XVal>10000</XVal></Ext>";
*/
//char tmpExt[] = "";
// find the Ext stuffs
if (end != StringBuffer::npos) {
unsigned int pos = end;
unsigned int previous = end;
start = 0, end = 0;
char* ext = NULL;
// for try
//pos = 0;
//while( (ext = XMLProcessor::copyElementContent(&tmpExt[pos], "Ext", &pos)) ) { // for try
while( (ext = XMLProcessor::copyElementContent(&msg[pos], "Ext", &pos)) ) {
char* xnam = XMLProcessor::copyElementContent(ext, "XNam", 0);
if (!xnam)
break;
if (strcmp(xnam, "x-funambol-body") == 0) {
char* val = XMLProcessor::copyElementContent(ext, "XVal", 0);
if (val) {
setRemainingBodySize(atol(val));
totalEmailSize += atol(val);
delete [] val; val = NULL;
isMailPartial = true;
}
} else if (strcmp(xnam, "x-funambol-attach-n") == 0) {
char* val = XMLProcessor::copyElementContent(ext, "XVal", 0);
if (val) {
setRemainingAttachNumber(atol(val));
delete [] val; val = NULL;
isMailPartial = true;
}
} else if (strcmp(xnam, "x-funambol-attach") == 0) {
if (!remainingAttachments) {
remainingAttachments = new ArrayList();
}
extMailData = new ExtMailData();
unsigned int from = 0;
char* val = XMLProcessor::copyElementContent(ext, "XVal", &from);
if (val) {
extMailData->attachName = stringdup(MailMessage::decodeHeader(val).c_str());
delete [] val; val = NULL;
}
val = XMLProcessor::copyElementContent(&ext[from], "XVal", &from);
if (val) {
extMailData->attachSize = atol(val);
totalEmailSize += atol(val);
delete [] val; val = NULL;
}
if (extMailData->attachName && extMailData->attachSize != 0) {
remainingAttachments->add(*extMailData);
isMailPartial = true;
} else {
setRemainingAttachNumber(getRemainingAttachNumber() == 0 ? 0
: (getRemainingAttachNumber() - 1));
}
delete extMailData;
extMailData = NULL;
}
pos += previous;
previous = pos;
if (xnam) {
delete [] xnam; xnam = NULL;
}
if (ext) {
delete [] ext; ext = NULL;
}
}
}
return ret;
}
char *EmailData::format() {
StringBuffer out;
out.reserve(150);
out = "<Email>\n";
out += XMLProcessor::makeElement(EMAIL_READ, read);
out += XMLProcessor::makeElement(EMAIL_FORW, forwarded);
out += XMLProcessor::makeElement(EMAIL_REPL, replied);
out += XMLProcessor::makeElement(EMAIL_TREC, received);
out += XMLProcessor::makeElement(EMAIL_TCRE, created);
out += XMLProcessor::makeElement(EMAIL_TMOD, modified);
out += XMLProcessor::makeElement(EMAIL_DELE, deleted);
out += XMLProcessor::makeElement(EMAIL_FLAG, flagged);
char *item = emailItem.format();
if ( item ) {
out += "<emailitem>\n<![CDATA[";
out += item;
delete [] item;
out += "]]>\n</emailitem>\n";
}
out += "</Email>\n";
return stringdup(out.c_str());
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?