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