Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Types | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Protected Attributes
nsMsgSearchNewsEx Class Reference

#include <nsMsgSearchNews.h>

Inheritance diagram for nsMsgSearchNewsEx:
Inheritance graph
[legend]
Collaboration diagram for nsMsgSearchNewsEx:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsMsgSearchNewsEx (nsMsgSearchScopeTerm *scope, nsISupportsArray *termList)
virtual ~nsMsgSearchNewsEx ()
NS_IMETHOD ValidateTerms ()
NS_IMETHOD Search (PRBool *aDone)
virtual nsresult Encode (nsCString *pEncoding)
nsresult SaveProfile (const char *profileName)
void Search (out boolean done)
NS_IMETHOD GetEncoding (char **result)
NS_IMETHOD AddHit (nsMsgKey key)
void AddHit (in nsMsgKey key)
NS_IMETHOD CurrentUrlDone (PRInt32 exitCode)
void CurrentUrlDone (in long exitCode)
virtual char * EncodeTerm (nsIMsgSearchTerm *)
PRUnicharEncodeToWildmat (const PRUnichar *)
void ReportHits ()
PRBool DuplicateHit (PRUint32 artNum)
void CollateHits ()
void ReportHit (nsIMsgDBHdr *pHeaders, nsIMsgFolder *folder)
void SendUrl ()
void AddResultElement (in nsIMsgDBHdr aHdr)
void OpenResultElement (in nsMsgResultElement element)
void ModifyResultElement (in nsMsgResultElement element, in nsMsgSearchValue value)
nsIMsgFolder FindTargetFolder ([const ] in nsMsgResultElement element)
void Abort ()
void getSearchCharsets (out wstring srcCharset, out wstring destCharset)

Static Public Member Functions

static int PR_CALLBACK CompareArticleNumbers (const void *v1, const void *v2, void *data)
static nsresult EncodeImap (char **ppEncoding, nsISupportsArray *searchTerms, const PRUnichar *srcCharset, const PRUnichar *destCharset, PRBool reallyDredd=PR_FALSE)
static nsresult EncodeImapValue (char *encoding, const char *value, PRBool useQuotes, PRBool reallyDredd)
static char * GetImapCharsetParam (const PRUnichar *destCharset)
static PRUnicharEscapeSearchUrl (const PRUnichar *nntpCommand)
static PRUnicharEscapeImapSearchProtocol (const PRUnichar *imapCommand)
static PRUnicharEscapeQuoteImapSearchProtocol (const PRUnichar *imapCommand)
static char * UnEscapeSearchUrl (const char *commandSpecificData)

Public Attributes

NS_DECL_ISUPPORTS
NS_DECL_NSIMSGSEARCHADAPTER
nsIMsgSearchScopeTerm
m_scope
nsCOMPtr< nsISupportsArraym_searchTerms
PRBool m_abortCalled
nsXPIDLString m_defaultCharset
PRBool m_forceAsciiSearch
readonly attribute string encoding

Static Public Attributes

static const char * m_kImapBefore = " SENTBEFORE "
static const char * m_kImapBody = " BODY "
static const char * m_kImapCC = " CC "
static const char * m_kImapFrom = " FROM "
static const char * m_kImapNot = " NOT"
static const char * m_kImapOr = " OR"
static const char * m_kImapSince = " SENTSINCE "
static const char * m_kImapSubject = " SUBJECT "
static const char * m_kImapTo = " TO "
static const char * m_kImapHeader = " HEADER"
static const char * m_kImapAnyText = " TEXT "
static const char * m_kImapKeyword = " KEYWORD "
static const char * m_kNntpKeywords = " KEYWORDS "
static const char * m_kImapSentOn = " SENTON "
static const char * m_kImapSeen = " SEEN "
static const char * m_kImapAnswered = " ANSWERED "
static const char * m_kImapNotSeen = " UNSEEN "
static const char * m_kImapNotAnswered = " UNANSWERED "
static const char * m_kImapCharset = " CHARSET "
static const char * m_kImapUnDeleted = " UNDELETED"
static const char * m_kImapSizeSmaller = " SMALLER "
static const char * m_kImapSizeLarger = " LARGER "
static const char * m_kImapNew = " NEW "
static const char * m_kImapNotNew = " OLD SEEN "
static const char * m_kImapFlagged = " FLAGGED "
static const char * m_kImapNotFlagged = " UNFLAGGED "

Protected Types

enum  _msg_TransformType { kOverwrite, kInsert, kSurround }
typedef enum
nsMsgSearchAdapter::_msg_TransformType 
msg_TransformType

Protected Member Functions

char * TransformSpacesToStars (const char *, msg_TransformType transformType)
nsresult OpenNewsResultInUnknownGroup (nsMsgResultElement *)

Static Protected Member Functions

static nsresult EncodeImapTerm (nsIMsgSearchTerm *, PRBool reallyDredd, const PRUnichar *srcCharset, const PRUnichar *destCharset, char **ppOutTerm)

Protected Attributes

nsCString m_encoding
PRBool m_ORSearch
nsMsgKeyArray m_candidateHits
nsMsgKeyArray m_hits

Static Protected Attributes

static const char * m_kSearchTemplate = "?search/SEARCH HEADER NEWSGROUPS %s %s"
static const char * m_kProfileTemplate = "%s/dummy?profile/PROFILE NEW %s HEADER NEWSGROUPS %s %s"
static const char * m_kNntpFrom = "FROM "
static const char * m_kNntpSubject = "SUBJECT "
static const char * m_kTermSeparator = "/"
static const char * m_kUrlPrefix

Detailed Description

Definition at line 82 of file nsMsgSearchNews.h.


Member Typedef Documentation


Member Enumeration Documentation

enum nsMsgSearchAdapter::_msg_TransformType [protected, inherited]
Enumerator:
kOverwrite 
kInsert 
kSurround 

Definition at line 127 of file nsMsgSearchAdapter.h.

  {
         kOverwrite,    /* "John Doe" -> "John*Doe",   simple contains   */
         kInsert,       /* "John Doe" -> "John* Doe",  name completion   */
         kSurround      /* "John Doe" -> "John* *Doe", advanced contains */
  } msg_TransformType;

Constructor & Destructor Documentation

Definition at line 474 of file nsMsgSearchNews.cpp.

                                                                                             : nsMsgSearchNews (scope, termList) 
{
}

Definition at line 479 of file nsMsgSearchNews.cpp.

{
}

Member Function Documentation

Implemented in nsMsgSearchOfflineMail.

Definition at line 317 of file nsMsgSearchNews.cpp.

{
  m_candidateHits.Add (key); 
  return NS_OK;
}

Definition at line 364 of file nsMsgSearchNews.cpp.

{
       // Since the XPAT commands are processed one at a time, the result set for the
       // entire query is the intersection of results for each XPAT command if an AND Search
       // otherwise we want the union of all the search hits (minus the duplicates of course)

       if (m_candidateHits.GetSize() == 0)
              return;

       // Sort the article numbers first, so it's easy to tell how many hits
       // on a given article we got
       m_candidateHits.QuickSort(CompareArticleNumbers);
       int size = m_candidateHits.GetSize();
       int index = 0;
       PRUint32 candidate = m_candidateHits.ElementAt(index);

       if (m_ORSearch)
       {
              for (index = 0; index < size; index++)
              {
                     candidate = m_candidateHits.ElementAt(index);
                     if (!DuplicateHit(candidate)) // if not a dup, add it to the hit list
                            m_hits.Add (candidate);
              }
              return;
       }


       // otherwise we have a traditional and search which must be collated

       // In order to get promoted into the hits list, a candidate article number
       // must appear in the results of each XPAT command. So if we fire 3 XPAT
       // commands (one per search term), the article number must appear 3 times.
       // If it appears less than 3 times, it matched some search terms, but not all

       PRUint32 termCount;
  m_searchTerms->Count(&termCount);
       PRUint32 candidateCount = 0;
       while (index < size)
       {
              if (candidate == m_candidateHits.ElementAt(index))
                     candidateCount++;
              else
                     candidateCount = 1;
              if (candidateCount == termCount)
                     m_hits.Add (m_candidateHits.ElementAt(index));
              candidate = m_candidateHits.ElementAt(index++);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int PR_CALLBACK nsMsgSearchNews::CompareArticleNumbers ( const void v1,
const void v2,
void data 
) [static, inherited]

Definition at line 456 of file nsMsgSearchNews.cpp.

{
       // QuickSort callback to compare article numbers

       uint32 i1 = *(uint32*) v1;
       uint32 i2 = *(uint32*) v2;
       return i1 - i2;
}

Here is the caller graph for this function:

void nsIMsgSearchAdapter::CurrentUrlDone ( in long  exitCode) [inherited]

Definition at line 324 of file nsMsgSearchNews.cpp.

{
       CollateHits();
       ReportHits();
  return NS_OK;
}

Here is the call graph for this function:

Definition at line 353 of file nsMsgSearchNews.cpp.

{
       PRUint32 index;
       for (index = 0; index < m_hits.GetSize(); index++)
              if (artNum == m_hits.ElementAt(index))
                     return PR_TRUE;
       return PR_FALSE;
}

Here is the caller graph for this function:

nsresult nsMsgSearchNewsEx::Encode ( nsCString pEncoding) [virtual]

Reimplemented from nsMsgSearchNews.

Definition at line 499 of file nsMsgSearchNews.cpp.

{
       *ppOutEncoding = "";
       char *imapTerms = nsnull;

       // Figure out the charsets to use for the search terms and targets.
       nsXPIDLString srcCharset, dstCharset;
       GetSearchCharsets(getter_Copies(srcCharset), getter_Copies(dstCharset));

       nsresult err = EncodeImap (&imapTerms, m_searchTerms, srcCharset.get(), dstCharset.get(), PR_TRUE /*reallyDredd*/);
#ifdef DOING_DREDD
       if (NS_OK == err)
       {
              char *scopeString = nsnull; 
              err = m_scope->m_frame->EncodeDreddScopes (&scopeString);
              if (NS_OK == err)
              {
                     // Wrap the pattern with the RFC-977bis (Dredd) specified SEARCH syntax
                     char *dreddEncoding = PR_smprintf (m_kSearchTemplate, scopeString, imapTerms);
                     if (dreddEncoding)
                     {
                            // Build the encoding part of the URL e.g. search?SEARCH FROM "John Smith"
                            *ppOutEncoding = dreddEncoding;
                            nsCRT::free(dreddEncoding);
                     }
                     else
                            err = NS_ERROR_OUT_OF_MEMORY;
                     nsCRT::free(scopeString);
              }
       }
#endif
       return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsMsgSearchAdapter::EncodeImap ( char **  ppEncoding,
nsISupportsArray searchTerms,
const PRUnichar srcCharset,
const PRUnichar destCharset,
PRBool  reallyDredd = PR_FALSE 
) [static, inherited]

Definition at line 765 of file nsMsgSearchAdapter.cpp.

{
  // i've left the old code (before using CBoolExpression for debugging purposes to make sure that
  // the new code generates the same encoding string as the old code.....
  
  nsresult err = NS_OK;
  *ppOutEncoding = nsnull;
  
  PRUint32 termCount;
  searchTerms->Count(&termCount);
  PRUint32 i = 0;
  
  // create our expression
  nsMsgSearchBoolExpression * expression = new nsMsgSearchBoolExpression();
  if (!expression)
    return NS_ERROR_OUT_OF_MEMORY;
  
  for (i = 0; i < termCount && NS_SUCCEEDED(err); i++)
  {
    char *termEncoding;
    nsCOMPtr<nsIMsgSearchTerm> pTerm;
    searchTerms->QueryElementAt(i, NS_GET_IID(nsIMsgSearchTerm),
      (void **)getter_AddRefs(pTerm));
    err = EncodeImapTerm (pTerm, reallyDredd, srcCharset, destCharset, &termEncoding);
    if (NS_SUCCEEDED(err) && nsnull != termEncoding)
    {
      expression = nsMsgSearchBoolExpression::AddSearchTerm(expression, pTerm, termEncoding);
      delete [] termEncoding;
    }
  }
  
  if (NS_SUCCEEDED(err)) 
  {
    // Catenate the intermediate encodings together into a big string
    nsCAutoString encodingBuff;
    
    if (!reallyDredd)
      encodingBuff.Append(m_kImapUnDeleted);

    expression->GenerateEncodeStr(&encodingBuff);
    *ppOutEncoding = ToNewCString(encodingBuff);
  }
  
  delete expression;
  
  return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsMsgSearchAdapter::EncodeImapTerm ( nsIMsgSearchTerm term,
PRBool  reallyDredd,
const PRUnichar srcCharset,
const PRUnichar destCharset,
char **  ppOutTerm 
) [static, protected, inherited]

Definition at line 401 of file nsMsgSearchAdapter.cpp.

{
  nsresult err = NS_OK;
  PRBool useNot = PR_FALSE;
  PRBool useQuotes = PR_FALSE;
  PRBool ignoreValue = PR_FALSE;
  nsCAutoString arbitraryHeader;
  const char *whichMnemonic = nsnull;
  const char *orHeaderMnemonic = nsnull;
  
  *ppOutTerm = nsnull;
  
  nsCOMPtr <nsIMsgSearchValue> searchValue;
  nsresult rv = term->GetValue(getter_AddRefs(searchValue));
  
  if (NS_FAILED(rv))
    return rv;
  
  nsMsgSearchOpValue op;
  term->GetOp(&op);
  
  if (op == nsMsgSearchOp::DoesntContain || op == nsMsgSearchOp::Isnt)
    useNot = PR_TRUE;
  
  nsMsgSearchAttribValue attrib;
  term->GetAttrib(&attrib);
  
  switch (attrib)
  {
  case nsMsgSearchAttrib::ToOrCC:
    orHeaderMnemonic = m_kImapCC;
    // fall through to case nsMsgSearchAttrib::To:
  case nsMsgSearchAttrib::To:
    whichMnemonic = m_kImapTo;
    break;
  case nsMsgSearchAttrib::CC:
    whichMnemonic = m_kImapCC;
    break;
  case nsMsgSearchAttrib::Sender:
    whichMnemonic = m_kImapFrom;
    break;
  case nsMsgSearchAttrib::Subject:
    whichMnemonic = m_kImapSubject;
    break;
  case nsMsgSearchAttrib::Body:
    whichMnemonic = m_kImapBody;
    break;
  case nsMsgSearchAttrib::AgeInDays:  // added for searching online for age in days...
    // for AgeInDays, we are actually going to perform a search by date, so convert the operations for age
    // to the IMAP mnemonics that we would use for date!
    switch (op)
    {
    case nsMsgSearchOp::IsGreaterThan:
      whichMnemonic = m_kImapBefore;
      break;
    case nsMsgSearchOp::IsLessThan:
      whichMnemonic = m_kImapSince;
      break;
    case nsMsgSearchOp::Is:
      whichMnemonic = m_kImapSentOn;
      break;
    default:
      NS_ASSERTION(PR_FALSE, "invalid search operator");
      return NS_ERROR_INVALID_ARG;
    }
    break;
  case nsMsgSearchAttrib::Size:
    switch (op)
    {
    case nsMsgSearchOp::IsGreaterThan:
      whichMnemonic = m_kImapSizeLarger;
      break;
    case nsMsgSearchOp::IsLessThan:
      whichMnemonic = m_kImapSizeSmaller;
      break;
    default:
      NS_ASSERTION(PR_FALSE, "invalid search operator");
      return NS_ERROR_INVALID_ARG;
    }
    break;
    case nsMsgSearchAttrib::Date:
      switch (op)
      {
      case nsMsgSearchOp::IsBefore:
        whichMnemonic = m_kImapBefore;
        break;
      case nsMsgSearchOp::IsAfter:
        whichMnemonic = m_kImapSince;
        break;
      case nsMsgSearchOp::Isnt:  /* we've already added the "Not" so just process it like it was a date is search */
      case nsMsgSearchOp::Is:
        whichMnemonic = m_kImapSentOn;
        break;
      default:
        NS_ASSERTION(PR_FALSE, "invalid search operator");
        return NS_ERROR_INVALID_ARG;
      }
      break;
      case nsMsgSearchAttrib::AnyText:
        whichMnemonic = m_kImapAnyText;
        break;
      case nsMsgSearchAttrib::Keywords:
        whichMnemonic = m_kImapKeyword;
        break;
      case nsMsgSearchAttrib::MsgStatus:
        useNot = PR_FALSE; // bizarrely, NOT SEEN is wrong, but UNSEEN is right.
        ignoreValue = PR_TRUE; // the mnemonic is all we need
        PRUint32 status;
        searchValue->GetStatus(&status);
        
        switch (status)
        {
        case MSG_FLAG_READ:
          whichMnemonic = op == nsMsgSearchOp::Is ? m_kImapSeen : m_kImapNotSeen;
          break;
        case MSG_FLAG_REPLIED:
          whichMnemonic = op == nsMsgSearchOp::Is ? m_kImapAnswered : m_kImapNotAnswered;
          break;
        case MSG_FLAG_NEW:                         
          whichMnemonic = op == nsMsgSearchOp::Is ? m_kImapNew : m_kImapNotNew;
          break; 
        case MSG_FLAG_MARKED:
          whichMnemonic = op == nsMsgSearchOp::Is ? m_kImapFlagged : m_kImapNotFlagged;
          break;
        default:
          NS_ASSERTION(PR_FALSE, "invalid search operator");
          return NS_ERROR_INVALID_ARG;
        }
        break;
        default:
          if ( attrib > nsMsgSearchAttrib::OtherHeader && attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes)
          {
            nsXPIDLCString arbitraryHeaderTerm;
            term->GetArbitraryHeader(getter_Copies(arbitraryHeaderTerm));
            if (!arbitraryHeaderTerm.IsEmpty())
            {
              arbitraryHeader.AssignLiteral(" \"");
              arbitraryHeader.Append(arbitraryHeaderTerm);
              arbitraryHeader.AppendLiteral("\" ");
              whichMnemonic = arbitraryHeader.get();
            }
            else
              return NS_ERROR_FAILURE;
          }
          else
          {
            NS_ASSERTION(PR_FALSE, "invalid search operator");
            return NS_ERROR_INVALID_ARG;
          }
        }
        
        char *value = "";
        char dateBuf[100];
        dateBuf[0] = '\0';
        
        PRBool valueWasAllocated = PR_FALSE;
        if (attrib == nsMsgSearchAttrib::Date)
        {
          // note that there used to be code here that encoded an RFC822 date for imap searches.
          // The IMAP RFC 2060 is misleading to the point that it looks like it requires an RFC822
          // date but really it expects dd-mmm-yyyy, like dredd, and refers to the RFC822 date only in that the
          // dd-mmm-yyyy date will match the RFC822 date within the message.
          
          PRTime adjustedDate;
          searchValue->GetDate(&adjustedDate);
          if (whichMnemonic == m_kImapSince)
          {
            // it looks like the IMAP server searches on Since includes the date in question...
            // our UI presents Is, IsGreater and IsLessThan. For the IsGreater case (m_kImapSince)
            // we need to adjust the date so we get greater than and not greater than or equal to which
            // is what the IMAP server wants to search on
            // won't work on Mac.
            // ack, is this right? is PRTime seconds or microseconds?
            PRInt64 microSecondsPerSecond, secondsInDay, microSecondsInDay;
            
            LL_I2L(microSecondsPerSecond, PR_USEC_PER_SEC);
            LL_UI2L(secondsInDay, 60 * 60 * 24);
            LL_MUL(microSecondsInDay, secondsInDay, microSecondsPerSecond);
            LL_ADD(adjustedDate, adjustedDate, microSecondsInDay); // bump up to the day after this one...
          }
          
          PRExplodedTime exploded;
          PR_ExplodeTime(adjustedDate, PR_LocalTimeParameters, &exploded);
          PR_FormatTimeUSEnglish(dateBuf, sizeof(dateBuf), "%d-%b-%Y", &exploded);
          //         strftime (dateBuf, sizeof(dateBuf), "%d-%b-%Y", localtime (/* &term->m_value.u.date */ &adjustedDate));
          value = dateBuf;
        }
        else
        {
          if (attrib == nsMsgSearchAttrib::AgeInDays)
          {
            // okay, take the current date, subtract off the age in days, then do an appropriate Date search on 
            // the resulting day.
            PRUint32 ageInDays;
            
            searchValue->GetAge(&ageInDays);
            
            PRTime now = PR_Now();
            PRTime matchDay;
            
            PRInt64 microSecondsPerSecond, secondsInDays, microSecondsInDay;
            
            LL_I2L(microSecondsPerSecond, PR_USEC_PER_SEC);
            LL_UI2L(secondsInDays, 60 * 60 * 24 * ageInDays);
            LL_MUL(microSecondsInDay, secondsInDays, microSecondsPerSecond);
            
            LL_SUB(matchDay, now, microSecondsInDay); // = now - term->m_value.u.age * 60 * 60 * 24; 
            PRExplodedTime exploded;
            PR_ExplodeTime(matchDay, PR_LocalTimeParameters, &exploded);
            PR_FormatTimeUSEnglish(dateBuf, sizeof(dateBuf), "%d-%b-%Y", &exploded);
            //                     strftime (dateBuf, sizeof(dateBuf), "%d-%b-%Y", localtime (&matchDay));
            value = dateBuf;
          }
          else if (attrib == nsMsgSearchAttrib::Size)
          {
            PRUint32 sizeValue;
            nsCAutoString searchTermValue;
            searchValue->GetSize(&sizeValue);

            // Multiply by 1024 to get into kb resolution
            sizeValue *= 1024;

            // Ensure that greater than is really greater than
            // in kb resolution.
            if (op == nsMsgSearchOp::IsGreaterThan)
              sizeValue += 1024;

            searchTermValue.AppendInt(sizeValue);

            value = nsCRT::strdup(searchTermValue.get());
            valueWasAllocated = PR_TRUE;
          }
          else
            
            if (IsStringAttribute(attrib))
            {
              PRUnichar *convertedValue; // = reallyDredd ? MSG_EscapeSearchUrl (term->m_value.u.string) : msg_EscapeImapSearchProtocol(term->m_value.u.string);
              nsXPIDLString searchTermValue;
              searchValue->GetStr(getter_Copies(searchTermValue));
              // Ugly switch for Korean mail/news charsets.
              // We want to do this here because here is where
              // we know what charset we want to use.
#ifdef DOING_CHARSET
              if (reallyDredd)
                dest_csid = INTL_DefaultNewsCharSetID(dest_csid);
              else
                dest_csid = INTL_DefaultMailCharSetID(dest_csid);
#endif
              
              // do all sorts of crazy escaping
              convertedValue = reallyDredd ? EscapeSearchUrl (searchTermValue) :
              EscapeImapSearchProtocol(searchTermValue);
              useQuotes = ((!reallyDredd || 
                          (nsDependentString(convertedValue).FindChar(PRUnichar(' ')) != -1)) &&
                 (attrib != nsMsgSearchAttrib::Keywords));
              // now convert to char* and escape quoted_specials
              nsCAutoString valueStr;
              nsresult rv = ConvertFromUnicode(NS_LossyConvertUTF16toASCII(destCharset).get(),
                nsDependentString(convertedValue), valueStr);
              if (NS_SUCCEEDED(rv))
              {
                const char *vptr = valueStr.get();
                // max escaped length is one extra character for every character in the cmd.
                nsAutoArrayPtr<char> newValue(new char[2*strlen(vptr) + 1]);
                if (newValue)
                {
                  char *p = newValue;
                  while (1)
                  {
                    char ch = *vptr++;
                    if (!ch)
                      break;
                    if ((useQuotes ? ch == '"' : 0) || ch == '\\')
                      *p++ = '\\';
                    *p++ = ch;
                  }
                  *p = '\0';
                  value = nsCRT::strdup(newValue); // realloc down to smaller size
                }
              }
              else
                value = nsCRT::strdup("");
              nsCRT::free(convertedValue);
              valueWasAllocated = PR_TRUE;
              
            }
        }
        
        // this should be rewritten to use nsCString
        int len = strlen(whichMnemonic) + strlen(value) + (useNot ? strlen(m_kImapNot) : 0) + 
          (useQuotes ? 2 : 0) + strlen(m_kImapHeader) + 
          (orHeaderMnemonic ? (strlen(m_kImapHeader) + strlen(m_kImapOr) + (useNot ? strlen(m_kImapNot) : 0) + 
          strlen(orHeaderMnemonic) + strlen(value) + 2 /*""*/) : 0) + 10; // add slough for imap string literals
        char *encoding = new char[len];
        if (encoding)
        {
          encoding[0] = '\0';
          // Remember: if ToOrCC and useNot then the expression becomes NOT To AND Not CC as opposed to (NOT TO) || (NOT CC)
          if (orHeaderMnemonic && !useNot)
            PL_strcat(encoding, m_kImapOr);
          if (useNot)
            PL_strcat (encoding, m_kImapNot);
          if (!arbitraryHeader.IsEmpty())
            PL_strcat (encoding, m_kImapHeader);
          PL_strcat (encoding, whichMnemonic);
          if (!ignoreValue)
            err = EncodeImapValue(encoding, value, useQuotes, reallyDredd);
          
          if (orHeaderMnemonic)
          {
            if (useNot)
              PL_strcat(encoding, m_kImapNot);
            
            PL_strcat (encoding, m_kImapHeader);
            
            PL_strcat (encoding, orHeaderMnemonic);
            if (!ignoreValue)
              err = EncodeImapValue(encoding, value, useQuotes, reallyDredd);
          }
          
          // kmcentee, don't let the encoding end with whitespace, 
          // this throws off later url STRCMP
          if (*encoding && *(encoding + strlen(encoding) - 1) == ' ')
            *(encoding + strlen(encoding) - 1) = '\0';
        }
        
        if (value && valueWasAllocated)
          PR_Free (value);
        
        *ppOutTerm = encoding;
        
        return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsMsgSearchAdapter::EncodeImapValue ( char *  encoding,
const char *  value,
PRBool  useQuotes,
PRBool  reallyDredd 
) [static, inherited]

Definition at line 735 of file nsMsgSearchAdapter.cpp.

{
  // By NNTP RFC, SEARCH HEADER SUBJECT "" is legal and means 'find messages without a subject header'
  if (!reallyDredd)
  {
    // By IMAP RFC, SEARCH HEADER SUBJECT "" is illegal and will generate an error from the server
    if (!value || !value[0])
      return NS_ERROR_NULL_POINTER;
  }
  
  if (!nsCRT::IsAscii(value))
  {
    nsCAutoString lengthStr;
    PL_strcat(encoding, "{");
    lengthStr.AppendInt((PRInt32) strlen(value));
    PL_strcat(encoding, lengthStr.get());
    PL_strcat(encoding, "}"CRLF);
    PL_strcat(encoding, value);
    return NS_OK;
  }
  if (useQuotes)
    PL_strcat(encoding, "\"");
  PL_strcat (encoding, value);
  if (useQuotes)
    PL_strcat(encoding, "\"");
  
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char * nsMsgSearchNews::EncodeTerm ( nsIMsgSearchTerm term) [virtual, inherited]

Definition at line 124 of file nsMsgSearchNews.cpp.

{
       // Develop an XPAT-style encoding for the search term

       NS_ASSERTION(term, "null term");
       if (!term)
              return nsnull;

       // Find a string to represent the attribute
       const char *attribEncoding = nsnull;
  nsMsgSearchAttribValue attrib;

  term->GetAttrib(&attrib);

       switch (attrib)
       {
       case nsMsgSearchAttrib::Sender:
              attribEncoding = m_kNntpFrom;
              break;
       case nsMsgSearchAttrib::Subject:
              attribEncoding = m_kNntpSubject;
              break;
       default:
              NS_ASSERTION(PR_FALSE,"malformed search"); // malformed search term?
              return nsnull;
       }

       // Build a string to represent the string pattern
       PRBool leadingStar = PR_FALSE;
       PRBool trailingStar = PR_FALSE;
       int overhead = 1; // null terminator
  nsMsgSearchOpValue op;
  term->GetOp(&op);

       switch (op)
       {
       case nsMsgSearchOp::Contains:
              leadingStar = PR_TRUE;
              trailingStar = PR_TRUE;
              overhead += 2;
              break;
       case nsMsgSearchOp::Is:
              break;
       case nsMsgSearchOp::BeginsWith:
              trailingStar = PR_TRUE;
              overhead++;
              break;
       case nsMsgSearchOp::EndsWith:
              leadingStar = PR_TRUE;
              overhead++;
              break;
       default:
              NS_ASSERTION(PR_FALSE,"malformed search"); // malformed search term?
              return nsnull;
       }
       
    // ### i18N problem Get the csid from FE, which is the correct csid for term
//     int16 wincsid = INTL_GetCharSetID(INTL_DefaultTextWidgetCsidSel);

       // Do INTL_FormatNNTPXPATInRFC1522Format trick for non-ASCII string
//     unsigned char *intlNonRFC1522Value = INTL_FormatNNTPXPATInNonRFC1522Format (wincsid, (unsigned char*)term->m_value.u.string);
  nsCOMPtr <nsIMsgSearchValue> searchValue;

  nsresult rv = term->GetValue(getter_AddRefs(searchValue));
  if (NS_FAILED(rv) || !searchValue)
    return nsnull;


  nsXPIDLString intlNonRFC1522Value;
  rv = searchValue->GetStr(getter_Copies(intlNonRFC1522Value));
       if (NS_FAILED(rv) || !intlNonRFC1522Value)
              return nsnull;
              
       PRUnichar *caseInsensitiveValue = EncodeToWildmat (intlNonRFC1522Value);
       if (!caseInsensitiveValue)
              return nsnull;

       // TO DO: Do INTL_FormatNNTPXPATInRFC1522Format trick for non-ASCII string
       // Unfortunately, we currently do not handle xxx or xxx search in XPAT
       // Need to add the INTL_FormatNNTPXPATInRFC1522Format call after we can do that
       // so we should search a string in either RFC1522 format and non-RFC1522 format
              
       PRUnichar *escapedValue = EscapeSearchUrl (caseInsensitiveValue);
       nsMemory::Free(caseInsensitiveValue);
       if (!escapedValue)
              return nsnull;

#if 0
       // We also need to apply NET_Escape to it since we have to pass 8-bits data
       // And sometimes % in the 7-bit doulbe byte JIS
       // 
       PRUnichar * urlEncoded = nsEscape(escapedValue, url_Path);
       nsCRT::free(escapedValue);

       if (! urlEncoded)
              return nsnull;

       char *pattern = new char [nsCRT::strlen(urlEncoded) + overhead];
       if (!pattern)
              return nsnull;
       else 
              pattern[0] = '\0';
#else
    nsCAutoString pattern;
#endif

    
       if (leadingStar)
      pattern.Append('*');
    AppendUTF16toUTF8(escapedValue, pattern);
       if (trailingStar)
      pattern.Append('*');

       // Combine the XPAT command syntax with the attribute and the pattern to
       // form the term encoding
       const char xpatTemplate[] = "XPAT %s 1- %s";
       int termLength = (sizeof(xpatTemplate) - 1) + strlen(attribEncoding) + pattern.Length() + 1;
       char *termEncoding = new char [termLength];
       if (termEncoding)
              PR_snprintf (termEncoding, termLength, xpatTemplate, attribEncoding, pattern.get());

       return termEncoding;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 95 of file nsMsgSearchNews.cpp.

{
       // Here we take advantage of XPAT's use of the wildmat format, which allows
       // a case-insensitive match by specifying each case possibility for each character
       // So, "FooBar" is encoded as "[Ff][Oo][Bb][Aa][Rr]"

  PRUnichar *caseInsensitiveValue = (PRUnichar*) nsMemory::Alloc(sizeof(PRUnichar) * ((4 * nsCRT::strlen(value)) + 1));
       if (caseInsensitiveValue)
       {
              PRUnichar *walkValue = caseInsensitiveValue;
              while (*value)
              {
                     if (nsCRT::IsAsciiAlpha(*value))
                     {
                            *walkValue++ = (PRUnichar)'[';
                            *walkValue++ = ToUpperCase((PRUnichar)*value);
                            *walkValue++ = ToLowerCase((PRUnichar)*value);
                            *walkValue++ = (PRUnichar)']';
                     }
                     else
                            *walkValue++ = *value;
                     value++;
              }
              *walkValue = 0;
       }
       return caseInsensitiveValue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRUnichar * nsMsgSearchAdapter::EscapeImapSearchProtocol ( const PRUnichar imapCommand) [static, inherited]

Definition at line 226 of file nsMsgSearchAdapter.cpp.

{
       return nsCRT::strdup(imapCommand);
#if 0
       PRUnichar *result = nsnull;
       // max escaped length is one extra character for every character in the cmd.
    PRUnichar *scratchBuf =
        (PRUnichar*) PR_Malloc (sizeof(PRUnichar) * (2*nsCRT::strlen(imapCommand) + 1));
       if (scratchBuf)
       {
              PRUnichar *scratchPtr = scratchBuf;
              while (1)
              {
                     PRUnichar ch = *imapCommand++;
                     if (!ch)
                            break;
                     if (ch == (PRUnichar)'\\')
                     {
                            *scratchPtr++ = (PRUnichar)'\\';
                            *scratchPtr++ = (PRUnichar)'\\';
                     }
                     else
                            *scratchPtr++ = ch;
              }
              *scratchPtr = 0;
        result = nsCRT::strdup (scratchBuf); // realloc down to smaller size
        nsCRT::free (scratchBuf);
       }
       return result;
#endif
}

Here is the caller graph for this function:

Definition at line 265 of file nsMsgSearchAdapter.cpp.

{
       return nsCRT::strdup(imapCommand);
#if 0
       PRUnichar *result = nsnull;
       // max escaped length is one extra character for every character in the cmd.
    PRUnichar *scratchBuf =
        (PRUnichar*) PR_Malloc (sizeof(PRUnichar) * (2*nsCRT::strlen(imapCommand) + 1));
       if (scratchBuf)
       {
              PRUnichar *scratchPtr = scratchBuf;
              while (1)
              {
                     PRUnichar ch = *imapCommand++;
                     if (!ch)
                            break;
                     if (ch == '"')
                     {
                            *scratchPtr++ = '\\';
                            *scratchPtr++ = '"';
                     }
                     else
                            *scratchPtr++ = ch;
              }
              *scratchPtr = '\0';
    result = nsCRT::strdup (scratchBuf); // realloc down to smaller size
    nsCRT::free (scratchBuf);
       }
       return result;
#endif
}
PRUnichar * nsMsgSearchAdapter::EscapeSearchUrl ( const PRUnichar nntpCommand) [static, inherited]

Definition at line 185 of file nsMsgSearchAdapter.cpp.

{
       return nsCRT::strdup(nntpCommand);
#if 0
       PRUnichar *result = nsnull;
       // max escaped length is two extra characters for every character in the cmd.
  PRUnichar *scratchBuf = (PRUnichar*) PR_Malloc(sizeof(PRUnichar) * (3*nsCRT::strlen(nntpCommand) + 1));
       if (scratchBuf)
       {
              PRUnichar *scratchPtr = scratchBuf;
              while (PR_TRUE)
              {
                     PRUnichar ch = *nntpCommand++;
                     if (!ch)
                            break;
                     if (ch == '#' || ch == '?' || ch == '@' || ch == '\\')
                     {
                            *scratchPtr++ = '\\';
                nsTextFormatter::snprintf(scratchPtr, 2,
                                          NS_LITERAL_STRING("%2.2X").get(), ch);
                                   /* Reviewed 4.51 safe use of sprintf */
                            scratchPtr += 2;
                     }
                     else
                            *scratchPtr++ = ch;
              }
              *scratchPtr = '\0';
              result = nsCRT::strdup (scratchBuf); // realloc down to smaller size
        nsCRT::free (scratchBuf);
       }
       return result;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Here is the caller graph for this function:

nsresult nsMsgSearchNews::GetEncoding ( char **  result) [inherited]

Definition at line 248 of file nsMsgSearchNews.cpp.

Here is the call graph for this function:

char * nsMsgSearchAdapter::GetImapCharsetParam ( const PRUnichar destCharset) [static, inherited]

Definition at line 168 of file nsMsgSearchAdapter.cpp.

{
       char *result = nsnull;

       // Specify a character set unless we happen to be US-ASCII.
  if (nsCRT::strcmp(destCharset, NS_LITERAL_STRING("us-ascii").get()))
           result = PR_smprintf("%s%s", nsMsgSearchAdapter::m_kImapCharset, NS_ConvertUCS2toUTF8(destCharset).get());

       return result;
}

Here is the caller graph for this function:

void nsIMsgSearchAdapter::getSearchCharsets ( out wstring  srcCharset,
out wstring  destCharset 
) [inherited]

Here is the caller graph for this function:

void nsMsgSearchNews::ReportHit ( nsIMsgDBHdr pHeaders,
nsIMsgFolder folder 
) [inherited]

Definition at line 440 of file nsMsgSearchNews.cpp.

{
    // this is totally filched from msg_SearchOfflineMail until I decide whether the 
    // right thing is to get them from the db or from NNTP

    nsresult err = NS_OK;
    nsCOMPtr<nsIMsgSearchSession> session;
    nsCOMPtr <nsIMsgFolder> scopeFolder;
    err = m_scope->GetFolder(getter_AddRefs(scopeFolder));
    m_scope->GetSearchSession(getter_AddRefs(session));
    if (session)
      session->AddSearchHit (pHeaders, scopeFolder);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 414 of file nsMsgSearchNews.cpp.

{
  nsCOMPtr <nsIMsgDatabase> db;
  nsCOMPtr <nsIDBFolderInfo>  folderInfo;
  nsCOMPtr <nsIMsgFolder> scopeFolder;

  nsresult err = m_scope->GetFolder(getter_AddRefs(scopeFolder));
  if (NS_SUCCEEDED(err) && scopeFolder)
  {
    err = scopeFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(db));
  }

  if (db)
  {
         for (PRUint32 i = 0; i < m_hits.GetSize(); i++)
         {
      nsCOMPtr <nsIMsgDBHdr> header;

                db->GetMsgHdrForKey(m_hits.ElementAt(i), getter_AddRefs(header));
                if (header)
                       ReportHit(header, scopeFolder);
         }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Reimplemented from nsMsgSearchNews.

Definition at line 493 of file nsMsgSearchNews.cpp.

{
       // State machine runs in mknews.c?
       return NS_ERROR_NOT_IMPLEMENTED;
}
char * nsMsgSearchAdapter::TransformSpacesToStars ( const char *  spaceString,
msg_TransformType  transformType 
) [protected, inherited]

Definition at line 814 of file nsMsgSearchAdapter.cpp.

{
       char *starString;
       
       if (transformType == kOverwrite)
       {
              if ((starString = nsCRT::strdup(spaceString)) != nsnull)
              {
                     char *star = starString;
                     while ((star = PL_strchr(star, ' ')) != nsnull)
                            *star = '*';
              }
       }
       else
       {
              int i, count;

              for (i = 0, count = 0; spaceString[i]; )
              {
                     if (spaceString[i++] == ' ')
                     {
                            count++;
                            while (spaceString[i] && spaceString[i] == ' ') i++;
                     }
              }

              if (transformType == kSurround)
                     count *= 2;

              if (count > 0)
              {
                     if ((starString = (char *)PR_Malloc(i + count + 1)) != nsnull)
                     {
                            int j;

                            for (i = 0, j = 0; spaceString[i]; )
                            {
                                   if (spaceString[i] == ' ')
                                   {
                                          starString[j++] = '*';
                                          starString[j++] = ' ';
                                          if (transformType == kSurround)
                                                 starString[j++] = '*';

                                          i++;
                                          while (spaceString[i] && spaceString[i] == ' ')
                                                 i++;
                                   }
                                   else
                                          starString[j++] = spaceString[i++];
                            }
                            starString[j] = 0;
                     }
              }
              else
                     starString = nsCRT::strdup(spaceString);
       }

       return starString;
}

Here is the call graph for this function:

char * nsMsgSearchAdapter::UnEscapeSearchUrl ( const char *  commandSpecificData) [static, inherited]

Definition at line 298 of file nsMsgSearchAdapter.cpp.

{
  char *result = (char*) PR_Malloc (strlen(commandSpecificData) + 1);
       if (result)
       {
              char *resultPtr = result;
              while (1)
              {
                     char ch = *commandSpecificData++;
                     if (!ch)
                            break;
                     if (ch == '\\')
                     {
                            char scratchBuf[3];
                            scratchBuf[0] = (char) *commandSpecificData++;
                            scratchBuf[1] = (char) *commandSpecificData++;
                            scratchBuf[2] = '\0';
                            unsigned int accum = 0;
                            sscanf (scratchBuf, "%X", &accum);
                            *resultPtr++ = (char) accum;
                     }
                     else
                            *resultPtr++ = ch;
              }
              *resultPtr = '\0';
       }
       return result;
}

Here is the call graph for this function:

Reimplemented from nsMsgSearchNews.

Definition at line 484 of file nsMsgSearchNews.cpp.

{
       nsresult err = nsMsgSearchAdapter::ValidateTerms ();
       if (NS_OK == err)
              err = Encode (&m_encoding);
  // this used to create a url struct for some reason.
       return err;
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 63 of file nsIMsgSearchAdapter.idl.

Definition at line 81 of file nsMsgSearchAdapter.h.

nsMsgKeyArray nsMsgSearchNews::m_candidateHits [protected, inherited]

Definition at line 71 of file nsMsgSearchNews.h.

Definition at line 82 of file nsMsgSearchAdapter.h.

nsCString nsMsgSearchNews::m_encoding [protected, inherited]

Definition at line 68 of file nsMsgSearchNews.h.

Definition at line 83 of file nsMsgSearchAdapter.h.

nsMsgKeyArray nsMsgSearchNews::m_hits [protected, inherited]

Definition at line 72 of file nsMsgSearchNews.h.

const char * nsMsgSearchAdapter::m_kImapAnswered = " ANSWERED " [static, inherited]

Definition at line 115 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapAnyText = " TEXT " [static, inherited]

Definition at line 110 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapBefore = " SENTBEFORE " [static, inherited]

Definition at line 100 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapBody = " BODY " [static, inherited]

Definition at line 101 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapCC = " CC " [static, inherited]

Definition at line 102 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapCharset = " CHARSET " [static, inherited]

Definition at line 118 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapFlagged = " FLAGGED " [static, inherited]

Definition at line 124 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapFrom = " FROM " [static, inherited]

Definition at line 103 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapHeader = " HEADER" [static, inherited]

Definition at line 109 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapKeyword = " KEYWORD " [static, inherited]

Definition at line 111 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapNew = " NEW " [static, inherited]

Definition at line 122 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapNot = " NOT" [static, inherited]

Definition at line 104 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapNotAnswered = " UNANSWERED " [static, inherited]

Definition at line 117 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapNotFlagged = " UNFLAGGED " [static, inherited]

Definition at line 125 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapNotNew = " OLD SEEN " [static, inherited]

Definition at line 123 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapNotSeen = " UNSEEN " [static, inherited]

Definition at line 116 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapOr = " OR" [static, inherited]

Definition at line 105 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapSeen = " SEEN " [static, inherited]

Definition at line 114 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapSentOn = " SENTON " [static, inherited]

Definition at line 113 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapSince = " SENTSINCE " [static, inherited]

Definition at line 106 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapSizeLarger = " LARGER " [static, inherited]

Definition at line 121 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapSizeSmaller = " SMALLER " [static, inherited]

Definition at line 120 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapSubject = " SUBJECT " [static, inherited]

Definition at line 107 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapTo = " TO " [static, inherited]

Definition at line 108 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchAdapter::m_kImapUnDeleted = " UNDELETED" [static, inherited]

Definition at line 119 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchNews::m_kNntpFrom = "FROM " [static, protected, inherited]

Definition at line 74 of file nsMsgSearchNews.h.

const char * nsMsgSearchAdapter::m_kNntpKeywords = " KEYWORDS " [static, inherited]

Definition at line 112 of file nsMsgSearchAdapter.h.

const char * nsMsgSearchNews::m_kNntpSubject = "SUBJECT " [static, protected, inherited]

Definition at line 75 of file nsMsgSearchNews.h.

const char * nsMsgSearchNewsEx::m_kProfileTemplate = "%s/dummy?profile/PROFILE NEW %s HEADER NEWSGROUPS %s %s" [static, protected]

Definition at line 96 of file nsMsgSearchNews.h.

const char * nsMsgSearchNewsEx::m_kSearchTemplate = "?search/SEARCH HEADER NEWSGROUPS %s %s" [static, protected]

Definition at line 95 of file nsMsgSearchNews.h.

const char * nsMsgSearchNews::m_kTermSeparator = "/" [static, protected, inherited]

Definition at line 76 of file nsMsgSearchNews.h.

const char* nsMsgSearchNews::m_kUrlPrefix [static, protected, inherited]

Definition at line 77 of file nsMsgSearchNews.h.

PRBool nsMsgSearchNews::m_ORSearch [protected, inherited]

Definition at line 69 of file nsMsgSearchNews.h.

NS_DECL_ISUPPORTS NS_DECL_NSIMSGSEARCHADAPTER nsIMsgSearchScopeTerm* nsMsgSearchAdapter::m_scope [inherited]

Definition at line 78 of file nsMsgSearchAdapter.h.

Definition at line 79 of file nsMsgSearchAdapter.h.


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