kioslaves

mimehdrline.cc

Go to the documentation of this file.
00001 /***************************************************************************
00002                           mimehdrline.cc  -  description
00003                              -------------------
00004     begin                : Wed Oct 11 2000
00005     copyright            : (C) 2000 by Sven Carstens
00006     email                : s.carstens@gmx.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include <config.h>
00019 #include <iostream>
00020 #include <ctype.h>
00021 #include <stdlib.h>
00022 #include <stdio.h>
00023 
00024 #include "mimehdrline.h"
00025 #include "rfcdecoder.h"
00026 
00027 using namespace std;
00028 
00029 const char *wdays[] = {
00030   "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
00031 };
00032 
00033 const char *months[] = {
00034   "Jan", "Feb", "Mar", "Apr", "May", "Jun",
00035   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
00036 };
00037 
00038 mimeHdrLine::mimeHdrLine ():
00039 mimeValue ((const char *) NULL), mimeLabel ((const char *) NULL)
00040 {
00041 }
00042 
00043 mimeHdrLine::mimeHdrLine (const QCString & aLabel, const QCString & aValue):
00044 mimeValue (aValue),
00045 mimeLabel (aLabel)
00046 {
00047 }
00048 
00049 mimeHdrLine::mimeHdrLine (mimeHdrLine * aHdrLine):
00050 mimeValue (aHdrLine->mimeValue), mimeLabel (aHdrLine->mimeLabel)
00051 {
00052 }
00053 
00054 mimeHdrLine::~mimeHdrLine ()
00055 {
00056 }
00057 
00058 int
00059 mimeHdrLine::appendStr (const char *inCStr)
00060 {
00061   int retVal = 0;
00062   int skip;
00063   char *aCStr = (char *) inCStr;
00064 
00065   if (aCStr)
00066   {
00067     skip = skipWS (aCStr);
00068     if (skip && !mimeLabel.isEmpty ())
00069     {
00070       if (skip > 0)
00071       {
00072         mimeValue += QCString (aCStr, skip + 1);
00073         aCStr += skip;
00074         retVal += skip;
00075         skip = parseFullLine (aCStr);
00076         mimeValue += QCString (aCStr, skip + 1);
00077         retVal += skip;
00078         aCStr += skip;
00079       }
00080     }
00081     else
00082     {
00083       if (mimeLabel.isEmpty ())
00084         return setStr (aCStr);
00085     }
00086   }
00087   return retVal;
00088 }
00089 
00093 int
00094 mimeHdrLine::setStr (const char *inCStr)
00095 {
00096   int retVal = 0;
00097   char *aCStr = (char *) inCStr;
00098 //  char *begin = aCStr;  
00099   mimeLabel = QCString ((const char *) NULL);
00100   mimeValue = QCString ((const char *) NULL);
00101 
00102   if (aCStr)
00103   {
00104     // can't have spaces on normal lines
00105     if (!skipWS (aCStr))
00106     {
00107       int label = 0, advance;
00108       while ((advance = parseWord (&aCStr[label])))
00109       {
00110         label += advance;
00111       }
00112       if (label && aCStr[label - 1] != ':')
00113         retVal = 0;
00114       else
00115       {
00116         mimeLabel = QCString (aCStr, label);  //length including zero
00117         retVal += label;
00118         aCStr += label;
00119       }
00120     }
00121     if (retVal)
00122     {
00123       int skip;
00124       skip = skipWS (aCStr);
00125       if (skip < 0)
00126         skip *= -1;
00127       aCStr += skip;
00128       retVal += skip;
00129       skip = parseFullLine (aCStr);
00130       mimeValue = QCString (aCStr, skip + 1);
00131       retVal += skip;
00132       aCStr += skip;
00133     }
00134     else
00135     {
00136       //Skip malformed line
00137       while (*aCStr && *aCStr != '\r' && *aCStr != '\n')
00138       {
00139         retVal--;
00140         aCStr++;
00141       }
00142       if (*aCStr == '\r')
00143       {
00144         retVal--;
00145         aCStr++;
00146       }
00147       if (*aCStr == '\n')
00148       {
00149         retVal--;
00150         aCStr++;
00151       }
00152     }
00153   }
00154   else
00155   {
00156     //debug
00157   }
00158   return retVal;
00159 }
00160 
00162 int
00163 mimeHdrLine::parseWord (const char *inCStr)
00164 {
00165   int retVal = 0;
00166   char *aCStr = (char *) inCStr;
00167 
00168   if (aCStr && *aCStr)
00169   {
00170     if (*aCStr == '"')
00171       return mimeHdrLine::parseQuoted ('"', '"', aCStr);
00172     else
00173       return mimeHdrLine::parseHalfWord (aCStr);
00174   }
00175   else
00176   {
00177     //debug();
00178   }
00179   return retVal;
00180 }
00181 
00183 int
00184 mimeHdrLine::parseQuoted (char startQuote, char endQuote, const char *inCStr)
00185 {
00186   char *aCStr = (char *) inCStr;
00187   int retVal = 0;
00188 
00189   if (aCStr && *aCStr)
00190   {
00191     if (*aCStr == startQuote)
00192     {
00193       aCStr++;
00194       retVal++;
00195     }
00196     else
00197       return 0;
00198     while (*aCStr && *aCStr != endQuote)
00199     {
00200       //skip over backticks
00201       if (*aCStr == '\\')
00202       {
00203         aCStr++;
00204         retVal++;
00205       }
00206       //eat this
00207       aCStr++;
00208       retVal++;
00209     }
00210     if (*aCStr == endQuote)
00211     {
00212       aCStr++;
00213       retVal++;
00214     }
00215   }
00216   else
00217   {
00218     //debug();
00219   }
00220   return retVal;
00221 }
00222 
00224 int
00225 mimeHdrLine::parseAlphaNum (const char *inCStr)
00226 {
00227   int retVal = 0;
00228   char *aCStr = (char *) inCStr;
00229 
00230   if (aCStr)
00231   {
00232     while (*aCStr && isalnum (*aCStr))
00233     {
00234       //skip over backticks
00235       if (*aCStr == '\\')
00236       {
00237         aCStr++;
00238         retVal++;
00239       }
00240       //eat this
00241       aCStr++;
00242       retVal++;
00243     }
00244   }
00245   else
00246   {
00247     //debug();
00248   }
00249   return retVal;
00250 }
00251 
00252 int
00253 mimeHdrLine::parseHalfWord (const char *inCStr)
00254 {
00255   int retVal = 0;
00256   char *aCStr = (char *) inCStr;
00257 
00258   if (aCStr && *aCStr)
00259   {
00260     if (isalnum (*aCStr))
00261       return mimeHdrLine::parseAlphaNum (aCStr);
00262     //skip over backticks
00263     if (*aCStr == '\\')
00264     {
00265       aCStr++;
00266       retVal++;
00267     }
00268     else if (!isspace (*aCStr))
00269     {
00270       //eat this
00271       aCStr++;
00272       retVal++;
00273     }
00274   }
00275   else
00276   {
00277     //debug();
00278   }
00279   return retVal;
00280 }
00281 
00283 int
00284 mimeHdrLine::parseHalfLine (const char *inCStr)
00285 {
00286   int retVal = 0;
00287   char *aCStr = (char *) inCStr;
00288 
00289   if (aCStr)
00290   {
00291     while (*aCStr && *aCStr != '\n')
00292     {
00293       //skip over backticks
00294       if (*aCStr == '\\')
00295       {
00296         aCStr++;
00297         retVal++;
00298       }
00299       //eat this
00300       aCStr++;
00301       retVal++;
00302     }
00303     if (*aCStr == '\n')
00304     {
00305       aCStr++;
00306       retVal++;
00307     }
00308   }
00309   else
00310   {
00311     //debug();
00312   }
00313   return retVal;
00314 }
00315 
00317 int
00318 mimeHdrLine::skipWS (const char *inCStr)
00319 {
00320   int retVal = 0;
00321   char *aCStr = (char *) inCStr;
00322 
00323   if (aCStr && *aCStr)
00324   {
00325     while (*aCStr == ' ' || *aCStr == '\t')
00326     {
00327       aCStr++;
00328       retVal++;
00329     }
00330     //check out for continuation lines
00331     if (*aCStr == '\r')
00332     {
00333       aCStr++;
00334       retVal++;
00335     }
00336     if (*aCStr++ == '\n')
00337       if (*aCStr == '\t' || *aCStr == ' ')
00338       {
00339         int skip = mimeHdrLine::skipWS (aCStr);
00340         if (skip < 0)
00341           skip *= -1;
00342         retVal += 1 + skip;
00343       }
00344       else
00345       {
00346         retVal = -retVal - 1;
00347       }
00348   }
00349   else
00350   {
00351     //debug();
00352   }
00353   return retVal;
00354 }
00355 
00357 int
00358 mimeHdrLine::parseFullLine (const char *inCStr)
00359 {
00360   int retVal = 0;
00361   char *aCStr = (char *) inCStr;
00362   int skip;
00363 
00364   if (aCStr)
00365   {
00366     //skip leading white space
00367     skip = skipWS (aCStr);
00368     if (skip > 0)
00369     {
00370       aCStr += skip;
00371       retVal += skip;
00372     }
00373     while (*aCStr)
00374     {
00375       int advance;
00376 
00377       if ((advance = parseHalfLine (aCStr)))
00378       {
00379         retVal += advance;
00380         aCStr += advance;
00381       }
00382       else if ((advance = skipWS (aCStr)))
00383       {
00384         if (advance > 0)
00385         {
00386           retVal += advance;
00387           aCStr += advance;
00388         }
00389         else
00390         {
00391           retVal -= advance;
00392           break;
00393         }
00394       }
00395       else
00396         break;
00397     }
00398   }
00399   else
00400   {
00401     //debug();
00402   }
00403   return retVal;
00404 }
00405 
00407 int
00408 mimeHdrLine::parseSeparator (char separator, const char *inCStr)
00409 {
00410   char *aCStr = (char *) inCStr;
00411   int retVal = 0;
00412   int skip;
00413 
00414   if (aCStr)
00415   {
00416     //skip leading white space
00417     skip = skipWS (aCStr);
00418     if (skip > 0)
00419     {
00420       aCStr += skip;
00421       retVal += skip;
00422     }
00423     while (*aCStr)
00424     {
00425       int advance;
00426 
00427       if (*aCStr != separator)
00428       {
00429         if ((advance = mimeHdrLine::parseWord (aCStr)))
00430         {
00431           retVal += advance;
00432           aCStr += advance;
00433         }
00434         else if ((advance = mimeHdrLine::skipWS (aCStr)))
00435         {
00436           if (advance > 0)
00437           {
00438             retVal += advance;
00439             aCStr += advance;
00440           }
00441           else
00442           {
00443             retVal -= advance;
00444             break;
00445           }
00446         }
00447         else
00448           break;
00449       }
00450       else
00451       {
00452         //include separator in result
00453         retVal++;
00454         aCStr++;
00455         break;
00456       }
00457     }
00458   }
00459   else
00460   {
00461     //debug();
00462   }
00463   return retVal;
00464 }
00465 
00468 const QCString&
00469 mimeHdrLine::getLabel ()
00470 {
00471   return mimeLabel;
00472 }
00473 
00475 const QCString&
00476 mimeHdrLine::getValue ()
00477 {
00478   return mimeValue;
00479 }
00480 
00481 
00482 // FIXME: very inefficient still
00483 QCString
00484 mimeHdrLine::truncateLine(QCString aLine, unsigned int truncate)
00485 {
00486   int cutHere;
00487   QCString retVal;
00488   uint len = aLine.length();
00489 
00490   // see if we have a line of the form "key: value" (like "Subject: bla")
00491   // then we do not want to truncate between key and value
00492   int validStart = aLine.find(": ");
00493   if (validStart > -1) {
00494     validStart += 2;
00495   }
00496   while (len > truncate) {
00497     cutHere = aLine.findRev(' ', truncate);
00498     if (cutHere < 1 || cutHere < validStart) {
00499       cutHere = aLine.findRev('\t', truncate);
00500       if (cutHere < 1) {
00501         cutHere = aLine.find(' ', 1);
00502         if (cutHere < 1) {
00503           cutHere = aLine.find('\t', 1);
00504           if (cutHere < 1) {
00505             // simply truncate
00506             return aLine.left(truncate);
00507           }
00508         }
00509       }
00510     }
00511 
00512     retVal += aLine.left(cutHere) + '\n';
00513     int chop = len - cutHere;
00514     aLine = aLine.right(chop);
00515     len -= chop;
00516   }
00517   retVal += aLine;
00518 
00519   return retVal;
00520 }
00521