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

Modified Files:
        UUDecode.cpp 
Log Message:
UUdecoding seems to work (at least for the first file in a message)

Index: UUDecode.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/modules/viewflt/UUDecode.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -b -u -2 -r1.1 -r1.2
--- UUDecode.cpp        11 May 2004 13:53:39 -0000      1.1
+++ UUDecode.cpp        13 May 2004 15:19:13 -0000      1.2
@@ -31,4 +31,178 @@
 #include <wx/bitmap.h>
 
+
+
+#include "MimePart.h"
+#include <wx/mimetype.h>
+
+class MimePartUUencode : public MimePart
+{
+public:
+  MimePartUUencode(const String& fileName, const String& mimeType, const String& 
content) 
+    : m_fileName(fileName)
+    , m_mimeType(mimeType)
+    , m_content(content)
+  {}
+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 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 {
+      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 {
+     unsigned long len;
+     const char *p = reinterpret_cast<const char *>(GetContent(&len));
+     if ( !p )
+       return wxGetEmptyString();
+
+#if wxUSE_UNICODE
+#warning "We need the original encoding here, TODO"
+     return wxConvertMB2WX(p);
+#else // ANSI
+     return wxString(p, len);
+#endif // Unicode/ANSI
+   }
+
+
+   /// 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;
+  MimeParameterList m_dispositionParameters;
+
+  String m_fileName;
+  String m_mimeType;
+  String m_content;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 // ----------------------------------------------------------------------------
 // UUDecodeFilter itself
@@ -78,4 +252,74 @@
 // ----------------------------------------------------------------------------
 
+
+#define DEC(c) (((c) - ' ') & 077)
+
+int UUdecodeLine(const wxChar* input, wxChar* output, const wxChar** endOfLine) {
+  if  (input[0] > ' ' && input[0] <= '`') {
+    char * cv_ptr = output;
+    register const wxChar * p=input;
+
+    int cv_len = DEC(*p++);
+
+    /* Actually decode the uue data; ensure characters are in range. */
+    for (int 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]>'`') ) {
+        return -1;
+      }
+      *cv_ptr++ = DEC(p[0]) << 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 (*p != '\r' && *p != '\n' && *p != '\0')
+      return -1;
+    //else  *p=0;
+
+    *endOfLine = p;
+    return cv_len;
+  } else 
+    return -1;
+}
+
+bool UUdecodeFile(const wxChar* input, String& output) {
+
+  static const int allocationSize = 10000;
+
+  String decodedFile;
+  size_t totalAllocatedBytes = 0;
+
+  size_t totalDecodedBytes = 0;
+  int decodedBytesInLine;
+  const wxChar* startOfLine = input;
+  const wxChar* endOfLine = 0; // init not needed
+  wxChar* buffer = new wxChar[45];
+  while ((decodedBytesInLine = UUdecodeLine(startOfLine, buffer, &endOfLine)) > 0) {
+    // We've just decoded a line
+    totalDecodedBytes += decodedBytesInLine;
+    String decodedLine(buffer, decodedBytesInLine);
+    if (decodedFile.length() + (size_t)decodedBytesInLine >= totalAllocatedBytes) {
+      totalAllocatedBytes += allocationSize;
+      decodedFile.Alloc(totalAllocatedBytes);
+    }
+    decodedFile << decodedLine;
+    ASSERT_MSG( decodedFile.Length() == totalDecodedBytes, 
+      _T("Number of decoded bytes does not match!") );
+    ASSERT_MSG( endOfLine[0] == '\r', _T("Line has no '\\r' at the end!") );
+    ASSERT_MSG( endOfLine[1] == '\n', _T("Line has no '\\n' at the end!") );
+    startOfLine = endOfLine + 2;
+  }
+  delete buffer;
+  if (decodedBytesInLine < 0) {
+    return false;
+  }
+  decodedFile.Shrink();
+  output = decodedFile;
+  return true;
+}
+
+
+
 void
 UUDecodeFilter::DoProcess(String& text,
@@ -88,5 +332,6 @@
    bool foundBegin = false;
    const wxChar *start = text.c_str();
-   for ( size_t numLines = 0; numLines < 10; numLines++ )
+   const wxChar* start_data = 0;
+   for ( size_t numLines = 0; numLines < 100; numLines++ )
    {
       if ( wxStrncmp(start, UU_BEGIN_PREFIX, wxStrlen(UU_BEGIN_PREFIX)) == 0 )
@@ -139,4 +384,5 @@
          ASSERT_MSG( tail[1] == '\n', _T("'begin' line does not end with 
\"\\r\\n\"?") );
          fileName = String(startName, tail);
+         start_data = tail + 2;
       }
 
@@ -203,16 +449,21 @@
          }
 
-#if 0
-         String decodedData; // TODO: decode, of course...
-         MimePartText* decodedMime = new MimePartText(decodedData);
-         ClickableAttachment *attachment = 
-           new ClickableAttachment((MessageView*)0, decodedMime);
-
-          // get the icon for the attachment using its 
-          // filename extension (if any)
-          wxIcon icon = mApplication->GetIconManager()->
-                            GetIconFromMimeType("", fileName.AfterLast('.'));
+         String decodedFile;
+         bool ok = UUdecodeFile(start_data, decodedFile);
 
-          viewer->InsertAttachment(icon, attachment);
+         if ( ok )
+         {
+#if 1
+            // Let's get a fileType
+            wxFileType *fileType = 
mApplication->GetMimeManager().GetFileTypeFromExtension(fileName.AfterLast('.'));
+            String mimeType;
+            if (!fileType->GetMimeType(&mimeType)) {
+              mimeType = _T("APPLICATION/OCTET-STREAM");
+            }
+            delete fileType;
+
+            MimePartUUencode* decodedMime = new MimePartUUencode(fileName, mimeType, 
decodedFile);
+
+            m_msgView->ShowPart(decodedMime);
 #else
           viewer->InsertText(_T("UUencoded file named \""), style);
@@ -227,4 +478,5 @@
           }
       }
+      }
 
       if ( ok )
@@ -241,2 +493,182 @@
 }
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#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]);
+  }
+  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