62static bool parseOneHeaderLine(
Binc::Header *header,
unsigned int *nlines)
64 using namespace ::
Binc;
76 for (
int i = 0; i < (int) name.length() + 1; ++i)
94 bool endOfHeaders =
false;
95 while (!endOfHeaders) {
101 if (c ==
'\n') ++*nlines;
103 for (
int i = 0; i < 3; ++i)
104 cqueue[i] = cqueue[i + 1];
107 if (strncmp(cqueue,
"\r\n\r\n", 4) == 0) {
115 if (cqueue[2] ==
'\n' && c !=
' ' && c !=
'\t') {
116 if (content.length() > 2)
117 content.resize(content.length() - 2);
120 header->
add(name, content);
124 if (c ==
'\n') --*nlines;
136 if (content.length() > 2)
137 content.resize(content.length() - 2);
138 header->
add(name, content);
142 return !(eof || endOfHeaders);
146static void parseHeader(
Binc::Header *header,
unsigned int *nlines)
148 while (parseOneHeaderLine(header, nlines))
153static void analyzeHeader(
Binc::Header *header,
bool *multipart,
154 bool *messagerfc822,
string *subtype,
string *boundary)
156 using namespace ::
Binc;
162 vector<string> types;
163 split(ctype.getValue(),
";", types);
165 if (types.size() > 0) {
167 string tmp = types[0];
173 key = (v.size() > 0) ? v[0] :
"text";
174 value = (v.size() > 1) ? v[1] :
"plain";
177 if (key ==
"multipart") {
181 }
else if (key ==
"message") {
183 if (value ==
"rfc822")
184 *messagerfc822 =
true;
188 for (vector<string>::const_iterator i = types.begin();
189 i != types.end(); ++i) {
193 if (element.find(
"=") != string::npos) {
194 string::size_type pos = element.find(
'=');
195 string key = element.substr(0, pos);
196 string value = element.substr(pos + 1);
201 if (key ==
"boundary") {
210static void parseMessageRFC822(vector<Binc::MimePart> *members,
211 bool *foundendofpart,
212 unsigned int *bodylength,
213 unsigned int *nbodylines,
214 const string &toboundary)
216 using namespace ::
Binc;
229 if (m.parseFull(toboundary, bsize))
230 *foundendofpart =
true;
234 if (*bodylength >= bodystartoffsetcrlf) {
235 *bodylength -= bodystartoffsetcrlf;
236 if (*bodylength >= (
unsigned int) bsize) {
237 *bodylength -= (
unsigned int) bsize;
245 *nbodylines += m.getNofLines();
247 members->push_back(m);
250static bool skipUntilBoundary(
const string &delimiter,
251 unsigned int *nlines,
bool *eof)
253 int endpos = delimiter.length();
254 char *delimiterqueue = 0;
255 int delimiterpos = 0;
256 const char *delimiterStr = delimiter.c_str();
257 if (delimiter !=
"") {
258 delimiterqueue =
new char[endpos];
259 memset(delimiterqueue, 0, endpos);
267 bool foundBoundary =
false;
274 if (c ==
'\n') ++*nlines;
278 if (!delimiterqueue)
continue;
280 delimiterqueue[delimiterpos++ % endpos] = c;
283 delimiterpos, endpos)) {
284 foundBoundary =
true;
289 delete[] delimiterqueue;
292 return foundBoundary;
296static void parseMultipart(
const string &boundary,
297 const string &toboundary,
299 unsigned int *nlines,
301 bool *foundendofpart,
302 unsigned int *bodylength,
303 vector<Binc::MimePart> *members)
305 using namespace ::
Binc;
313 string delimiter =
"--" + boundary;
315 skipUntilBoundary(delimiter, nlines, eof);
317 if (!eof) *boundarysize = delimiter.size();
324 if (a ==
'\n') ++*nlines;
328 if (b ==
'\n') ++*nlines;
333 if (a ==
'-' && b ==
'-') {
334 *foundendofpart =
true;
338 if (a ==
'\n') ++*nlines;
340 if (b ==
'\n') ++*nlines;
343 if (a ==
'\r' && b ==
'\n') {
349 else if (a ==
'-' && b ==
'-') {
367 if (!*foundendofpart && !*eof) {
375 if (m.parseFull(boundary, bsize)) {
377 *boundarysize = bsize;
380 members->push_back(m);
385 if (!*foundendofpart && !*eof) {
391 string delimiter =
"\r\n--" + toboundary;
393 skipUntilBoundary(delimiter, nlines, eof);
395 if (!*eof) *boundarysize = delimiter.size();
402 if (a ==
'\n') ++*nlines;
406 if (b ==
'\n') ++*nlines;
411 if (a ==
'-' && b ==
'-') {
412 *foundendofpart =
true;
424 if (a ==
'\r' && b ==
'\n') {
430 else if (a ==
'-' && b ==
'-') {
450 if (*bodylength >= bodystartoffsetcrlf) {
451 *bodylength -= bodystartoffsetcrlf;
452 if (*bodylength >= (
unsigned int) *boundarysize) {
453 *bodylength -= (
unsigned int) *boundarysize;
462static void parseSinglePart(
const string &toboundary,
464 unsigned int *nbodylines,
465 unsigned int *nlines,
466 bool *eof,
bool *foundendofpart,
467 unsigned int *bodylength)
469 using namespace ::
Binc;
475 if (toboundary !=
"") {
476 _toboundary =
"\r\n--";
477 _toboundary += toboundary;
483 char *boundaryqueue = 0;
484 int endpos = _toboundary.length();
485 if (toboundary !=
"") {
486 boundaryqueue =
new char[endpos];
487 memset(boundaryqueue, 0, endpos);
493 const char *_toboundaryStr = _toboundary.c_str();
495 bool toboundaryIsEmpty = (toboundary ==
"");
498 if (c ==
'\n') { ++*nbodylines; ++*nlines; }
499 if (toboundaryIsEmpty)
continue;
502 boundaryqueue[boundarypos++ % endpos] = c;
505 boundarypos, endpos)) {
506 *boundarysize = _toboundary.length();
511 delete[] boundaryqueue;
513 if (toboundary !=
"") {
517 if (a ==
'\n') ++*nlines;
521 if (b ==
'\n') ++*nlines;
523 if (a ==
'-' && b ==
'-') {
525 *foundendofpart =
true;
527 if (a ==
'\n') ++*nlines;
529 if (b ==
'\n') ++*nlines;
532 if (a ==
'\r' && b ==
'\n') {
538 else if (a ==
'-' && b ==
'-') {
557 if (*bodylength >= bodystartoffsetcrlf) {
558 *bodylength -= bodystartoffsetcrlf;
559 if (*bodylength >= (
unsigned int) *boundarysize) {
560 *bodylength -= (
unsigned int) *boundarysize;
572 int &boundarysize)
const
577 parseHeader(&h, &nlines);
587 analyzeHeader(&h, &multipart, &messagerfc822, &subtype, &boundary);
590 bool foundendofpart =
false;
593 parseMessageRFC822(&members, &foundendofpart, &bodylength,
594 &nbodylines, toboundary);
596 }
else if (multipart) {
597 parseMultipart(boundary, toboundary, &eof, &nlines, &boundarysize,
598 &foundendofpart, &bodylength, &members);
600 parseSinglePart(toboundary, &boundarysize, &nbodylines, &nlines,
601 &eof, &foundendofpart, &bodylength);
604 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")