/*************************************************************************** mimehdrline.cc - description ------------------- begin : Wed Oct 11 2000 copyright : (C) 2000 by Sven Carstens email : s.carstens@gmx.de ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include #include #include #include #include #include "mimehdrline.h" #include "rfcdecoder.h" using namespace std; const char *wdays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; mimeHdrLine::mimeHdrLine (): mimeValue ((const char *) NULL), mimeLabel ((const char *) NULL) { } mimeHdrLine::mimeHdrLine (const TQCString & aLabel, const TQCString & aValue): mimeValue (aValue), mimeLabel (aLabel) { } mimeHdrLine::mimeHdrLine (mimeHdrLine * aHdrLine): mimeValue (aHdrLine->mimeValue), mimeLabel (aHdrLine->mimeLabel) { } mimeHdrLine::~mimeHdrLine () { } int mimeHdrLine::appendStr (const char *inCStr) { int retVal = 0; int skip; char *aCStr = (char *) inCStr; if (aCStr) { skip = skipWS (aCStr); if (skip && !mimeLabel.isEmpty ()) { if (skip > 0) { mimeValue += TQCString (aCStr, skip + 1); aCStr += skip; retVal += skip; skip = parseFullLine (aCStr); mimeValue += TQCString (aCStr, skip + 1); retVal += skip; aCStr += skip; } } else { if (mimeLabel.isEmpty ()) return setStr (aCStr); } } return retVal; } /** parse a Line into the class move input ptr accordingly and report characters slurped */ int mimeHdrLine::setStr (const char *inCStr) { int retVal = 0; char *aCStr = (char *) inCStr; // char *begin = aCStr; mimeLabel = TQCString ((const char *) NULL); mimeValue = TQCString ((const char *) NULL); if (aCStr) { // can't have spaces on normal lines if (!skipWS (aCStr)) { int label = 0, advance; while ((advance = parseWord (&aCStr[label]))) { label += advance; } if (label && aCStr[label - 1] != ':') retVal = 0; else { mimeLabel = TQCString (aCStr, label); //length including zero retVal += label; aCStr += label; } } if (retVal) { int skip; skip = skipWS (aCStr); if (skip < 0) skip *= -1; aCStr += skip; retVal += skip; skip = parseFullLine (aCStr); mimeValue = TQCString (aCStr, skip + 1); retVal += skip; aCStr += skip; } else { //Skip malformed line while (*aCStr && *aCStr != '\r' && *aCStr != '\n') { retVal--; aCStr++; } if (*aCStr == '\r') { retVal--; aCStr++; } if (*aCStr == '\n') { retVal--; aCStr++; } } } else { //debug } return retVal; } /** slurp one word*/ int mimeHdrLine::parseWord (const char *inCStr) { int retVal = 0; char *aCStr = (char *) inCStr; if (aCStr && *aCStr) { if (*aCStr == '"') return mimeHdrLine::parseQuoted ('"', '"', aCStr); else return mimeHdrLine::parseHalfWord (aCStr); } else { //debug(); } return retVal; } /** slurp one word*/ int mimeHdrLine::parseQuoted (char startQuote, char endQuote, const char *inCStr) { char *aCStr = (char *) inCStr; int retVal = 0; if (aCStr && *aCStr) { if (*aCStr == startQuote) { aCStr++; retVal++; } else return 0; while (*aCStr && *aCStr != endQuote) { //skip over backticks if (*aCStr == '\\') { aCStr++; retVal++; } //eat this aCStr++; retVal++; } if (*aCStr == endQuote) { aCStr++; retVal++; } } else { //debug(); } return retVal; } /** slurp one alphanumerical word without continuation*/ int mimeHdrLine::parseAlphaNum (const char *inCStr) { int retVal = 0; char *aCStr = (char *) inCStr; if (aCStr) { while (*aCStr && isalnum (*aCStr)) { //skip over backticks if (*aCStr == '\\') { aCStr++; retVal++; } //eat this aCStr++; retVal++; } } else { //debug(); } return retVal; } int mimeHdrLine::parseHalfWord (const char *inCStr) { int retVal = 0; char *aCStr = (char *) inCStr; if (aCStr && *aCStr) { if (isalnum (*aCStr)) return mimeHdrLine::parseAlphaNum (aCStr); //skip over backticks if (*aCStr == '\\') { aCStr++; retVal++; } else if (!isspace (*aCStr)) { //eat this aCStr++; retVal++; } } else { //debug(); } return retVal; } /** slurp one line without continuation*/ int mimeHdrLine::parseHalfLine (const char *inCStr) { int retVal = 0; char *aCStr = (char *) inCStr; if (aCStr) { while (*aCStr && *aCStr != '\n') { //skip over backticks if (*aCStr == '\\') { aCStr++; retVal++; } //eat this aCStr++; retVal++; } if (*aCStr == '\n') { aCStr++; retVal++; } } else { //debug(); } return retVal; } /** skip all white space characters including continuation*/ int mimeHdrLine::skipWS (const char *inCStr) { int retVal = 0; char *aCStr = (char *) inCStr; if (aCStr && *aCStr) { while (*aCStr == ' ' || *aCStr == '\t') { aCStr++; retVal++; } //check out for continuation lines if (*aCStr == '\r') { aCStr++; retVal++; } if (*aCStr++ == '\n') if (*aCStr == '\t' || *aCStr == ' ') { int skip = mimeHdrLine::skipWS (aCStr); if (skip < 0) skip *= -1; retVal += 1 + skip; } else { retVal = -retVal - 1; } } else { //debug(); } return retVal; } /** parses continuated lines */ int mimeHdrLine::parseFullLine (const char *inCStr) { int retVal = 0; char *aCStr = (char *) inCStr; int skip; if (aCStr) { //skip leading white space skip = skipWS (aCStr); if (skip > 0) { aCStr += skip; retVal += skip; } while (*aCStr) { int advance; if ((advance = parseHalfLine (aCStr))) { retVal += advance; aCStr += advance; } else if ((advance = skipWS (aCStr))) { if (advance > 0) { retVal += advance; aCStr += advance; } else { retVal -= advance; break; } } else break; } } else { //debug(); } return retVal; } /** parses continuated lines */ int mimeHdrLine::parseSeparator (char separator, const char *inCStr) { char *aCStr = (char *) inCStr; int retVal = 0; int skip; if (aCStr) { //skip leading white space skip = skipWS (aCStr); if (skip > 0) { aCStr += skip; retVal += skip; } while (*aCStr) { int advance; if (*aCStr != separator) { if ((advance = mimeHdrLine::parseWord (aCStr))) { retVal += advance; aCStr += advance; } else if ((advance = mimeHdrLine::skipWS (aCStr))) { if (advance > 0) { retVal += advance; aCStr += advance; } else { retVal -= advance; break; } } else break; } else { //include separator in result retVal++; aCStr++; break; } } } else { //debug(); } return retVal; } /** return the label */ const TQCString& mimeHdrLine::getLabel () { return mimeLabel; } /** return the value */ const TQCString& mimeHdrLine::getValue () { return mimeValue; } // FIXME: very inefficient still TQCString mimeHdrLine::truncateLine(TQCString aLine, unsigned int truncate) { int cutHere; TQCString retVal; uint len = aLine.length(); // see if we have a line of the form "key: value" (like "Subject: bla") // then we do not want to truncate between key and value int validStart = aLine.find(": "); if (validStart > -1) { validStart += 2; } while (len > truncate) { cutHere = aLine.findRev(' ', truncate); if (cutHere < 1 || cutHere < validStart) { cutHere = aLine.findRev('\t', truncate); if (cutHere < 1) { cutHere = aLine.find(' ', 1); if (cutHere < 1) { cutHere = aLine.find('\t', 1); if (cutHere < 1) { // simply truncate return aLine.left(truncate); } } } } retVal += aLine.left(cutHere) + '\n'; int chop = len - cutHere; aLine = aLine.right(chop); len -= chop; } retVal += aLine; return retVal; }