/* -*- Mode: c++; -*- */ /* -------------------------------------------------------------------- * Filename: * mime-printheader.cc * * Description: * Implementation of main mime parser components * -------------------------------------------------------------------- * Copyright 2002-2004 Andreas Aardal Hanssen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY 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 Street #330, Boston, MA 02111-1307, USA. * -------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H #include #endif #include "mime.h" #include "mime-utils.h" #include "mime-inputsource.h" #include "convert.h" #include "iodevice.h" #include "iofactory.h" #include #include #include #include #include #include #include #include #include using namespace ::std; //------------------------------------------------------------------------ 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 (vector::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; } } if (name != "") { string lowername = name; lowercase(lowername); trim(lowername, ": \t"); bool foundMatch = false; for (vector::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; } } }