Beispiel #1
0
nsresult nsMsgOfflineImapOperation::AddKeyword(const char *aKeyword, nsCString &addList, const char *addProp,
                                               nsCString &removeList, const char *removeProp)
{
  PRInt32 startOffset, keywordLength;
  if (!MsgFindKeyword(nsDependentCString(aKeyword), addList, &startOffset, &keywordLength))
  {
    if (!addList.IsEmpty())
      addList.Append(' ');
    addList.Append(aKeyword);
  }
  // if the keyword we're removing was in the list of keywords to add,
  // cut it from that list.
  if (MsgFindKeyword(nsDependentCString(aKeyword), removeList, &startOffset, &keywordLength))
  {
    removeList.Cut(startOffset, keywordLength);
    m_mdb->SetProperty(m_mdbRow, removeProp, removeList.get());
  }
  return m_mdb->SetProperty(m_mdbRow, addProp, addList.get());
}
void nsMsgLocalStoreUtils::ChangeKeywordsHelper(
    nsIMsgDBHdr *message, uint64_t desiredOffset,
    nsLineBuffer<char> *lineBuffer, nsTArray<nsCString> &keywordArray,
    bool aAdd, nsIOutputStream *outputStream, nsISeekableStream *seekableStream,
    nsIInputStream *inputStream) {
  uint32_t bytesWritten;

  for (uint32_t i = 0; i < keywordArray.Length(); i++) {
    nsAutoCString header;
    nsAutoCString keywords;
    bool done = false;
    uint32_t len = 0;
    nsAutoCString keywordToWrite(" ");

    keywordToWrite.Append(keywordArray[i]);
    seekableStream->Seek(nsISeekableStream::NS_SEEK_SET, desiredOffset);
    // need to reset lineBuffer, which is cheaper than creating a new one.
    lineBuffer->start = lineBuffer->end = lineBuffer->buf;
    bool inKeywordHeader = false;
    bool foundKeyword = false;
    int64_t offsetToAddKeyword = 0;
    bool more;
    message->GetMessageSize(&len);
    // loop through
    while (!done) {
      int64_t lineStartPos;
      seekableStream->Tell(&lineStartPos);
      // we need to adjust the linestart pos by how much extra the line
      // buffer has read from the stream.
      lineStartPos -= (lineBuffer->end - lineBuffer->start);
      // NS_ReadLine doesn't return line termination chars.
      nsCString keywordHeaders;
      nsresult rv = NS_ReadLine(inputStream, lineBuffer, keywordHeaders, &more);
      if (NS_SUCCEEDED(rv)) {
        if (keywordHeaders.IsEmpty())
          break;  // passed headers; no x-mozilla-keywords header; give up.
        if (StringBeginsWith(keywordHeaders,
                             NS_LITERAL_CSTRING(HEADER_X_MOZILLA_KEYWORDS)))
          inKeywordHeader = true;
        else if (inKeywordHeader && (keywordHeaders.CharAt(0) == ' ' ||
                                     keywordHeaders.CharAt(0) == '\t'))
          ;  // continuation header line
        else if (inKeywordHeader)
          break;
        else
          continue;
        uint32_t keywordHdrLength = keywordHeaders.Length();
        int32_t startOffset, keywordLength;
        // check if we have the keyword
        if (MsgFindKeyword(keywordArray[i], keywordHeaders, &startOffset,
                           &keywordLength)) {
          foundKeyword = true;
          if (!aAdd)  // if we're removing, remove it, and break;
          {
            keywordHeaders.Cut(startOffset, keywordLength);
            for (int32_t j = keywordLength; j > 0; j--)
              keywordHeaders.Append(' ');
            seekableStream->Seek(nsISeekableStream::NS_SEEK_SET, lineStartPos);
            outputStream->Write(keywordHeaders.get(), keywordHeaders.Length(),
                                &bytesWritten);
          }
          offsetToAddKeyword = 0;
          // if adding and we already have the keyword, done
          done = true;
          break;
        }
        // argh, we need to check all the lines to see if we already have the
        // keyword, but if we don't find it, we want to remember the line and
        // position where we have room to add the keyword.
        if (aAdd) {
          nsAutoCString curKeywordHdr(keywordHeaders);
          // strip off line ending spaces.
          curKeywordHdr.Trim(" ", false, true);
          if (!offsetToAddKeyword &&
              curKeywordHdr.Length() + keywordToWrite.Length() <
                  keywordHdrLength)
            offsetToAddKeyword = lineStartPos + curKeywordHdr.Length();
        }
      }
    }
    if (aAdd && !foundKeyword) {
      if (!offsetToAddKeyword)
        message->SetUint32Property("growKeywords", 1);
      else {
        seekableStream->Seek(nsISeekableStream::NS_SEEK_SET,
                             offsetToAddKeyword);
        outputStream->Write(keywordToWrite.get(), keywordToWrite.Length(),
                            &bytesWritten);
      }
    }
  }
}