diff options
Diffstat (limited to 'src/mime-printheader.cc')
-rw-r--r-- | src/mime-printheader.cc | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/src/mime-printheader.cc b/src/mime-printheader.cc new file mode 100644 index 0000000..84dca1e --- /dev/null +++ b/src/mime-printheader.cc @@ -0,0 +1,172 @@ +/** -------------------------------------------------------------------- + * @file mime-printheader.cc + * @brief Implementation of main mime parser components + * @author Andreas Aardal Hanssen + * @date 2002-2005 + * ----------------------------------------------------------------- **/ +#include "mime.h" +#include "mime-utils.h" +#include "mime-inputsource.h" +#include "convert.h" +#include "iodevice.h" +#include "iofactory.h" + +#include <string> +#include <vector> +#include <map> +#include <exception> +#include <iostream> + +#include <string.h> +#include <ctype.h> +#include <stdio.h> +#include <errno.h> + +using namespace ::std; + +//------------------------------------------------------------------------ +void Binc::MimePart::printHeader(int fd, IODevice &output, + vector<string> 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 (vector<string>::const_iterator i = headers.begin(); + i != headers.end(); ++i) { + string nametmp = *i; + lowercase(nametmp); + if (nametmp == lowername) { + foundMatch = true; + break; + } + } + + if (foundMatch == includeheaders || headers.size() == 0) { + string out = name + content; + for (string::const_iterator i = out.begin(); i != out.end(); ++i) + 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 (vector<string>::const_iterator i = headers.begin(); + i != headers.end(); ++i) { + string nametmp = *i; + lowercase(nametmp); + if (nametmp == lowername) { + foundMatch = true; + break; + } + } + + if (hasHeaderSeparator || foundMatch == includeheaders || headers.size() == 0) { + string out = name + content; + for (string::const_iterator i = out.begin(); i != out.end(); ++i) + if (processedbytes >= startoffset && wrotebytes < length) { + store += *i; + ++wrotebytes; + } else + ++processedbytes; + } + } +} |