Update of /cvsroot/mahogany/M/src/classes
In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv14177/src/classes

Modified Files:
        MessageView.cpp 
Log Message:
added multipart/related support

Index: MessageView.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/classes/MessageView.cpp,v
retrieving revision 1.171
retrieving revision 1.172
diff -b -u -2 -r1.171 -r1.172
--- MessageView.cpp     8 Apr 2006 01:40:32 -0000       1.171
+++ MessageView.cpp     26 Jun 2006 18:26:02 -0000      1.172
@@ -81,4 +81,5 @@
 #include <wx/fontutil.h>
 #include <wx/tokenzr.h>
+#include <wx/fs_mem.h>
 
 #ifdef OS_UNIX
@@ -233,4 +234,14 @@
 };
 
+// a wxFileSystem providing access to MIME parts data
+class MIMEFSHandler : public wxMemoryFSHandler
+{
+public:
+   virtual bool CanOpen(const wxString& location)
+   {
+      return GetProtocol(location) == _T("cid");
+   }
+};
+
 // ----------------------------------------------------------------------------
 // TransparentFilter: the filter which doesn't filter anything but simply
@@ -564,4 +575,5 @@
    m_filters = NULL;
    m_virtualMimeParts = NULL;
+   m_cidsInMemory = NULL;
 
    m_uid = UID_ILLEGAL;
@@ -578,4 +590,6 @@
    delete m_virtualMimeParts;
 
+   delete m_cidsInMemory;
+
    UnregisterForEvents();
 
@@ -2070,4 +2084,69 @@
 
 bool
+MessageView::ProcessRelatedMultiPart(const MimePart *mimepart,
+                                     MimePartAction action)
+{
+   // see RFC 2387: http://www.faqs.org/rfcs/rfc2387.html
+
+   // we need to find the start part: it is specified using the "start"
+   // parameter but usually is just the first one as this parameter is optional
+   const String cidStart = mimepart->GetParam("start");
+
+   const MimePart *partChild = mimepart->GetNested();
+
+   const MimePart *partStart = cidStart.empty() ? partChild : NULL;
+
+   while ( partChild )
+   {
+      // if we're just testing, it's enough to find the start part, it's the
+      // only one which counts
+      if ( action == Part_Test && partStart )
+         break;
+
+      // FIXME: this manual parsing is ugly and probably wrong, should add
+      //        a method to MimePart for this...
+      const String headers = partChild->GetHeaders();
+
+      static const char *CONTENT_ID = "content-id: ";
+      static const size_t CONTENT_ID_LEN = 12; // strlen(CONTENT_ID)
+
+      size_t posCID = headers.Lower().find(CONTENT_ID);
+      if ( posCID != String::npos )
+      {
+         posCID += CONTENT_ID_LEN;
+
+         const size_t posEOL = headers.find_first_of("\r\n", posCID);
+
+         String cid;
+         cid.assign(headers, posCID, posEOL - posCID);
+
+         if ( cid == cidStart )
+         {
+            if ( partStart )
+            {
+               wxLogDebug(_T("Duplicate CIDs in multipart/related message"));
+            }
+
+            partStart = partChild;
+         }
+
+         // if we're going to display the part now we need to store all the
+         // parts except the start part in memory so that the start part could
+         // use them
+         if ( !cid.empty() && action == Part_Show && partChild != partStart )
+         {
+            StoreMIMEPartData(partChild, cid);
+         }
+      }
+
+      partChild = partChild->GetNext();
+   }
+
+   CHECK( partStart, false, _T("No start part in multipart/related") );
+
+   return ProcessPart(partStart, action);
+}
+
+bool
 MessageView::ProcessSignedMultiPart(const MimePart *mimepart)
 {
@@ -2247,5 +2326,5 @@
                               MimePartAction action)
 {
-   // TODO: support for DIGEST and RELATED
+   // TODO: support for DIGEST
 
    bool processed = false;
@@ -2254,4 +2333,8 @@
       processed = ProcessAlternativeMultiPart(mimepart, action);
    }
+   else if ( subtype == _T("RELATED") )
+   {
+      processed = ProcessRelatedMultiPart(mimepart, action);
+   }
    else if ( subtype == _T("SIGNED") )
    {
@@ -2364,4 +2447,46 @@
 }
 
+bool MessageView::StoreMIMEPartData(const MimePart *part, const String& cid)
+{
+   unsigned long len;
+   const void *data = part->GetContent(&len);
+
+   if ( !data )
+      return false;
+
+   if ( !m_cidsInMemory )
+   {
+      // one-time initialization
+      m_cidsInMemory = new wxArrayString;
+
+      static bool s_mimeHandlerInitialized = false;
+      if ( !s_mimeHandlerInitialized )
+      {
+         s_mimeHandlerInitialized = true;
+
+         wxFileSystem::AddHandler(new MIMEFSHandler);
+      }
+   }
+
+   m_cidsInMemory->Add(cid);
+   MIMEFSHandler::AddFile(cid, data, len);
+
+   return true;
+}
+
+void MessageView::ClearMIMEPartDataStore()
+{
+   if ( !m_cidsInMemory || m_cidsInMemory->empty() )
+      return;
+
+   const size_t count = m_cidsInMemory->size();
+   for ( size_t n = 0; n < count; n++ )
+   {
+      MIMEFSHandler::RemoveFile((*m_cidsInMemory)[n]);
+   }
+
+   m_cidsInMemory->clear();
+}
+
 // ----------------------------------------------------------------------------
 // finding the best viewer for the current message
@@ -2595,4 +2720,6 @@
    m_textBody.clear();
 
+   ClearMIMEPartDataStore();
+
    m_viewer->Clear();
 


Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Mahogany-cvsupdates mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to