Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Protected Member Functions | Protected Attributes
MsgMapiListContext Class Reference
Collaboration diagram for MsgMapiListContext:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 MsgMapiListContext ()
 ~MsgMapiListContext ()
nsresult OpenDatabase (nsIMsgFolder *folder)
nsMsgKey GetNext ()
nsresult MarkRead (nsMsgKey key, PRBool read)
lpnsMapiMessage GetMessage (nsMsgKey, unsigned long flFlags)
PRBool IsIMAPHost (void)
PRBool DeleteMessage (nsMsgKey key)

Protected Member Functions

char * ConvertDateToMapiFormat (time_t)
char * ConvertBodyToMapiFormat (nsIMsgDBHdr *hdr)
void ConvertRecipientsToMapiFormat (nsIMsgHeaderParser *parser, const char *ourRecips, lpnsMapiRecipDesc mapiRecips, int mapiRecipClass)

Protected Attributes

nsCOMPtr< nsIMsgFolderm_folder
nsCOMPtr< nsIMsgDatabasem_db
nsCOMPtr< nsISimpleEnumeratorm_msgEnumerator

Detailed Description

Definition at line 346 of file msgMapiImp.cpp.


Constructor & Destructor Documentation

Definition at line 349 of file msgMapiImp.cpp.

{}

Definition at line 527 of file msgMapiImp.cpp.

{
  if (m_db)
    m_db->Close(PR_FALSE);
}

Member Function Documentation

Definition at line 746 of file msgMapiImp.cpp.

{
  const int kBufLen = 64000; // I guess we only return the first 64K of a message.
  int bytesUsed = 0;
#define EMPTY_MESSAGE_LINE(buf) (buf[0] == nsCRT::CR || buf[0] == nsCRT::LF || buf[0] == '\0')

  nsCOMPtr <nsIMsgFolder> folder;
  hdr->GetFolder(getter_AddRefs(folder));
  if (!folder)
    return nsnull;

  nsCOMPtr <nsIInputStream> inputStream;
  nsCOMPtr <nsIFileSpec> fileSpec;
  folder->GetPath(getter_AddRefs(fileSpec));
  nsFileSpec realSpec;
  fileSpec->GetFileSpec(&realSpec);
  nsCOMPtr <nsILocalFile> localFile;
  NS_FileSpecToIFile(&realSpec, getter_AddRefs(localFile));

  nsresult rv;
  nsCOMPtr<nsIFileInputStream> fileStream = do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, nsnull);

  rv = fileStream->Init(localFile,  PR_RDONLY, 0664, PR_FALSE);  //just have to read the messages
  inputStream = do_QueryInterface(fileStream);

  if (inputStream)
  {
    nsCOMPtr <nsILineInputStream> fileLineStream = do_QueryInterface(inputStream);
    if (!fileLineStream)
      return nsnull;
    // ### really want to skip past headers...
    PRUint32 messageOffset;
    PRUint32 lineCount;
    hdr->GetMessageOffset(&messageOffset);
    hdr->GetLineCount(&lineCount);
    nsCOMPtr <nsISeekableStream> seekableStream = do_QueryInterface(inputStream);
    seekableStream->Seek(PR_SEEK_SET, messageOffset);
    PRBool hasMore = PR_TRUE;
    nsCAutoString curLine;
    PRBool inMessageBody = PR_FALSE;
    nsresult rv = NS_OK;
    while (hasMore) // advance past message headers
    {
      nsresult rv = fileLineStream->ReadLine(curLine, &hasMore);
      if (NS_FAILED(rv) || EMPTY_MESSAGE_LINE(curLine))
        break;
    }
    PRUint32 msgSize;
    hdr->GetMessageSize(&msgSize);
    if (msgSize > kBufLen)
      msgSize = kBufLen - 1;
    // this is too big, since it includes the msg hdr size...oh well
    char *body = (char*) CoTaskMemAlloc (msgSize + 1);

    if (!body)
      return nsnull;
    PRInt32 bytesCopied = 0;
    for (hasMore = TRUE; lineCount > 0 && hasMore && NS_SUCCEEDED(rv); lineCount--)
    {
      rv = fileLineStream->ReadLine(curLine, &hasMore);
      if (NS_FAILED(rv))
        break;
      curLine.Append(CRLF);
      // make sure we have room left
      if (bytesCopied + curLine.Length() < msgSize)
      {
        strcpy(body + bytesCopied, curLine.get());
        bytesCopied += curLine.Length();
      }
    }
    PR_LOG(MAPI, PR_LOG_DEBUG, ("ConvertBodyToMapiFormat size=%x allocated size %x body = %100.100s\n", 
        bytesCopied, msgSize + 1, (char *) body) );
    body[bytesCopied] = '\0';   // rhp - fix last line garbage...
    return body;
  }
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char * MsgMapiListContext::ConvertDateToMapiFormat ( time_t  ourTime) [protected]

Definition at line 682 of file msgMapiImp.cpp.

{
  char *date = (char*) CoTaskMemAlloc(32);
  if (date)
  {
    // MAPI time format is YYYY/MM/DD HH:MM
    // Note that we're not using XP_StrfTime because that localizes the time format,
    // and the way I read the MAPI spec is that their format is canonical, not localized.
    struct tm *local = localtime (&ourTime);
    if (local)
      strftime (date, 32, "%Y/%m/%d %I:%M", local); //use %H if hours should be 24 hour format
  }
  return date;
}

Here is the caller graph for this function:

void MsgMapiListContext::ConvertRecipientsToMapiFormat ( nsIMsgHeaderParser parser,
const char *  ourRecips,
lpnsMapiRecipDesc  mapiRecips,
int  mapiRecipClass 
) [protected]

Definition at line 698 of file msgMapiImp.cpp.

{
  char *names = nsnull;
  char *addresses = nsnull;
  
  if (!parser)
    return ;
  PRUint32 numAddresses = 0;
  parser->ParseHeaderAddresses(nsnull, recipients, &names, &addresses, &numAddresses);
  
  if (numAddresses > 0)
  {
    char *walkNames = names;
    char *walkAddresses = addresses;
    for (int i = 0; i < numAddresses; i++)
    {
      if (walkNames)
      {
        if (*walkNames)
        {
          mapiRecips[i].lpszName = (char *) CoTaskMemAlloc(strlen(walkNames) + 1);
          if (mapiRecips[i].lpszName )
            strcpy((char *) mapiRecips[i].lpszName, walkNames);
        }
        walkNames += strlen (walkNames) + 1;
      }
      
      if (walkAddresses)
      {
        if (*walkAddresses)
        {
          mapiRecips[i].lpszAddress = (char *) CoTaskMemAlloc(strlen(walkAddresses) + 1);
          if (mapiRecips[i].lpszAddress)
            strcpy((char *) mapiRecips[i].lpszAddress, walkAddresses);
        }
        walkAddresses += strlen (walkAddresses) + 1;
      }
      
      mapiRecips[i].ulRecipClass = mapiRecipClass;
    }
  }
  
  PR_Free(names);
  PR_Free(addresses);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 901 of file msgMapiImp.cpp.

{
  if (!m_db)
    return FALSE;
  
  nsMsgKeyArray messageKeys;      
  messageKeys.InsertAt(0, key);
  
  if ( !IsIMAPHost() )
  {
    return NS_SUCCEEDED((m_db->DeleteMessages(&messageKeys, nsnull)));
  }
  else
  {
    return FALSE;
#if 0 
    if ( m_folder->GetIMAPFolderInfoMail() )
    {
      (m_folder->GetIMAPFolderInfoMail())->DeleteSpecifiedMessages(pane, messageKeys, nsMsgKey_None);
      m_db->DeleteMessage(key, nsnull, FALSE);
      return TRUE;
    }
    else
    {
      return FALSE;
    }
#endif
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 609 of file msgMapiImp.cpp.

{
  lpnsMapiMessage message = (lpnsMapiMessage) CoTaskMemAlloc (sizeof(nsMapiMessage));
  memset(message, 0, sizeof(nsMapiMessage));
  if (message)
  {
    nsXPIDLCString subject;
    nsXPIDLCString author;
    nsCOMPtr <nsIMsgDBHdr> msgHdr;

    nsresult rv = m_db->GetMsgHdrForKey (key, getter_AddRefs(msgHdr));
    if (msgHdr)
    {
      msgHdr->GetSubject (getter_Copies(subject));
      message->lpszSubject = (char *) CoTaskMemAlloc(subject.Length() + 1);
      strcpy((char *) message->lpszSubject, subject.get());
      PRUint32 date;
      (void) msgHdr->GetDateInSeconds(&date);
      message->lpszDateReceived = ConvertDateToMapiFormat (date);
      
      // Pull out the flags info
      // anything to do with MAPI_SENT? Since we're only reading the Inbox, I guess not
      PRUint32 ourFlags;
      (void) msgHdr->GetFlags(&ourFlags);
      if (!(ourFlags & MSG_FLAG_READ))
        message->flFlags |= MAPI_UNREAD;
      if (ourFlags & (MSG_FLAG_MDN_REPORT_NEEDED | MSG_FLAG_MDN_REPORT_SENT))
        message->flFlags |= MAPI_RECEIPT_REQUESTED;
      
      nsCOMPtr<nsIMsgHeaderParser> parser = do_GetService(NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID);
      if (!parser)
        return nsnull;
      // Pull out the author/originator info
      message->lpOriginator = (lpnsMapiRecipDesc) CoTaskMemAlloc (sizeof(nsMapiRecipDesc));
      memset(message->lpOriginator, 0, sizeof(nsMapiRecipDesc));
      if (message->lpOriginator)
      {
        msgHdr->GetAuthor (getter_Copies(author));
        ConvertRecipientsToMapiFormat (parser, author.get(), message->lpOriginator, MAPI_ORIG);
      }
      // Pull out the To/CC info
      nsXPIDLCString recipients, ccList;
      msgHdr->GetRecipients(getter_Copies(recipients));
      msgHdr->GetCcList(getter_Copies(ccList));

      PRUint32 numToRecips;
      PRUint32 numCCRecips;
      parser->ParseHeaderAddresses(nsnull, recipients, nsnull, nsnull, &numToRecips);
      parser->ParseHeaderAddresses(nsnull, ccList, nsnull, nsnull, &numCCRecips);

      message->lpRecips = (lpnsMapiRecipDesc) CoTaskMemAlloc ((numToRecips + numCCRecips) * sizeof(MapiRecipDesc));
      memset(message->lpRecips, 0, (numToRecips + numCCRecips) * sizeof(MapiRecipDesc));
      if (message->lpRecips)
      {
        ConvertRecipientsToMapiFormat (parser, recipients, message->lpRecips, MAPI_TO);
        ConvertRecipientsToMapiFormat (parser, ccList, &message->lpRecips[numToRecips], MAPI_CC);
      }
  
      PR_LOG(MAPI, PR_LOG_DEBUG, ("MsgMapiListContext::GetMessage flags=%x subject %s date %s sender %s\n", 
        flFlags, (char *) message->lpszSubject,(char *) message->lpszDateReceived, author.get()) );

      // Convert any body text that we have locally
      if (!(flFlags & MAPI_ENVELOPE_ONLY))
        message->lpszNoteText = (char *) ConvertBodyToMapiFormat (msgHdr);
      
    }
    if (! (flFlags & (MAPI_PEEK | MAPI_ENVELOPE_ONLY)))
      m_db->MarkRead(key, PR_TRUE, nsnull);
  }
  return message;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 557 of file msgMapiImp.cpp.

{
  nsMsgKey key = nsMsgKey_None;
  PRBool    keepTrying = TRUE;
  
//  NS_ASSERTION (m_msgEnumerator && m_db, "need enumerator and db");
  if (m_msgEnumerator && m_db)
  {
    
    do 
    {
      keepTrying = FALSE;  
      nsCOMPtr <nsISupports> hdrISupports;
      nsCOMPtr <nsIMsgDBHdr> msgHdr;
      if (NS_SUCCEEDED(m_msgEnumerator->GetNext(getter_AddRefs(hdrISupports))) && hdrISupports)
      {
        msgHdr = do_QueryInterface(hdrISupports);
        msgHdr->GetMessageKey(&key);
        
        // Check here for IMAP message...if not, just return...
        if (!IsIMAPHost())
          return key;
        
        // If this is an IMAP message, we have to make sure we have a valid
        // body to work with.
        PRUint32  flags = 0;
        
        (void) msgHdr->GetFlags(&flags);
        if (flags & MSG_FLAG_OFFLINE) 
          return key;
        
        // Ok, if we get here, we have an IMAP message without a body!
        // We need to keep trying by calling the GetNext member recursively...
        keepTrying = TRUE;
      }
    } while (keepTrying);
  }
  
  return key;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 548 of file msgMapiImp.cpp.

{
  if (!m_folder) 
    return FALSE;
  nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_folder);

  return imapFolder != nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 599 of file msgMapiImp.cpp.

{
  nsresult err = NS_ERROR_FAILURE;
  NS_ASSERTION(m_db, "no db");
  if (m_db)
    err = m_db->MarkRead (key, read, nsnull);
  return err;
}

Here is the caller graph for this function:

Definition at line 534 of file msgMapiImp.cpp.

{
  nsresult dbErr = NS_ERROR_FAILURE;
  if (folder)
  {
    m_folder = folder;
    dbErr = folder->GetMsgDatabase(nsnull, getter_AddRefs(m_db));
    if (m_db)
      dbErr = m_db->EnumerateMessages(getter_AddRefs(m_msgEnumerator));
  }
  return dbErr;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 370 of file msgMapiImp.cpp.

Definition at line 369 of file msgMapiImp.cpp.

Definition at line 371 of file msgMapiImp.cpp.


The documentation for this class was generated from the following file: