📄 emaildata.cpp
字号:
/*
* 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 General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY, TITLE, NONINFRINGEMENT or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
#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"
#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;
size_t itemlen = end-start;
if(XMLProcessor::getElementAttributes(msg, EMAIL_ITEM, &startAttr, &endAttr, false)){ //currently emailitem is not escaped so 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;
start = 0, end = 0;
unsigned int previous = 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, previous = 0;
char* val = XMLProcessor::copyElementContent(ext, "XVal", &from);
if (val) {
extMailData->attachName = stringdup(val);
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;
}
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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -