61static bool parseOneHeaderLine(
Binc::Header *header,
unsigned int *nlines)
63 using namespace ::
Binc;
75 for (
int i = 0; i < (int) name.length() + 1; ++i)
93 bool endOfHeaders =
false;
94 while (!endOfHeaders) {
100 if (c ==
'\n') ++*nlines;
102 for (
int i = 0; i < 3; ++i)
103 cqueue[i] = cqueue[i + 1];
106 if (strncmp(cqueue,
"\r\n\r\n", 4) == 0) {
114 if (cqueue[2] ==
'\n' && c !=
' ' && c !=
'\t') {
115 if (content.length() > 2)
116 content.resize(content.length() - 2);
119 header->
add(name, content);
123 if (c ==
'\n') --*nlines;
135 if (content.length() > 2)
136 content.resize(content.length() - 2);
137 header->
add(name, content);
140 return !(eof || endOfHeaders);
144static void parseHeader(
Binc::Header *header,
unsigned int *nlines)
146 while (parseOneHeaderLine(header, nlines))
151static void analyzeHeader(
Binc::Header *header,
bool *multipart,
152 bool *messagerfc822,
string *subtype,
string *boundary)
154 using namespace ::
Binc;
160 vector<string> types;
161 split(ctype.getValue(),
";", types);
163 if (types.size() > 0) {
165 string tmp = types[0];
171 key = (v.size() > 0) ? v[0] :
"text";
172 value = (v.size() > 1) ? v[1] :
"plain";
175 if (key ==
"multipart") {
179 }
else if (key ==
"message") {
181 if (value ==
"rfc822")
182 *messagerfc822 =
true;
186 for (vector<string>::const_iterator i = types.begin();
187 i != types.end(); ++i) {
191 if (element.find(
"=") != string::npos) {
192 string::size_type pos = element.find(
'=');
193 string key = element.substr(0, pos);
194 string value = element.substr(pos + 1);
199 if (key ==
"boundary") {
208static void parseMessageRFC822(vector<Binc::MimePart> *members,
209 bool *foundendofpart,
210 unsigned int *bodylength,
211 unsigned int *nbodylines,
212 const string &toboundary)
214 using namespace ::
Binc;
227 if (m.parseFull(toboundary, bsize))
228 *foundendofpart =
true;
232 if (*bodylength >= bodystartoffsetcrlf) {
233 *bodylength -= bodystartoffsetcrlf;
234 if (*bodylength >= (
unsigned int) bsize) {
235 *bodylength -= (
unsigned int) bsize;
243 *nbodylines += m.getNofLines();
245 members->push_back(m);
248static bool skipUntilBoundary(
const string &delimiter,
249 unsigned int *nlines,
bool *eof)
251 int endpos = delimiter.length();
252 char *delimiterqueue = 0;
253 int delimiterpos = 0;
254 const char *delimiterStr = delimiter.c_str();
255 if (delimiter !=
"") {
256 delimiterqueue =
new char[endpos];
257 memset(delimiterqueue, 0, endpos);
265 bool foundBoundary =
false;
272 if (c ==
'\n') ++*nlines;
276 if (!delimiterqueue)
continue;
278 delimiterqueue[delimiterpos++ % endpos] = c;
281 delimiterpos, endpos)) {
282 foundBoundary =
true;
287 delete[] delimiterqueue;
290 return foundBoundary;
294static void parseMultipart(
const string &boundary,
295 const string &toboundary,
297 unsigned int *nlines,
299 bool *foundendofpart,
300 unsigned int *bodylength,
301 vector<Binc::MimePart> *members)
303 using namespace ::
Binc;
311 string delimiter =
"--" + boundary;
313 skipUntilBoundary(delimiter, nlines, eof);
315 if (!eof) *boundarysize = delimiter.size();
322 if (a ==
'\n') ++*nlines;
326 if (b ==
'\n') ++*nlines;
331 if (a ==
'-' && b ==
'-') {
332 *foundendofpart =
true;
336 if (a ==
'\n') ++*nlines;
338 if (b ==
'\n') ++*nlines;
341 if (a ==
'\r' && b ==
'\n') {
347 else if (a ==
'-' && b ==
'-') {
365 if (!*foundendofpart && !*eof) {
373 if (m.parseFull(boundary, bsize)) {
375 *boundarysize = bsize;
378 members->push_back(m);
383 if (!*foundendofpart && !*eof) {
389 string delimiter =
"\r\n--" + toboundary;
391 skipUntilBoundary(delimiter, nlines, eof);
393 if (!*eof) *boundarysize = delimiter.size();
400 if (a ==
'\n') ++*nlines;
404 if (b ==
'\n') ++*nlines;
409 if (a ==
'-' && b ==
'-') {
410 *foundendofpart =
true;
422 if (a ==
'\r' && b ==
'\n') {
428 else if (a ==
'-' && b ==
'-') {
448 if (*bodylength >= bodystartoffsetcrlf) {
449 *bodylength -= bodystartoffsetcrlf;
450 if (*bodylength >= (
unsigned int) *boundarysize) {
451 *bodylength -= (
unsigned int) *boundarysize;
460static void parseSinglePart(
const string &toboundary,
462 unsigned int *nbodylines,
463 unsigned int *nlines,
464 bool *eof,
bool *foundendofpart,
465 unsigned int *bodylength)
467 using namespace ::
Binc;
473 if (toboundary !=
"") {
474 _toboundary =
"\r\n--";
475 _toboundary += toboundary;
481 char *boundaryqueue = 0;
482 int endpos = _toboundary.length();
483 if (toboundary !=
"") {
484 boundaryqueue =
new char[endpos];
485 memset(boundaryqueue, 0, endpos);
491 const char *_toboundaryStr = _toboundary.c_str();
493 bool toboundaryIsEmpty = (toboundary ==
"");
496 if (c ==
'\n') { ++*nbodylines; ++*nlines; }
497 if (toboundaryIsEmpty)
continue;
500 boundaryqueue[boundarypos++ % endpos] = c;
503 boundarypos, endpos)) {
504 *boundarysize = _toboundary.length();
509 delete[] boundaryqueue;
511 if (toboundary !=
"") {
515 if (a ==
'\n') ++*nlines;
519 if (b ==
'\n') ++*nlines;
521 if (a ==
'-' && b ==
'-') {
523 *foundendofpart =
true;
525 if (a ==
'\n') ++*nlines;
527 if (b ==
'\n') ++*nlines;
530 if (a ==
'\r' && b ==
'\n') {
536 else if (a ==
'-' && b ==
'-') {
555 if (*bodylength >= bodystartoffsetcrlf) {
556 *bodylength -= bodystartoffsetcrlf;
557 if (*bodylength >= (
unsigned int) *boundarysize) {
558 *bodylength -= (
unsigned int) *boundarysize;
570 int &boundarysize)
const
575 parseHeader(&h, &nlines);
585 analyzeHeader(&h, &multipart, &messagerfc822, &subtype, &boundary);
588 bool foundendofpart =
false;
591 parseMessageRFC822(&members, &foundendofpart, &bodylength,
592 &nbodylines, toboundary);
594 }
else if (multipart) {
595 parseMultipart(boundary, toboundary, &eof, &nlines, &boundarysize,
596 &foundendofpart, &bodylength, &members);
598 parseSinglePart(toboundary, &boundarysize, &nbodylines, &nlines,
599 &eof, &foundendofpart, &bodylength);
602 return (eof || foundendofpart) ? 1 : 0;
void parseFull(int fd) const
virtual int parseFull(const std::string &toboundary, int &boundarysize) const
unsigned int headerstartoffsetcrlf
unsigned int bodystartoffsetcrlf
unsigned int headerlength
Declaration of miscellaneous convertion functions.
Binc::MimeInputSource * mimeSource
bool compareStringToQueue(const char *s_in, char *bqueue, int pos, int size)
Declaration of main mime parser components.
void split(const std::string &s_in, const std::string &delim, std::vector< std::string > &dest, bool skipempty=true)
void lowercase(std::string &input)
void trim(std::string &s_in, const std::string &chars=" \t\r\n")