Update of /cvsroot/mahogany/M/src/modules/viewflt
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32653/src/modules/viewflt

Modified Files:
        UUDecode.cpp 
Log Message:
Implemented UU decoding of (multiple) file(s) in a message.

Index: UUDecode.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/modules/viewflt/UUDecode.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -b -u -2 -r1.2 -r1.3
--- UUDecode.cpp        13 May 2004 15:19:13 -0000      1.2
+++ UUDecode.cpp        14 May 2004 08:14:21 -0000      1.3
@@ -36,90 +36,52 @@
 #include <wx/mimetype.h>
 
-class MimePartUUencode : public MimePart
+// MimePartRaw
+//
+// A MIME part built from raw data. This class does not know about sub-parts, 
+// or other MIME stuff.
+//
+// It should be possible to re-use this class to handle the result of decrypting
+// (part of) a message.
+
+class MimePartRaw : public MimePart
 {
 public:
-  MimePartUUencode(const String& fileName, const String& mimeType, const String& 
content) 
+  MimePartRaw(const String& fileName, 
+              const String& mimeType, 
+              const String& content,
+              const String& disposition) 
     : m_fileName(fileName)
     , m_mimeType(mimeType)
     , m_content(content)
+    , m_disposition(disposition)
   {}
 public:
-   /// get the parent MIME part (NULL for the top level one)
   virtual MimePart *GetParent() const {return 0;}
-
-   /// get the next MIME part (NULL if this is the last part of multipart)
    virtual MimePart *GetNext() const {return 0;}
-
-   /// get the first child part (NULL if not multipart or message)
    virtual MimePart *GetNested() const {return 0;}
 
-   //@}
-
-   /** @name Headers access
-
-       Get the information from "Content-Type" and "Content-Disposition"
-       headers.
-    */
-   //@{
-
-   /// get the MIME type of the part
    virtual MimeType GetType() const {
       return MimeType(m_mimeType);
    }
-
-   /// get the description of the part, if any
    virtual String GetDescription() const {return String();}
-
-   /// get the filename if the part is an attachment
    virtual String GetFilename() const {return m_fileName;}
-
-   /// get the disposition specified in Content-Disposition
-   virtual String GetDisposition() const {return _T("uuencoded");}
-
-   /// get the IMAP part spec (of the #.#.#.# form)
+   virtual String GetDisposition() const {return m_disposition;}
    virtual String GetPartSpec() const {return String();}
-
-   /// get the value of the specified Content-Type parameter
    virtual String GetParam(const String& name) const {return String();}
-
-   /// get the value of the specified Content-Disposition parameter
    virtual String GetDispositionParam(const String& name) const {return String();}
-
-   /// get the list of all parameters (from Content-Type)
    virtual const MimeParameterList& GetParameters() const {return m_parameters;}
-
-   /// get the list of all disposition parameters (from Content-Disposition)
    virtual const MimeParameterList& GetDispositionParameters() const {return 
m_dispositionParameters;}
 
-   //@}
-
-   /** @name Data access
-
-       Allows to get the part data. Note that it is always returned in the
-       decoded form (why would we need it otherwise?) so its size in general
-       won't be the same as the number returned by GetSize()
-    */
-   //@{
-
    /// get the raw (un-decoded) contents of this part
    virtual const void *GetRawContent(unsigned long *len = NULL) const {
+      // We actually return the only thing we have: the decoded file.
       return GetContent(len);
    }
-
-   /**
-       get the decoded contents of this part
-
-       WARNING: the pointer is not NULL terminated, len must be used!
-    */
    virtual const void *GetContent(unsigned long *len) const {
      if (len) *len = m_content.Length();
      return m_content.c_str();
    }
-
-   /**
-       get contents of this part as text.
-
-    */
    virtual String GetTextContent() const {
+      // Same as for MimePartCC
      unsigned long len;
      const char *p = reinterpret_cast<const char *>(GetContent(&len));
@@ -136,30 +98,11 @@
 
 
-   /// get all headers as one string
    virtual String GetHeaders() const {return String();}
-
-   /// get the encoding of the part
    virtual MimeXferEncoding GetTransferEncoding() const {return MIME_ENC_BINARY;}
-
-   /// get the part size in bytes
    virtual size_t GetSize() const {return m_content.length();}
 
-   //@}
-
-   /** @name Text part methods
-
-       These methods can only be called for the part of type MimeType::TEXT or
-       MESSAGE (if the message has a single text part)
-    */
-   //@{
-
-   /// get the encoding of the text (only if GetType() == TEXT!)
    virtual wxFontEncoding GetTextEncoding() const {return wxFONTENCODING_DEFAULT;}
-
-   /// get the size in lines
    virtual size_t GetNumberOfLines() const {return 0;}
 
-   //@}
-
 private:
   MimeParameterList m_parameters;
@@ -169,4 +112,5 @@
   String m_mimeType;
   String m_content;
+  String m_disposition;
 };
 
@@ -175,34 +119,4 @@
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 // ----------------------------------------------------------------------------
 // UUDecodeFilter itself
@@ -284,5 +198,5 @@
 }
 
-bool UUdecodeFile(const wxChar* input, String& output) {
+bool UUdecodeFile(const wxChar* input, String& output, const wxChar** 
endOfEncodedStream) {
 
   static const int allocationSize = 10000;
@@ -296,4 +210,5 @@
   const wxChar* endOfLine = 0; // init not needed
   wxChar* buffer = new wxChar[45];
+  //memset(buffer, '\0', 45);
   while ((decodedBytesInLine = UUdecodeLine(startOfLine, buffer, &endOfLine)) > 0) {
     // We've just decoded a line
@@ -317,4 +232,5 @@
   decodedFile.Shrink();
   output = decodedFile;
+  *endOfEncodedStream = endOfLine;
   return true;
 }
@@ -329,119 +245,74 @@
    // do we have something looking like UUencoded data?
    //
-   // there should be a BEGIN line near the start of the message
-   bool foundBegin = false;
+   
    const wxChar *start = text.c_str();
-   const wxChar* start_data = 0;
-   for ( size_t numLines = 0; numLines < 100; numLines++ )
-   {
-      if ( wxStrncmp(start, UU_BEGIN_PREFIX, wxStrlen(UU_BEGIN_PREFIX)) == 0 )
+   const wxChar *nextToOutput = start;
+   while ( *start )
       {
-         foundBegin = true;
-         break;
-      }
 
+      if ( wxStrncmp(start, UU_BEGIN_PREFIX, wxStrlen(UU_BEGIN_PREFIX)) != 0 )
+      {
       // try the next line (but only if not already at the end)
-      if ( *start )
          start = wxStrchr(start, '\n');
-      else
-         break;
       if ( start )
-         start++; // skip '\n' itself
-      else
-         break; // no more text
-   }
-
-   if ( foundBegin )
-   {
-      const wxChar *tail = start + wxStrlen(UU_BEGIN_PREFIX);
-      // this flag tells us if everything is ok so far -- as soon as it becomes
-      // false, we skip all subsequent steps
-      bool ok = true;
-
-      // Let's check that the next 4 chars after the 'begin ' are
-      // digit, digit, digit, space
-      if ( ok && !(    tail[0] >= '0' && tail[0] <= '9'
-                    && tail[1] >= '0' && tail[1] <= '9'
-                    && tail[2] >= '0' && tail[2] <= '9'
-                    && tail[3] == ' ' ) )
       {
-         wxLogWarning(_("The BEGIN line is not correctly formed."));
-
-         ok = false;
+            start++;  // skip '\n' itself
+            continue; // restart with next line
       }
-
-      String fileName;
-      if ( ok )
+         else 
       {
-         const wxChar* startName = tail+4;
-         tail = startName;
-         // Rest of the line is the name
-         while (*tail != '\r')
+            String prolog(nextToOutput);
+            if ( !prolog.empty() )
          {
-           ++tail;
-           ASSERT_MSG( tail < text.c_str()+text.Length(), _T("'begin' line does not 
end?") );
+               m_next->Process(prolog, viewer, style);
          }
-         ASSERT_MSG( tail[1] == '\n', _T("'begin' line does not end with 
\"\\r\\n\"?") );
-         fileName = String(startName, tail);
-         start_data = tail + 2;
+            return;   // no more text
       }
-
-      // end of the UU part
-      const wxChar *end = NULL; // unneeded but suppresses the compiler warning
-      if ( ok ) // ok, it starts with something valid
-      {
-         // now locate the end line
-         const wxChar *pc = text.c_str() + text.Length() - 1;
-
-         bool foundEnd = false;
-         for ( ;; )
-         {
-            // optimistically suppose that this line will be the END one
-            end = pc + 2;
-
-            // find the beginning of this line
-            while ( *pc != '\n' && pc >= start )
-            {
-               pc--;
             }
 
-            // we took one extra char
-            pc++;
+      ASSERT_MSG( wxStrncmp(start, UU_BEGIN_PREFIX, wxStrlen(UU_BEGIN_PREFIX)) == 0,
+         _T("Stopped without a seemingly begin line ?") );
 
-            if ( wxStrncmp(pc, UU_END_PREFIX, wxStrlen(UU_END_PREFIX)) == 0 )
+      const wxChar* startBeginLine = start;
+      start = start + wxStrlen(UU_BEGIN_PREFIX);
+      // Let's check that the next 4 chars after the 'begin ' are
+      // digit, digit, digit, space
+      if ( !(    start[0] >= '0' && start[0] <= '9'
+              && start[1] >= '0' && start[1] <= '9'
+              && start[2] >= '0' && start[2] <= '9'
+              && start[3] == ' ' ) ) 
             {
-               tail = pc + wxStrlen(UU_END_PREFIX);
-
-               foundEnd = true;
-               break;
+         wxLogWarning(_("The BEGIN line is not correctly formed."));
+         continue;
             }
 
-            // undo the above
-            pc--;
-
-            if ( pc < start )
+      const wxChar* startName = start+4;
+      const wxChar* endName = startName;
+      // Rest of the line is the name
+      while (*endName != '\r')
             {
-               // we exhausted the message without finding the END line, leave
-               // foundEnd at false and exit the loop
-               break;
-            }
-
-            pc--;
-            ASSERT_MSG( *pc == '\r', _T("line doesn't end in\"\\r\\n\"?") );
+         ++endName;
+         ASSERT_MSG( endName < text.c_str()+text.Length(), _T("'begin' line does not 
end?") );
          }
+      ASSERT_MSG( endName[1] == '\n', _T("'begin' line does not end with 
\"\\r\\n\"?") );
+      String fileName = String(startName, endName);
+      const wxChar* start_data = endName + 2;
 
-         if ( !foundEnd )
+      String decodedFile;
+      const wxChar* endOfEncodedStream = 0;
+      bool ok = UUdecodeFile(start_data, decodedFile, &endOfEncodedStream);
+      if ( endOfEncodedStream[0] == '\r' &&
+           endOfEncodedStream[1] == '\n' &&
+           endOfEncodedStream[2] == 'e' &&
+           endOfEncodedStream[3] == 'n' &&
+           endOfEncodedStream[4] == 'd' )
          {
-            wxLogWarning(_("END line not found."));
-
-            ok = false;
-         }
+         endOfEncodedStream += 5;
       }
-
-      // if everything was ok so far, continue with decoding/verifying
       if ( ok )
       {
+
          // output the part before the BEGIN line, if any
-         String prolog(text.c_str(), start);
+         String prolog(nextToOutput, startBeginLine-2);
          if ( !prolog.empty() )
          {
@@ -449,9 +320,4 @@
          }
 
-         String decodedFile;
-         bool ok = UUdecodeFile(start_data, decodedFile);
-
-         if ( ok )
-         {
 #if 1
             // Let's get a fileType
@@ -463,5 +329,6 @@
             delete fileType;
 
-            MimePartUUencode* decodedMime = new MimePartUUencode(fileName, mimeType, 
decodedFile);
+         MimePartRaw* decodedMime = 
+            new MimePartRaw(fileName, mimeType, decodedFile, _T("uuencoded"));
 
             m_msgView->ShowPart(decodedMime);
@@ -471,204 +338,12 @@
             viewer->InsertText(_T("\"\n"), style);
 #endif
-            // output the part after the END line, if any
-            String epilog(end);
-            if ( !epilog.empty() )
-            {
-                m_next->Process(epilog, viewer, style);
-            }
-         }
-      }
 
-      if ( ok )
-      {
-         // skip the normal display below
-         return;
-      }
-
-      wxLogWarning(_("Part of this message seems to be UU encoded "
-                    "but in fact is not."));
+         nextToOutput = start = endOfEncodedStream;
    }
-
-   m_next->Process(text, viewer, style);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#if 0
-/*
-* Might it be data ? This _should_be_ the most common line type so
-* we need to make it run as fast as we can. 
-*
-* First try a fast UUdecode. This only allows perfectly correct data
-* from a modern uuencoder.
-*/
-
-if  (buf[0] > ' ' && buf[0] <= '`') {
-  int  i, ok = 1;
-  char * cv_ptr = cv_buf;
-  register unsigned char * p=buf;
-
-  cv_len = DEC(*p++);
-
-  /* Actually decode the uue data; ensure characters are in range. */
-  if (ok) for (i=0; i<cv_len; i+=3, p+=4) {
-    if ( (p[0]<=' ' || p[0]>'`') ||
-      (p[1]<=' ' || p[1]>'`') ||
-      (p[2]<=' ' || p[2]>'`') ||
-      (p[3]<=' ' || p[3]>'`') ) {
-        ok = 0;
-        break;
       }
-      *cv_ptr++ = DEC(*p) << 2 | DEC(p[1]) >> 4;
-      *cv_ptr++ = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
-      *cv_ptr++ = DEC(p[2]) << 6 | DEC(p[3]);
+   String prolog(nextToOutput);
+   if ( !prolog.empty() )
+   {
+      m_next->Process(prolog, viewer, style);
   }
-  if (*p != '\r' && *p != '\n' && *p != '\0')
-    ok=0;
-  else  *p=0;
-
-  if (ok) return cv_len ? LINE_UUDATA : LINE_EOD;
 }
-
-
-
-
-         /* 
-         * This decodes any line as a data line (like an ancient decoder would)
-         * it may be required for broken uuencoders.
-         *
-         * If the line is the wrong length it will still complain about corruption
-         * but unlike the normal decoder it will still classify the line as data.
-         *
-         * Unlike the original BSD decoder if the line is too short it assumes
-         * that trailing spaces have been clipped.
-         *
-         */
-         int decode_uue_line(char * buf, int data_type)
-         {
-           int len,i;
-           register unsigned char * p;
-
-           /* Remove EOL marker - any style. */
-           for(len=strlen(buf); len>0 && (buf[len-1]=='\r' || buf[len-1]=='\n') ;) 
-             buf[--len] = 0;
-
-           if (data_type == LINE_DATA || data_type == LINE_BEGIN) {
-             char * cv_ptr = cv_buf;
-             int expected;
-
-             cv_len = buf[0] ? DEC(buf[0]) :0;
-
-             /* Check for stripped trailing spaces. */
-             expected = (((cv_len + 2) / 3) << 2) + 1;
-
-             /* Warn about corruption */
-             if (len != expected) corruption = 1;
-
-             /* Add any stripped spaces */
-             for (; len < expected; ) buf[len++] = ' '; buf[len] = 0;
-
-             for (i=0,p=buf+1; i<cv_len; i+=3, p+=4) {
-               *cv_ptr++ = DEC(*p) << 2 | DEC(p[1]) >> 4;
-               *cv_ptr++ = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
-               *cv_ptr++ = DEC(p[2]) << 6 | DEC(p[3]);
-             }
-             return cv_len?LINE_DATA:LINE_EOD;
-           }
-           if (strncmp(buf, "begin ", 6) == 0) return LINE_BEGIN;
-           if (strcmp(buf, "end") == 0) return LINE_END;
-
-           return LINE_JUNK;
-         }
-
-
-
-
-
-
-         /* A more normal uudecoder, it's stricter than most but allows some
-         * varients. */
-         if  (len<89 && buf[0] >= ' ' && buf[0] <= '`') {
-           int  expected, ok = 1;
-           char * cv_ptr = cv_buf;
-           register unsigned char * p=buf+1;
-
-           cv_len = DEC(buf[0]);
-
-           /* The expected length may be either enough for all the byte triples
-           * or just enough characters for all the bits.
-           */
-           expected = (((cv_len + 2) / 3) << 2) + 1;
-           if (ok && len != expected) {
-
-             /* If the line is one byte too long try for a checksum */
-             if (len == expected + 1 || len == (cv_len*8 + 5)/6 + 2) {
-               int csum = 0;
-               for(i=1; i<len-1; i++) csum += DEC(buf[i]);
-               if ((csum & 077) != DEC(buf[len-1])) ok = 0;
-               else len--;
-             }
-             /* Is the line the precise length needed for the bits ? */
-             else if (len != (cv_len*8 + 5)/6 + 1)
-               ok = 0;
-
-             if (ok) {
-               /* Pad to where we originally expected the data. */
-               strcpy(lbuf, buf); p = lbuf + 1;
-               llen = len;
-               while (llen < expected) lbuf[llen++] = '`'; lbuf[llen] = 0;
-             }
-           }
-
-           /* Actually decode the uue data; ensure characters are in range. */
-           if (ok) for (i=1; i<expected; i+=4, p+=4) {
-             if ( (p[0]<' ' || p[0]>'`') ||
-               (p[1]<' ' || p[1]>'`') ||
-               (p[2]<' ' || p[2]>'`') ||
-               (p[3]<' ' || p[3]>'`') ) {
-                 ok = 0;
-                 break;
-               }
-               *cv_ptr++ = DEC(*p) << 2 | DEC(p[1]) >> 4;
-               *cv_ptr++ = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
-               *cv_ptr++ = DEC(p[2]) << 6 | DEC(p[3]);
-           }
-           if (ok) return cv_len ? LINE_UUDATA : LINE_EOD;
-         }
-
-#endif
\ No newline at end of file



-------------------------------------------------------
This SF.Net email is sponsored by: SourceForge.net Broadband
Sign-up now for SourceForge Broadband and get the fastest
6.0/768 connection for only $19.95/mo for the first 3 months!
http://ads.osdn.com/?ad_id=2562&alloc_id=6184&op=click
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to