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
nsMsgSearchNews Class Reference

#include <nsMsgSearchNews.h>

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

List of all members.

Public Member Functions

 nsMsgSearchNews (nsMsgSearchScopeTerm *scope, nsISupportsArray *termList)
virtual ~nsMsgSearchNews ()
NS_IMETHOD ValidateTerms ()
NS_IMETHOD Search (PRBool *aDone)
NS_IMETHOD GetEncoding (char **result)
NS_IMETHOD AddHit (nsMsgKey key)
NS_IMETHOD CurrentUrlDone (PRInt32 exitCode)
virtual nsresult Encode (nsCString *outEncoding)
virtual char * EncodeTerm (nsIMsgSearchTerm *)
PRUnicharEncodeToWildmat (const PRUnichar *)
void ReportHits ()
PRBool DuplicateHit (PRUint32 artNum)
void CollateHits ()
void ReportHit (nsIMsgDBHdr *pHeaders, nsIMsgFolder *folder)
void Search (out boolean done)
void SendUrl ()
void CurrentUrlDone (in long exitCode)
void AddHit (in nsMsgKey key)
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_kNntpFrom = "FROM "
static const char * m_kNntpSubject = "SUBJECT "
static const char * m_kTermSeparator = "/"
static const char * m_kUrlPrefix

Detailed Description

Definition at line 45 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 66 of file nsMsgSearchNews.cpp.

                                                                                         : nsMsgSearchAdapter (scope, termList)
{
}

Definition at line 71 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:

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 nsMsgSearchNews::Encode ( nsCString outEncoding) [virtual]

Reimplemented in nsMsgSearchNewsEx.

Definition at line 255 of file nsMsgSearchNews.cpp.

{
       NS_ASSERTION(outEncoding, "no out encoding");
       if (!outEncoding)
              return NS_ERROR_NULL_POINTER;

       nsresult err = NS_OK;

  PRUint32 numTerms;

  m_searchTerms->Count(&numTerms);
       char **intermediateEncodings = new char * [numTerms];
       if (intermediateEncodings)
       {
              // Build an XPAT command for each term
              int encodingLength = 0;
              PRUint32 i;
              for (i = 0; i < numTerms; i++)
              {
      nsCOMPtr<nsIMsgSearchTerm> pTerm;
      m_searchTerms->QueryElementAt(i, NS_GET_IID(nsIMsgSearchTerm),
                               (void **)getter_AddRefs(pTerm));
                     // set boolean OR term if any of the search terms are an OR...this only works if we are using
                     // homogeneous boolean operators.
      PRBool isBooleanOpAnd;
      pTerm->GetBooleanAnd(&isBooleanOpAnd);
                     m_ORSearch = !isBooleanOpAnd;
              
                     intermediateEncodings[i] = EncodeTerm (pTerm);   
                     if (intermediateEncodings[i])
                            encodingLength += strlen(intermediateEncodings[i]) + strlen(m_kTermSeparator);
              }
              encodingLength += strlen("?search");
              // Combine all the term encodings into one big encoding
              char *encoding = new char [encodingLength + 1];
              if (encoding)
              {
                     PL_strcpy (encoding, "?search");

      m_searchTerms->Count(&numTerms);

                     for (i = 0; i < numTerms; i++)
                     {
                            if (intermediateEncodings[i])
                            {
                                   PL_strcat (encoding, m_kTermSeparator);
                                   PL_strcat (encoding, intermediateEncodings[i]);
                                   delete [] intermediateEncodings[i];
                            }
                     }
                     *outEncoding = encoding;
              }
              else
                     err = NS_ERROR_OUT_OF_MEMORY;
       }
       else
              err = NS_ERROR_OUT_OF_MEMORY;
       delete [] intermediateEncodings;

       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]

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:

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 
)

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 in nsMsgSearchNewsEx.

Definition at line 88 of file nsMsgSearchNews.cpp.

{
       // the state machine runs in the news: handler
       nsresult err = NS_ERROR_NOT_IMPLEMENTED;
       return err;
}
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:

Implements nsIMsgSearchAdapter.

Reimplemented in nsMsgSearchNewsEx.

Definition at line 76 of file nsMsgSearchNews.cpp.

{
       nsresult err = nsMsgSearchAdapter::ValidateTerms ();
       if (NS_OK == err)
       {
              err = Encode (&m_encoding);
       }

       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]

Definition at line 71 of file nsMsgSearchNews.h.

Definition at line 82 of file nsMsgSearchAdapter.h.

Definition at line 68 of file nsMsgSearchNews.h.

Definition at line 83 of file nsMsgSearchAdapter.h.

nsMsgKeyArray nsMsgSearchNews::m_hits [protected]

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]

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]

Definition at line 75 of file nsMsgSearchNews.h.

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

Definition at line 76 of file nsMsgSearchNews.h.

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

Definition at line 77 of file nsMsgSearchNews.h.

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: