/** * @file mime-printheader.cc * @brief Implementation of main mime parser components * @author Andreas Aardal Hanssen * @date 2002-2005 */ #include "convert.h" #include "iodevice.h" #include "iofactory.h" #include "mime-inputsource.h" #include "mime-utils.h" #include "mime.h" #include #include #include #include #include #include #include #include #include using std::string; using std::vector; void Binc::MimePart::printHeader(int fd, IODevice &output, vector headers, bool includeheaders, unsigned int startoffset, unsigned int length, string &store) const { if (!mimeSource || mimeSource->getFileDescriptor() != fd) { delete mimeSource; mimeSource = new MimeInputSource(fd); } mimeSource->seek(headerstartoffsetcrlf); string name; string content; char cqueue[2]; memset(cqueue, 0, sizeof(cqueue)); bool quit = false; char c = '\0'; unsigned int wrotebytes = 0; unsigned int processedbytes = 0; bool hasHeaderSeparator = false; while (!quit) { // read name while (1) { // allow EOF to end the header if (!mimeSource->getChar(&c)) { quit = true; break; } // assume this character is part of the header name. name += c; // break on the first colon if (c == ':') break; // break if a '\n' turned up. if (c == '\n') { // end of headers detected if (name == "\r\n") { hasHeaderSeparator = true; quit = true; break; } // put all data back in the buffer to the beginning of this // line. for (int i = name.length(); i >= 0; --i) mimeSource->ungetChar(); // abort printing of header. note that in this case, the // headers will not end with a seperate \r\n. quit = true; name = ""; break; } } if (quit) break; // at this point, we have a name, that is - the start of a // header. we'll read until the end of the header. while (!quit) { // allow EOF to end the header. if (!mimeSource->getChar(&c)) { quit = true; break; } if (c == '\n') ++nlines; // make a fifo queue of the last 4 characters. cqueue[0] = cqueue[1]; cqueue[1] = c; // print header if (cqueue[0] == '\n' && cqueue[1] != '\t' && cqueue[1] != ' ') { // it wasn't a space, so put it back as it is most likely // the start of a header name. in any case it terminates the // content part of this header. mimeSource->ungetChar(); string lowername = name; lowercase(lowername); trim(lowername, ": \t"); bool foundMatch = false; for (auto nametmp : headers) { lowercase(nametmp); if (nametmp == lowername) { foundMatch = true; break; } } if (foundMatch == includeheaders || headers.size() == 0) { string out = name + content; for (char i : out) { if (processedbytes >= startoffset && wrotebytes < length) { if (processedbytes >= startoffset) { store += i; ++wrotebytes; } } else { ++processedbytes; } } } // move on to the next header content = ""; name = ""; break; } content += c; } } // end while loop if (name != "") { string lowername = name; lowercase(lowername); trim(lowername, ": \t"); bool foundMatch = false; for (auto nametmp : headers) { lowercase(nametmp); if (nametmp == lowername) { foundMatch = true; break; } } if (hasHeaderSeparator || foundMatch == includeheaders || headers.size() == 0) { string out = name + content; for (char i : out) { if (processedbytes >= startoffset && wrotebytes < length) { store += i; ++wrotebytes; } else { ++processedbytes; } } } } }