コード例 #1
0
ファイル: Key.cpp プロジェクト: Gozala/gecko-dev
void
Key::EncodeString(const nsAString& aString, uint8_t aTypeOffset)
{
  // First measure how long the encoded string will be.

  // The +2 is for initial 3 and trailing 0. We'll compensate for multi-byte
  // chars below.
  uint32_t size = aString.Length() + 2;
  
  const char16_t* start = aString.BeginReading();
  const char16_t* end = aString.EndReading();
  for (const char16_t* iter = start; iter < end; ++iter) {
    if (*iter > ONE_BYTE_LIMIT) {
      size += *iter > TWO_BYTE_LIMIT ? 2 : 1;
    }
  }

  // Allocate memory for the new size
  uint32_t oldLen = mBuffer.Length();
  char* buffer;
  if (!mBuffer.GetMutableData(&buffer, oldLen + size)) {
    return;
  }
  buffer += oldLen;

  // Write type marker
  *(buffer++) = eString + aTypeOffset;

  // Encode string
  for (const char16_t* iter = start; iter < end; ++iter) {
    if (*iter <= ONE_BYTE_LIMIT) {
      *(buffer++) = *iter + ONE_BYTE_ADJUST;
    }
    else if (*iter <= TWO_BYTE_LIMIT) {
      char16_t c = char16_t(*iter) + TWO_BYTE_ADJUST + 0x8000;
      *(buffer++) = (char)(c >> 8);
      *(buffer++) = (char)(c & 0xFF);
    }
    else {
コード例 #2
0
bool
IsASCII( const nsAString& aString )
  {
    static const char16_t NOT_ASCII = char16_t(~0x007F);


    // Don't want to use |copy_string| for this task, since we can stop at the first non-ASCII character

    nsAString::const_iterator iter, done_reading;
    aString.BeginReading(iter);
    aString.EndReading(done_reading);

    const char16_t* c = iter.get();
    const char16_t* end = done_reading.get();
    
    while ( c < end )
      {
        if ( *c++ & NOT_ASCII )
          return false;
      }

    return true;
  }
コード例 #3
0
NS_IMETHODIMP
Location::GetProtocol(nsAString& aProtocol)
{
  aProtocol.SetLength(0);

  nsCOMPtr<nsIURI> uri;
  nsresult result = NS_OK;

  result = GetURI(getter_AddRefs(uri));

  if (uri) {
    nsAutoCString protocol;

    result = uri->GetScheme(protocol);

    if (NS_SUCCEEDED(result)) {
      CopyASCIItoUTF16(protocol, aProtocol);
      aProtocol.Append(char16_t(':'));
    }
  }

  return result;
}
コード例 #4
0
ファイル: nsCSSScanner.cpp プロジェクト: AtulKumar2/gecko-dev
/**
 * Scan a string constant ('foo' or "foo").  Will always produce
 * either a String or a Bad_String token; the latter occurs when the
 * close quote is missing.  Always returns true (for convenience in Next()).
 */
bool
nsCSSScanner::ScanString(nsCSSToken& aToken)
{
  int32_t aStop = Peek();
  MOZ_ASSERT(aStop == '"' || aStop == '\'', "should not have been called");
  aToken.mType = eCSSToken_String;
  aToken.mSymbol = char16_t(aStop); // Remember how it's quoted.
  Advance();

  for (;;) {
    GatherText(IS_STRING, aToken.mIdent);

    int32_t ch = Peek();
    if (ch == -1) {
      AddEOFCharacters(aStop == '"' ? eEOFCharacters_DoubleQuote :
                                      eEOFCharacters_SingleQuote);
      break; // EOF ends a string token with no error.
    }
    if (ch == aStop) {
      Advance();
      break;
    }
    // Both " and ' are excluded from IS_STRING.
    if (ch == '"' || ch == '\'') {
      aToken.mIdent.Append(ch);
      Advance();
      continue;
    }

    mSeenBadToken = true;
    aToken.mType = eCSSToken_Bad_String;
    if (mReporter)
      mReporter->ReportUnexpected("SEUnterminatedString", aToken);
    break;
  }
  return true;
}
コード例 #5
0
ファイル: txExecutionState.cpp プロジェクト: bgrins/gecko-dev
const txXPathNode*
txExecutionState::retrieveDocument(const nsAString& aUri)
{
    NS_ASSERTION(!aUri.Contains(char16_t('#')),
                 "Remove the fragment.");

    if (mDisableLoads) {
        return nullptr;
    }

    MOZ_LOG(txLog::xslt, LogLevel::Debug,
           ("Retrieve Document %s", NS_LossyConvertUTF16toASCII(aUri).get()));

    // try to get already loaded document
    txLoadedDocumentEntry *entry = mLoadedDocuments.PutEntry(aUri);
    if (!entry) {
        return nullptr;
    }

    if (!entry->mDocument && !entry->LoadingFailed()) {
        // open URI
        nsAutoString errMsg;
        // XXX we should get the loader from the actual node
        // triggering the load, but this will do for the time being
        entry->mLoadResult =
            txParseDocumentFromURI(aUri, *mLoadedDocuments.mSourceDocument,
                                   errMsg, getter_Transfers(entry->mDocument));

        if (entry->LoadingFailed()) {
            receiveError(NS_LITERAL_STRING("Couldn't load document '") +
                         aUri + NS_LITERAL_STRING("': ") + errMsg,
                         entry->mLoadResult);
        }
    }

    return entry->mDocument;
}
コード例 #6
0
ファイル: find.pass.cpp プロジェクト: drashti304/TizenRT
int tc_libcxx_strings_char_traits_specializations_char16_t_find(void)
{
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
    char16_t s1[] = {1, 2, 3};
    TC_ASSERT_EXPR(std::char_traits<char16_t>::find(s1, 3, char16_t(1)) == s1);
    TC_ASSERT_EXPR(std::char_traits<char16_t>::find(s1, 3, char16_t(2)) == s1+1);
    TC_ASSERT_EXPR(std::char_traits<char16_t>::find(s1, 3, char16_t(3)) == s1+2);
    TC_ASSERT_EXPR(std::char_traits<char16_t>::find(s1, 3, char16_t(4)) == 0);
    TC_ASSERT_EXPR(std::char_traits<char16_t>::find(s1, 3, char16_t(0)) == 0);
    TC_ASSERT_EXPR(std::char_traits<char16_t>::find(NULL, 0, char16_t(0)) == 0);

#if TEST_STD_VER > 14
    static_assert(test_constexpr(), "" );
#endif
#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
    TC_SUCCESS_RESULT();
    return 0;
}
コード例 #7
0
static void
retrieveNode(txExecutionState* aExecutionState, const nsAString& aUri,
             const nsAString& aBaseUri, txNodeSet* aNodeSet)
{
    nsAutoString absUrl;
    URIUtils::resolveHref(aUri, aBaseUri, absUrl);

    int32_t hash = absUrl.RFindChar(char16_t('#'));
    uint32_t urlEnd, fragStart, fragEnd;
    if (hash == kNotFound) {
        urlEnd = absUrl.Length();
        fragStart = 0;
        fragEnd = 0;
    }
    else {
        urlEnd = hash;
        fragStart = hash + 1;
        fragEnd = absUrl.Length();
    }

    nsDependentSubstring docUrl(absUrl, 0, urlEnd);
    nsDependentSubstring frag(absUrl, fragStart, fragEnd);

    const txXPathNode* loadNode = aExecutionState->retrieveDocument(docUrl);
    if (loadNode) {
        if (frag.IsEmpty()) {
            aNodeSet->add(*loadNode);
        }
        else {
            txXPathTreeWalker walker(*loadNode);
            if (walker.moveToElementById(frag)) {
                aNodeSet->add(walker.getCurrentPosition());
            }
        }
    }
}
コード例 #8
0
// Removes the value aRemoveValue from the string list of white-space separated
// values aValueList
void
ChangeStyleTransaction::RemoveValueFromListOfValues(
                          nsAString& aValues,
                          const nsAString& aRemoveValue)
{
  nsAutoString classStr(aValues);
  nsAutoString outString;
  // put an extra null at the end
  classStr.Append(kNullCh);

  char16_t* start = classStr.BeginWriting();
  char16_t* end = start;

  while (kNullCh != *start) {
    while (kNullCh != *start && nsCRT::IsAsciiSpace(*start)) {
      // skip leading space
      start++;
    }
    end = start;

    while (kNullCh != *end && !nsCRT::IsAsciiSpace(*end)) {
      // look for space or end
      end++;
    }
    // end string here
    *end = kNullCh;

    if (start < end && !aRemoveValue.Equals(start)) {
      outString.Append(start);
      outString.Append(char16_t(' '));
    }

    start = ++end;
  }
  aValues.Assign(outString);
}
コード例 #9
0
ファイル: msgMapiHook.cpp プロジェクト: bolt-dev/comm
nsresult nsMapiHook::HandleAttachments (nsIMsgCompFields * aCompFields, int32_t aFileCount,
                                        lpnsMapiFileDesc aFiles, BOOL aIsUnicode)
{
    nsresult rv = NS_OK ;

    nsAutoCString Attachments ;
    nsAutoCString TempFiles ;

    nsCOMPtr <nsIFile> pFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv) ;
    if (NS_FAILED(rv) || (!pFile) ) return rv ;
    nsCOMPtr <nsIFile> pTempDir = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv) ;
    if (NS_FAILED(rv) || (!pTempDir) ) return rv ;

    for (int i=0 ; i < aFileCount ; i++)
    {
        bool bTempFile = false ;
        if (aFiles[i].lpszPathName)
        {
            // check if attachment exists
            if (aIsUnicode)
                pFile->InitWithPath (nsDependentString(aFiles[i].lpszPathName));
            else
                pFile->InitWithNativePath (nsDependentCString((const char*)aFiles[i].lpszPathName));

            bool bExist ;
            rv = pFile->Exists(&bExist) ;
            MOZ_LOG(MAPI, mozilla::LogLevel::Debug, ("nsMapiHook::HandleAttachments: filename: %s path: %s exists = %s \n", (const char*)aFiles[i].lpszFileName, (const char*)aFiles[i].lpszPathName, bExist ? "true" : "false"));
            if (NS_FAILED(rv) || (!bExist) ) return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST ;

            //Temp Directory
            nsCOMPtr <nsIFile> pTempDir;
            NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(pTempDir));

            // create a new sub directory called moz_mapi underneath the temp directory
            pTempDir->AppendRelativePath(NS_LITERAL_STRING("moz_mapi"));
            pTempDir->Exists (&bExist) ;
            if (!bExist)
            {
                rv = pTempDir->Create(nsIFile::DIRECTORY_TYPE, 777) ;
                if (NS_FAILED(rv)) return rv ;
            }

            // rename or copy the existing temp file with the real file name

            nsAutoString leafName ;
            // convert to Unicode using Platform charset
            // leafName already contains a unicode leafName from lpszPathName. If we were given
            // a value for lpszFileName, use it. Otherwise stick with leafName
            if (aFiles[i].lpszFileName)
            {
              nsAutoString wholeFileName;
                if (aIsUnicode)
                    wholeFileName.Assign(aFiles[i].lpszFileName);
                else
                    ConvertToUnicode(nsMsgI18NFileSystemCharset(), (char *) aFiles[i].lpszFileName, wholeFileName);
                // need to find the last '\' and find the leafname from that.
                int32_t lastSlash = wholeFileName.RFindChar(char16_t('\\'));
                if (lastSlash != kNotFound)
                  leafName.Assign(Substring(wholeFileName, lastSlash + 1));
                else
                  leafName.Assign(wholeFileName);
            }
            else
              pFile->GetLeafName (leafName);

            nsCOMPtr<nsIMsgAttachment> attachment = do_CreateInstance(NS_MSGATTACHMENT_CONTRACTID, &rv);
            NS_ENSURE_SUCCESS(rv, rv);
            attachment->SetName(leafName);

            nsCOMPtr<nsIFile> pTempFile;
            rv = pTempDir->Clone(getter_AddRefs(pTempFile));
            if (NS_FAILED(rv) || !pTempFile)
              return rv;

            pTempFile->Append(leafName);
            pTempFile->Exists(&bExist);
            if (bExist)
            {
              rv = pTempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0777);
              NS_ENSURE_SUCCESS(rv, rv);
              pTempFile->Remove(false); // remove so we can copy over it.
              pTempFile->GetLeafName(leafName);
            }
            // copy the file to its new location and file name
            pFile->CopyTo(pTempDir, leafName);
            // point pFile to the new location of the attachment
            pFile->InitWithFile(pTempDir);
            pFile->Append(leafName);

            // create MsgCompose attachment object
            attachment->SetTemporary(true); // this one is a temp file so set the flag for MsgCompose

            // now set the attachment object
            nsAutoCString pURL ;
            NS_GetURLSpecFromFile(pFile, pURL);
            attachment->SetUrl(pURL);

            // set the file size
            int64_t fileSize;
            pFile->GetFileSize(&fileSize);
            attachment->SetSize(fileSize);

            // add the attachment
            rv = aCompFields->AddAttachment (attachment);
            if (NS_FAILED(rv))
              MOZ_LOG(MAPI, mozilla::LogLevel::Debug, ("nsMapiHook::HandleAttachments: AddAttachment rv =  %lx\n", rv));
        }
    }
    return rv ;
}
コード例 #10
0
nsresult
GetDirectoryListingTaskParent::IOWork()
{
  MOZ_ASSERT(XRE_IsParentProcess(),
             "Only call from parent process!");
  MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!");

  if (mFileSystem->IsShutdown()) {
    return NS_ERROR_FAILURE;
  }

  bool exists;
  nsresult rv = mTargetPath->Exists(&exists);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (!exists) {
    if (!mFileSystem->ShouldCreateDirectory()) {
      return NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
    }

    rv = mTargetPath->Create(nsIFile::DIRECTORY_TYPE, 0777);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
  }

  // Get isDirectory.
  bool isDir;
  rv = mTargetPath->IsDirectory(&isDir);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (!isDir) {
    return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
  }

  nsCOMPtr<nsISimpleEnumerator> entries;
  rv = mTargetPath->GetDirectoryEntries(getter_AddRefs(entries));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  bool filterOutSensitive = false;
  {
    HTMLSplitOnSpacesTokenizer tokenizer(mFilters, ';');
    nsAutoString token;
    while (tokenizer.hasMoreTokens()) {
      token = tokenizer.nextToken();
      if (token.EqualsLiteral("filter-out-sensitive")) {
        filterOutSensitive = true;
      } else {
        MOZ_CRASH("Unrecognized filter");
      }
    }
  }

  for (;;) {
    bool hasMore = false;
    if (NS_WARN_IF(NS_FAILED(entries->HasMoreElements(&hasMore))) || !hasMore) {
      break;
    }
    nsCOMPtr<nsISupports> supp;
    if (NS_WARN_IF(NS_FAILED(entries->GetNext(getter_AddRefs(supp))))) {
      break;
    }

    nsCOMPtr<nsIFile> currFile = do_QueryInterface(supp);
    MOZ_ASSERT(currFile);

    bool isSpecial, isFile;
    if (NS_WARN_IF(NS_FAILED(currFile->IsSpecial(&isSpecial))) ||
        isSpecial) {
      continue;
    }
    if (NS_WARN_IF(NS_FAILED(currFile->IsFile(&isFile)) ||
                   NS_FAILED(currFile->IsDirectory(&isDir))) ||
        !(isFile || isDir)) {
      continue;
    }

    if (filterOutSensitive) {
      bool isHidden;
      if (NS_WARN_IF(NS_FAILED(currFile->IsHidden(&isHidden))) || isHidden) {
        continue;
      }
      nsAutoString leafName;
      if (NS_WARN_IF(NS_FAILED(currFile->GetLeafName(leafName)))) {
        continue;
      }
      if (leafName[0] == char16_t('.')) {
        continue;
      }
    }

    nsAutoString path;
    if (NS_WARN_IF(NS_FAILED(currFile->GetPath(path)))) {
      continue;
    }

    Directory::FileOrDirectoryPath element;
    element.mPath = path;
    element.mType = isDir ? Directory::FileOrDirectoryPath::eDirectoryPath
                          : Directory::FileOrDirectoryPath::eFilePath;

    if (!mTargetData.AppendElement(element, fallible)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }
  return NS_OK;
}
コード例 #11
0
static bool
SetOperator(OperatorData*   aOperatorData,
            nsOperatorFlags aForm,
            const nsCString& aOperator,
            nsString&        aAttributes)

{
  static const char16_t kNullCh = char16_t('\0');

  // aOperator is in the expanded format \uNNNN\uNNNN ...
  // First compress these Unicode points to the internal nsString format
  int32_t i = 0;
  nsAutoString name, value;
  int32_t len = aOperator.Length();
  char16_t c = aOperator[i++];
  uint32_t state  = 0;
  char16_t uchar = 0;
  while (i <= len) {
    if (0 == state) {
      if (c != '\\')
        return false;
      if (i < len)
        c = aOperator[i];
      i++;
      if (('u' != c) && ('U' != c))
        return false;
      if (i < len)
        c = aOperator[i];
      i++;
      state++;
    }
    else {
      if (('0' <= c) && (c <= '9'))
         uchar = (uchar << 4) | (c - '0');
      else if (('a' <= c) && (c <= 'f'))
         uchar = (uchar << 4) | (c - 'a' + 0x0a);
      else if (('A' <= c) && (c <= 'F'))
         uchar = (uchar << 4) | (c - 'A' + 0x0a);
      else return false;
      if (i < len)
        c = aOperator[i];
      i++;
      state++;
      if (5 == state) {
        value.Append(uchar);
        uchar = 0;
        state = 0;
      }
    }
  }
  if (0 != state) return false;

  // Quick return when the caller doesn't care about the attributes and just wants
  // to know if this is a valid operator (this is the case at the first pass of the
  // parsing of the dictionary in InitOperators())
  if (!aForm) return true;

  // Add operator to hash table
  aOperatorData->mFlags |= aForm;
  aOperatorData->mStr.Assign(value);
  value.AppendInt(aForm, 10);
  gOperatorTable->Put(value, aOperatorData);

#ifdef DEBUG
  NS_LossyConvertUTF16toASCII str(aAttributes);
#endif
  // Loop over the space-delimited list of attributes to get the name:value pairs
  aAttributes.Append(kNullCh);  // put an extra null at the end
  char16_t* start = aAttributes.BeginWriting();
  char16_t* end   = start;
  while ((kNullCh != *start) && (kDashCh != *start)) {
    name.SetLength(0);
    value.SetLength(0);
    // skip leading space, the dash amounts to the end of the line
    while ((kNullCh!=*start) && (kDashCh!=*start) && nsCRT::IsAsciiSpace(*start)) {
      ++start;
    }
    end = start;
    // look for ':'
    while ((kNullCh!=*end) && (kDashCh!=*end) && !nsCRT::IsAsciiSpace(*end) &&
           (kColonCh!=*end)) {
      ++end;
    }
    // If ':' is not found, then it's a boolean property
    bool IsBooleanProperty = (kColonCh != *end);
    *end = kNullCh; // end segment here
    // this segment is the name
    if (start < end) {
      name.Assign(start);
    }
    if (IsBooleanProperty) {
      SetBooleanProperty(aOperatorData, name);
    } else {
      start = ++end;
      // look for space or end of line
      while ((kNullCh!=*end) && (kDashCh!=*end) &&
             !nsCRT::IsAsciiSpace(*end)) {
        ++end;
      }
      *end = kNullCh; // end segment here
      if (start < end) {
        // this segment is the value
        value.Assign(start);
      }
      SetProperty(aOperatorData, name, value);
    }
    start = ++end;
  }
  return true;
}
コード例 #12
0
  }

  // member data
  nsString        mStr;
  nsOperatorFlags mFlags;
  float           mLeadingSpace;   // unit is em
  float           mTrailingSpace;  // unit is em
};

static int32_t         gTableRefCount = 0;
static uint32_t        gOperatorCount = 0;
static OperatorData*   gOperatorArray = nullptr;
static nsDataHashtable<nsStringHashKey, OperatorData*>* gOperatorTable = nullptr;
static bool            gGlobalsInitialized   = false;

static const char16_t kDashCh  = char16_t('#');
static const char16_t kColonCh = char16_t(':');

static void
SetBooleanProperty(OperatorData* aOperatorData,
                   nsString      aName)
{
  if (aName.IsEmpty())
    return;

  if (aName.EqualsLiteral("stretchy") && (1 == aOperatorData->mStr.Length()))
    aOperatorData->mFlags |= NS_MATHML_OPERATOR_STRETCHY;
  else if (aName.EqualsLiteral("fence"))
    aOperatorData->mFlags |= NS_MATHML_OPERATOR_FENCE;
  else if (aName.EqualsLiteral("accent"))
    aOperatorData->mFlags |= NS_MATHML_OPERATOR_ACCENT;
コード例 #13
0
NS_IMETHODIMP
nsLocalFile::CreateUnique(uint32_t aType, uint32_t aAttributes)
{
  nsresult rv;
  bool longName;

#ifdef XP_WIN
  nsAutoString pathName, leafName, rootName, suffix;
  rv = GetPath(pathName);
#else
  nsAutoCString pathName, leafName, rootName, suffix;
  rv = GetNativePath(pathName);
#endif
  if (NS_FAILED(rv)) {
    return rv;
  }

  longName = (pathName.Length() + kMaxSequenceNumberLength >
              kMaxFilenameLength);
  if (!longName) {
    rv = Create(aType, aAttributes);
    if (rv != NS_ERROR_FILE_ALREADY_EXISTS) {
      return rv;
    }
  }

#ifdef XP_WIN
  rv = GetLeafName(leafName);
  if (NS_FAILED(rv)) {
    return rv;
  }

  const int32_t lastDot = leafName.RFindChar(char16_t('.'));
#else
  rv = GetNativeLeafName(leafName);
  if (NS_FAILED(rv)) {
    return rv;
  }

  const int32_t lastDot = leafName.RFindChar('.');
#endif

  if (lastDot == kNotFound) {
    rootName = leafName;
  } else {
    suffix = Substring(leafName, lastDot);      // include '.'
    rootName = Substring(leafName, 0, lastDot); // strip suffix and dot
  }

  if (longName) {
    int32_t maxRootLength = (kMaxFilenameLength -
                             (pathName.Length() - leafName.Length()) -
                             suffix.Length() - kMaxSequenceNumberLength);

    // We cannot create an item inside a directory whose name is too long.
    // Also, ensure that at least one character remains after we truncate
    // the root name, as we don't want to end up with an empty leaf name.
    if (maxRootLength < 2) {
      return NS_ERROR_FILE_UNRECOGNIZED_PATH;
    }

#ifdef XP_WIN
    // ensure that we don't cut the name in mid-UTF16-character
    rootName.SetLength(NS_IS_LOW_SURROGATE(rootName[maxRootLength]) ?
                       maxRootLength - 1 : maxRootLength);
    SetLeafName(rootName + suffix);
#else
    if (NS_IsNativeUTF8()) {
      // ensure that we don't cut the name in mid-UTF8-character
      // (assume the name is valid UTF8 to begin with)
      while (UTF8traits::isInSeq(rootName[maxRootLength])) {
        --maxRootLength;
      }

      // Another check to avoid ending up with an empty leaf name.
      if (maxRootLength == 0 && suffix.IsEmpty()) {
        return NS_ERROR_FILE_UNRECOGNIZED_PATH;
      }
    }

    rootName.SetLength(maxRootLength);
    SetNativeLeafName(rootName + suffix);
#endif
    nsresult rv = Create(aType, aAttributes);
    if (rv != NS_ERROR_FILE_ALREADY_EXISTS) {
      return rv;
    }
  }

  for (int indx = 1; indx < 10000; ++indx) {
    // start with "Picture-1.jpg" after "Picture.jpg" exists
#ifdef XP_WIN
    SetLeafName(rootName +
                NS_ConvertASCIItoUTF16(nsPrintfCString("-%d", indx)) +
                suffix);
#else
    SetNativeLeafName(rootName + nsPrintfCString("-%d", indx) + suffix);
#endif
    rv = Create(aType, aAttributes);
    if (NS_SUCCEEDED(rv) || rv != NS_ERROR_FILE_ALREADY_EXISTS) {
      return rv;
    }
  }

  // The disk is full, sort of
  return NS_ERROR_FILE_TOO_BIG;
}
コード例 #14
0
ファイル: nsExpatDriver.cpp プロジェクト: cbrem/gecko-dev
nsresult
nsExpatDriver::HandleError()
{
  int32_t code = XML_GetErrorCode(mExpatParser);
  NS_ASSERTION(code > XML_ERROR_NONE, "unexpected XML error code");

  // Map Expat error code to an error string
  // XXX Deal with error returns.
  nsAutoString description;
  nsParserMsgUtils::GetLocalizedStringByID(XMLPARSER_PROPERTIES, code,
                                           description);

  if (code == XML_ERROR_TAG_MISMATCH) {
    /**
     *  Expat can send the following:
     *    localName
     *    namespaceURI<separator>localName
     *    namespaceURI<separator>localName<separator>prefix
     *
     *  and we use 0xFFFF for the <separator>.
     *
     */
    const char16_t *mismatch = MOZ_XML_GetMismatchedTag(mExpatParser);
    const char16_t *uriEnd = nullptr;
    const char16_t *nameEnd = nullptr;
    const char16_t *pos;
    for (pos = mismatch; *pos; ++pos) {
      if (*pos == kExpatSeparatorChar) {
        if (uriEnd) {
          nameEnd = pos;
        }
        else {
          uriEnd = pos;
        }
      }
    }

    nsAutoString tagName;
    if (uriEnd && nameEnd) {
      // We have a prefix.
      tagName.Append(nameEnd + 1, pos - nameEnd - 1);
      tagName.Append(char16_t(':'));
    }
    const char16_t *nameStart = uriEnd ? uriEnd + 1 : mismatch;
    tagName.Append(nameStart, (nameEnd ? nameEnd : pos) - nameStart);
    
    nsAutoString msg;
    nsParserMsgUtils::GetLocalizedStringByName(XMLPARSER_PROPERTIES,
                                               "Expected", msg);

    // . Expected: </%S>.
    char16_t *message = nsTextFormatter::smprintf(msg.get(), tagName.get());
    if (!message) {
      return NS_ERROR_OUT_OF_MEMORY;
    }

    description.Append(message);

    nsTextFormatter::smprintf_free(message);
  }

  // Adjust the column number so that it is one based rather than zero based.
  uint32_t colNumber = XML_GetCurrentColumnNumber(mExpatParser) + 1;
  uint32_t lineNumber = XML_GetCurrentLineNumber(mExpatParser);

  nsAutoString errorText;
  CreateErrorText(description.get(), XML_GetBase(mExpatParser), lineNumber,
                  colNumber, errorText);

  NS_ASSERTION(mSink, "no sink?");

  nsAutoString sourceText(mLastLine);
  AppendErrorPointer(colNumber, mLastLine.get(), sourceText);

  // Try to create and initialize the script error.
  nsCOMPtr<nsIScriptError> serr(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
  nsresult rv = NS_ERROR_FAILURE;
  if (serr) {
    rv = serr->InitWithWindowID(description,
                                mURISpec,
                                mLastLine,
                                lineNumber, colNumber,
                                nsIScriptError::errorFlag, "malformed-xml",
                                mInnerWindowID);
  }

  // If it didn't initialize, we can't do any logging.
  bool shouldReportError = NS_SUCCEEDED(rv);

  if (mSink && shouldReportError) {
    rv = mSink->ReportError(errorText.get(), 
                            sourceText.get(), 
                            serr, 
                            &shouldReportError);
    if (NS_FAILED(rv)) {
      shouldReportError = true;
    }
  }

  if (shouldReportError) {
    nsCOMPtr<nsIConsoleService> cs
      (do_GetService(NS_CONSOLESERVICE_CONTRACTID));  
    if (cs) {
      cs->LogMessage(serr);
    }
  }

  return NS_ERROR_HTMLPARSER_STOPPARSING;
}
コード例 #15
0
NS_IMETHODIMP
nsHTMLURIRefObject::GetNextURI(nsAString & aURI)
{
  NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED);

  nsAutoString tagName;
  nsresult rv = mNode->GetNodeName(tagName);
  NS_ENSURE_SUCCESS(rv, rv);

  // Loop over attribute list:
  if (!mAttributes)
  {
    nsCOMPtr<nsIDOMElement> element (do_QueryInterface(mNode));
    NS_ENSURE_TRUE(element, NS_ERROR_INVALID_ARG);

    mCurAttrIndex = 0;
    element->GetAttributes(getter_AddRefs(mAttributes));
    NS_ENSURE_TRUE(mAttributes, NS_ERROR_NOT_INITIALIZED);

    rv = mAttributes->GetLength(&mAttributeCnt);
    NS_ENSURE_SUCCESS(rv, rv);
    NS_ENSURE_TRUE(mAttributeCnt, NS_ERROR_FAILURE);
    mCurAttrIndex = 0;
  }

  while (mCurAttrIndex < mAttributeCnt)
  {
    nsCOMPtr<nsIDOMAttr> attrNode;
    rv = mAttributes->Item(mCurAttrIndex++, getter_AddRefs(attrNode));
    NS_ENSURE_SUCCESS(rv, rv);
    NS_ENSURE_ARG_POINTER(attrNode);
    nsString curAttr;
    rv = attrNode->GetName(curAttr);
    NS_ENSURE_SUCCESS(rv, rv);

    // href >> A, AREA, BASE, LINK
    if (MATCHES(curAttr, "href"))
    {
      if (!MATCHES(tagName, "a") && !MATCHES(tagName, "area")
          && !MATCHES(tagName, "base") && !MATCHES(tagName, "link"))
        continue;
      rv = attrNode->GetValue(aURI);
      NS_ENSURE_SUCCESS(rv, rv);
      nsString uri (aURI);
      // href pointing to a named anchor doesn't count
      if (aURI.First() != char16_t('#'))
        return NS_OK;
      aURI.Truncate();
      return NS_ERROR_INVALID_ARG;
    }
    // src >> FRAME, IFRAME, IMG, INPUT, SCRIPT
    else if (MATCHES(curAttr, "src"))
    {
      if (!MATCHES(tagName, "img")
          && !MATCHES(tagName, "frame") && !MATCHES(tagName, "iframe")
          && !MATCHES(tagName, "input") && !MATCHES(tagName, "script"))
        continue;
      return attrNode->GetValue(aURI);
    }
    //<META http-equiv="refresh" content="3,http://www.acme.com/intro.html">
    else if (MATCHES(curAttr, "content"))
    {
      if (!MATCHES(tagName, "meta"))
        continue;
    }
    // longdesc >> FRAME, IFRAME, IMG
    else if (MATCHES(curAttr, "longdesc"))
    {
      if (!MATCHES(tagName, "img")
          && !MATCHES(tagName, "frame") && !MATCHES(tagName, "iframe"))
        continue;
    }
    // usemap >> IMG, INPUT, OBJECT
    else if (MATCHES(curAttr, "usemap"))
    {
      if (!MATCHES(tagName, "img")
          && !MATCHES(tagName, "input") && !MATCHES(tagName, "object"))
        continue;
    }
    // action >> FORM
    else if (MATCHES(curAttr, "action"))
    {
      if (!MATCHES(tagName, "form"))
        continue;
    }
    // background >> BODY
    else if (MATCHES(curAttr, "background"))
    {
      if (!MATCHES(tagName, "body"))
        continue;
    }
    // codebase >> OBJECT, APPLET
    else if (MATCHES(curAttr, "codebase"))
    {
      if (!MATCHES(tagName, "meta"))
        continue;
    }
    // classid >> OBJECT
    else if (MATCHES(curAttr, "classid"))
    {
      if (!MATCHES(tagName, "object"))
        continue;
    }
    // data >> OBJECT
    else if (MATCHES(curAttr, "data"))
    {
      if (!MATCHES(tagName, "object"))
        continue;
    }
    // cite >> BLOCKQUOTE, DEL, INS, Q
    else if (MATCHES(curAttr, "cite"))
    {
      if (!MATCHES(tagName, "blockquote") && !MATCHES(tagName, "q")
          && !MATCHES(tagName, "del") && !MATCHES(tagName, "ins"))
        continue;
    }
    // profile >> HEAD
    else if (MATCHES(curAttr, "profile"))
    {
      if (!MATCHES(tagName, "head"))
        continue;
    }
    // archive attribute on APPLET; warning, it contains a list of URIs.
    else if (MATCHES(curAttr, "archive"))
    {
      if (!MATCHES(tagName, "applet"))
        continue;
    }
  }
  // Return a code to indicate that there are no more,
  // to distinguish that case from real errors.
  return NS_ERROR_NOT_AVAILABLE;
}
コード例 #16
0
nsresult
nsRDFXMLSerializer::SerializeDescription(nsIOutputStream* aStream,
                                         nsIRDFResource* aResource)
{
    nsresult rv;

    bool isTypedNode = false;
    nsCString typeQName;

    nsCOMPtr<nsIRDFNode> typeNode;
    mDataSource->GetTarget(aResource, kRDF_type, true, getter_AddRefs(typeNode));
    if (typeNode) {
        nsCOMPtr<nsIRDFResource> type = do_QueryInterface(typeNode, &rv);
        if (type) {
            // Try to get a namespace prefix.  If none is available,
            // just treat the description as if it weren't a typed node 
            // after all and emit rdf:type as a normal property.  This 
            // seems preferable to using a bogus (invented) prefix.
            isTypedNode = NS_SUCCEEDED(GetQName(type, typeQName));
        }
    }

    nsAutoCString uri;
    rv = aResource->GetValueUTF8(uri);
    if (NS_FAILED(rv)) return rv;

    rdf_MakeRelativeRef(mBaseURLSpec, uri);
    rdf_EscapeAttributeValue(uri);

    // Emit an open tag and the subject
    if (isTypedNode) {
        rv = rdf_BlockingWrite(aStream, NS_LITERAL_STRING("  <"));
        if (NS_FAILED(rv)) return rv;
        // Watch out for the default namespace!
        rv = rdf_BlockingWrite(aStream, typeQName);
        if (NS_FAILED(rv)) return rv;
    }
    else {
        rv = rdf_BlockingWrite(aStream, kRDFDescriptionOpen,
                               sizeof(kRDFDescriptionOpen) - 1);
        if (NS_FAILED(rv)) return rv;
    }
    if (uri[0] == char16_t('#')) {
        uri.Cut(0, 1);
        rv = rdf_BlockingWrite(aStream, kIDAttr, sizeof(kIDAttr) - 1);
    }
    else {
        rv = rdf_BlockingWrite(aStream, kAboutAttr, sizeof(kAboutAttr) - 1);
    }
    if (NS_FAILED(rv)) return rv;

    uri.Append('"');
    rv = rdf_BlockingWrite(aStream, uri);
    if (NS_FAILED(rv)) return rv;

    // Any value that's a literal we can write out as an inline
    // attribute on the RDF:Description
    nsAutoTArray<nsIRDFResource*, 8> visited;
    int32_t skipped = 0;

    nsCOMPtr<nsISimpleEnumerator> arcs;
    mDataSource->ArcLabelsOut(aResource, getter_AddRefs(arcs));

    if (arcs) {
        // Don't re-serialize rdf:type later on
        if (isTypedNode)
            visited.AppendElement(kRDF_type);

        while (1) {
            bool hasMore = false;
            arcs->HasMoreElements(&hasMore);
            if (! hasMore)
                break;

            nsCOMPtr<nsISupports> isupports;
            arcs->GetNext(getter_AddRefs(isupports));

            nsCOMPtr<nsIRDFResource> property = do_QueryInterface(isupports);
            if (! property)
                continue;

            // Ignore properties that pertain to containers; we may be
            // called from SerializeContainer() if the container resource
            // has been assigned non-container properties.
            if (IsContainerProperty(property))
                continue;

            // Only serialize values for the property once.
            if (visited.Contains(property.get()))
                continue;

            visited.AppendElement(property.get());

            SerializeProperty(aStream, aResource, property, true, &skipped);
        }
    }

    if (skipped) {
        // Close the RDF:Description tag.
        rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(">\n"));
        if (NS_FAILED(rv)) return rv;

        // Now write out resources (which might have their own
        // substructure) as children.
        mDataSource->ArcLabelsOut(aResource, getter_AddRefs(arcs));

        if (arcs) {
            // Forget that we've visited anything
            visited.Clear();
            // ... except for rdf:type
            if (isTypedNode)
                visited.AppendElement(kRDF_type);

            while (1) {
                bool hasMore = false;
                arcs->HasMoreElements(&hasMore);
                if (! hasMore)
                    break;

                nsCOMPtr<nsISupports> isupports;
                arcs->GetNext(getter_AddRefs(isupports));

                nsCOMPtr<nsIRDFResource> property = do_QueryInterface(isupports);
                if (! property)
                    continue;

                // Ignore properties that pertain to containers; we may be
                // called from SerializeContainer() if the container
                // resource has been assigned non-container properties.
                if (IsContainerProperty(property))
                    continue;

                // have we already seen this property?  If so, don't write it
                // out again; serialize property will write each instance.
                if (visited.Contains(property.get()))
                    continue;

                visited.AppendElement(property.get());

                SerializeProperty(aStream, aResource, property, false, &skipped);
            }
        }

        // Emit a proper close-tag.
        if (isTypedNode) {
            rv = rdf_BlockingWrite(aStream,  NS_LITERAL_CSTRING("  </"));
            if (NS_FAILED(rv)) return rv;
            // Watch out for the default namespace!
            rdf_BlockingWrite(aStream, typeQName);
            if (NS_FAILED(rv)) return rv;
            rdf_BlockingWrite(aStream, ">\n", 2);
            if (NS_FAILED(rv)) return rv;
        }
        else {
            rv = rdf_BlockingWrite(aStream, kRDFDescriptionClose,
                                   sizeof(kRDFDescriptionClose) - 1);
            if (NS_FAILED(rv)) return rv;
        }
    }
    else {
        // If we saw _no_ child properties, then we can don't need a
        // close-tag.
        rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(" />\n"));
        if (NS_FAILED(rv)) return rv;
    }

    return NS_OK;
}
コード例 #17
0
ファイル: EventSource.cpp プロジェクト: Manishearth/gecko-dev
nsresult
EventSource::SetFieldAndClear()
{
  if (mLastFieldName.IsEmpty()) {
    mLastFieldValue.Truncate();
    return NS_OK;
  }

  char16_t first_char;
  first_char = mLastFieldName.CharAt(0);

  switch (first_char)  // with no case folding performed
  {
    case char16_t('d'):
      if (mLastFieldName.EqualsLiteral("data")) {
        // If the field name is "data" append the field value to the data
        // buffer, then append a single U+000A LINE FEED (LF) character
        // to the data buffer.
        mCurrentMessage.mData.Append(mLastFieldValue);
        mCurrentMessage.mData.Append(LF_CHAR);
      }
      break;

    case char16_t('e'):
      if (mLastFieldName.EqualsLiteral("event")) {
        mCurrentMessage.mEventName.Assign(mLastFieldValue);
      }
      break;

    case char16_t('i'):
      if (mLastFieldName.EqualsLiteral("id")) {
        mCurrentMessage.mLastEventID.Assign(mLastFieldValue);
      }
      break;

    case char16_t('r'):
      if (mLastFieldName.EqualsLiteral("retry")) {
        uint32_t newValue=0;
        uint32_t i = 0;  // we must ensure that there are only digits
        bool assign = true;
        for (i = 0; i < mLastFieldValue.Length(); ++i) {
          if (mLastFieldValue.CharAt(i) < (char16_t)'0' ||
              mLastFieldValue.CharAt(i) > (char16_t)'9') {
            assign = false;
            break;
          }
          newValue = newValue*10 +
                     (((uint32_t)mLastFieldValue.CharAt(i))-
                       ((uint32_t)((char16_t)'0')));
        }

        if (assign) {
          if (newValue < MIN_RECONNECTION_TIME_VALUE) {
            mReconnectionTime = MIN_RECONNECTION_TIME_VALUE;
          } else if (newValue > MAX_RECONNECTION_TIME_VALUE) {
            mReconnectionTime = MAX_RECONNECTION_TIME_VALUE;
          } else {
            mReconnectionTime = newValue;
          }
        }
        break;
      }
      break;
  }

  mLastFieldName.Truncate();
  mLastFieldValue.Truncate();

  return NS_OK;
}
コード例 #18
0
already_AddRefed<nsMIMEInfoWin> nsOSHelperAppService::GetByExtension(const nsAFlatString& aFileExt, const char *aTypeHint)
{
  if (aFileExt.IsEmpty())
    return nullptr;

  // windows registry assumes your file extension is going to include the '.'.
  // so make sure it's there...
  nsAutoString fileExtToUse;
  if (aFileExt.First() != char16_t('.'))
    fileExtToUse = char16_t('.');

  fileExtToUse.Append(aFileExt);

  // Try to get an entry from the windows registry.
  nsCOMPtr<nsIWindowsRegKey> regKey = 
    do_CreateInstance("@mozilla.org/windows-registry-key;1");
  if (!regKey) 
    return nullptr; 

  nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
                             fileExtToUse,
                             nsIWindowsRegKey::ACCESS_QUERY_VALUE);
  if (NS_FAILED(rv))
    return nullptr; 

  nsAutoCString typeToUse;
  if (aTypeHint && *aTypeHint) {
    typeToUse.Assign(aTypeHint);
  }
  else {
    nsAutoString temp;
    if (NS_FAILED(regKey->ReadStringValue(NS_LITERAL_STRING("Content Type"),
                  temp)) || temp.IsEmpty()) {
      return nullptr; 
    }
    // Content-Type is always in ASCII
    LossyAppendUTF16toASCII(temp, typeToUse);
  }

  nsRefPtr<nsMIMEInfoWin> mimeInfo = new nsMIMEInfoWin(typeToUse);

  // don't append the '.'
  mimeInfo->AppendExtension(NS_ConvertUTF16toUTF8(Substring(fileExtToUse, 1)));
  mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault);

  nsAutoString appInfo;
  bool found;

  // Retrieve the default application for this extension
  if (mAppAssoc) {
    // Vista: use the new application association COM interfaces
    // for resolving helpers.
    nsString assocType(fileExtToUse);
    wchar_t * pResult = nullptr;
    HRESULT hr = mAppAssoc->QueryCurrentDefault(assocType.get(),
                                                AT_FILEEXTENSION, AL_EFFECTIVE,
                                                &pResult);
    if (SUCCEEDED(hr)) {
      found = true;
      appInfo.Assign(pResult);
      CoTaskMemFree(pResult);
    } 
    else {
      found = false;
    }
  } 
  else
  {
    found = NS_SUCCEEDED(regKey->ReadStringValue(EmptyString(), 
                                                 appInfo));
  }

  // Bug 358297 - ignore the default handler, force the user to choose app
  if (appInfo.EqualsLiteral("XPSViewer.Document"))
    found = false;

  if (!found) {
    return nullptr;
  }

  // Get other nsIMIMEInfo fields from registry, if possible.
  nsAutoString defaultDescription;
  nsCOMPtr<nsIFile> defaultApplication;
  
  if (NS_FAILED(GetDefaultAppInfo(appInfo, defaultDescription,
                                  getter_AddRefs(defaultApplication)))) {
    return nullptr;
  }

  mimeInfo->SetDefaultDescription(defaultDescription);
  mimeInfo->SetDefaultApplicationHandler(defaultApplication);

  // Grab the general description
  GetMIMEInfoFromRegistry(appInfo, mimeInfo);

  return mimeInfo.forget();
}
コード例 #19
0
ファイル: nsMathMLmoFrame.cpp プロジェクト: L2-D2/gecko-dev
// get the text that we enclose and setup our nsMathMLChar
void
nsMathMLmoFrame::ProcessTextData()
{
  mFlags = 0;

  nsAutoString data;
  if (!nsContentUtils::GetNodeTextContent(mContent, false, data)) {
    NS_RUNTIMEABORT("OOM");
  }

  data.CompressWhitespace();
  int32_t length = data.Length();
  char16_t ch = (length == 0) ? char16_t('\0') : data[0];

  if ((length == 1) && 
      (ch == kApplyFunction  ||
       ch == kInvisibleSeparator ||
       ch == kInvisiblePlus ||
       ch == kInvisibleTimes)) {
    mFlags |= NS_MATHML_OPERATOR_INVISIBLE;
  }

  // don't bother doing anything special if we don't have a single child
  nsPresContext* presContext = PresContext();
  if (mFrames.GetLength() != 1) {
    data.Truncate(); // empty data to reset the char
    mMathMLChar.SetData(presContext, data);
    ResolveMathMLCharStyle(presContext, mContent, mStyleContext, &mMathMLChar);
    return;
  }

  // special... in math mode, the usual minus sign '-' looks too short, so
  // what we do here is to remap <mo>-</mo> to the official Unicode minus
  // sign (U+2212) which looks much better. For background on this, see
  // http://groups.google.com/groups?hl=en&th=66488daf1ade7635&rnum=1
  if (1 == length && ch == '-') {
    ch = 0x2212;
    data = ch;
  }

  // cache the special bits: mutable, accent, movablelimits, centered.
  // we need to do this in anticipation of other requirements, and these
  // bits don't change. Do not reset these bits unless the text gets changed.

  // lookup all the forms under which the operator is listed in the dictionary,
  // and record whether the operator has accent="true" or movablelimits="true"
  nsOperatorFlags flags[4];
  float lspace[4], rspace[4];
  nsMathMLOperators::LookupOperators(data, flags, lspace, rspace);
  nsOperatorFlags allFlags =
    flags[NS_MATHML_OPERATOR_FORM_INFIX] |
    flags[NS_MATHML_OPERATOR_FORM_POSTFIX] |
    flags[NS_MATHML_OPERATOR_FORM_PREFIX];

  mFlags |= allFlags & NS_MATHML_OPERATOR_ACCENT;
  mFlags |= allFlags & NS_MATHML_OPERATOR_MOVABLELIMITS;

  // see if this is an operator that should be centered to cater for 
  // fonts that are not math-aware
  if (1 == length) {
    if ((ch == '+') || (ch == '=') || (ch == '*') ||
        (ch == 0x2212) || // &minus;
        (ch == 0x2264) || // &le;
        (ch == 0x2265) || // &ge;
        (ch == 0x00D7)) { // &times;
      mFlags |= NS_MATHML_OPERATOR_CENTERED;
    }
  }

  // cache the operator
  mMathMLChar.SetData(presContext, data);

  // cache the native direction -- beware of bug 133429...
  // mEmbellishData.direction must always retain our native direction, whereas
  // mMathMLChar.GetStretchDirection() may change later, when Stretch() is called
  mEmbellishData.direction = mMathMLChar.GetStretchDirection();

  bool isMutable =
    NS_MATHML_OPERATOR_IS_LARGEOP(allFlags) ||
    (mEmbellishData.direction != NS_STRETCH_DIRECTION_UNSUPPORTED);
  if (isMutable)
    mFlags |= NS_MATHML_OPERATOR_MUTABLE;

  ResolveMathMLCharStyle(presContext, mContent, mStyleContext, &mMathMLChar);
}
コード例 #20
0
ファイル: nsMathMLmoFrame.cpp プロジェクト: L2-D2/gecko-dev
// additional style context to be used by our MathMLChar.
#define NS_MATHML_CHAR_STYLE_CONTEXT_INDEX   0

nsIFrame*
NS_NewMathMLmoFrame(nsIPresShell* aPresShell, nsStyleContext *aContext)
{
  return new (aPresShell) nsMathMLmoFrame(aContext);
}

NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmoFrame)

nsMathMLmoFrame::~nsMathMLmoFrame()
{
}

static const char16_t kApplyFunction  = char16_t(0x2061);
static const char16_t kInvisibleTimes = char16_t(0x2062);
static const char16_t kInvisibleSeparator = char16_t(0x2063);
static const char16_t kInvisiblePlus = char16_t(0x2064);

eMathMLFrameType
nsMathMLmoFrame::GetMathMLFrameType()
{
  return NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags)
    ? eMathMLFrameType_OperatorInvisible
    : eMathMLFrameType_OperatorOrdinary;
}

// since a mouse click implies selection, we cannot just rely on the
// frame's state bit in our child text frame. So we will first check
// its selected state bit, and use this little helper to double check.
コード例 #21
0
ファイル: nsMIMEInfoWin.cpp プロジェクト: Andrel322/gecko-dev
/** 
 * Returns a list of nsILocalHandlerApp objects containing local 
 * handlers associated with this mimeinfo. Implemented per 
 * platform using information in this object to generate the
 * best list. Typically used for an "open with" style user 
 * option.
 * 
 * @return nsIArray of nsILocalHandlerApp
 */
NS_IMETHODIMP
nsMIMEInfoWin::GetPossibleLocalHandlers(nsIArray **_retval)
{
  nsresult rv;

  *_retval = nullptr;

  nsCOMPtr<nsIMutableArray> appList =
    do_CreateInstance("@mozilla.org/array;1");

  if (!appList)
    return NS_ERROR_FAILURE;

  nsTArray<nsString> trackList;

  nsAutoCString fileExt;
  GetPrimaryExtension(fileExt);

  nsCOMPtr<nsIWindowsRegKey> regKey =
    do_CreateInstance("@mozilla.org/windows-registry-key;1");
  if (!regKey) 
    return NS_ERROR_FAILURE; 
  nsCOMPtr<nsIWindowsRegKey> appKey =
    do_CreateInstance("@mozilla.org/windows-registry-key;1");
  if (!appKey) 
    return NS_ERROR_FAILURE; 

  nsAutoString workingRegistryPath;

  bool extKnown = false;
  if (fileExt.IsEmpty()) {
    extKnown = true;
    // Mime type discovery is possible in some cases, through 
    // HKEY_CLASSES_ROOT\MIME\Database\Content Type, however, a number
    // of file extensions related to mime type are simply not defined,
    // (application/rss+xml & application/atom+xml are good examples)
    // in which case we can only provide a generic list.
    nsAutoCString mimeType;
    GetMIMEType(mimeType);
    if (!mimeType.IsEmpty()) {
      workingRegistryPath.AppendLiteral("MIME\\Database\\Content Type\\");
      workingRegistryPath.Append(NS_ConvertASCIItoUTF16(mimeType));
            
      rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
                        workingRegistryPath,
                        nsIWindowsRegKey::ACCESS_QUERY_VALUE);
      if(NS_SUCCEEDED(rv)) {
        nsAutoString mimeFileExt;
        if (NS_SUCCEEDED(regKey->ReadStringValue(EmptyString(), mimeFileExt))) {
          CopyUTF16toUTF8(mimeFileExt, fileExt);
          extKnown = false;
        }
      }
    }
  }

  nsAutoString fileExtToUse;
  if (fileExt.First() != '.')
    fileExtToUse = char16_t('.');
  fileExtToUse.Append(NS_ConvertUTF8toUTF16(fileExt));

  // Note, the order in which these occur has an effect on the 
  // validity of the resulting display list.

  if (!extKnown) {
    // 1) Get the default handler if it exists
    workingRegistryPath = fileExtToUse;

    rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
                      workingRegistryPath,
                      nsIWindowsRegKey::ACCESS_QUERY_VALUE);
    if (NS_SUCCEEDED(rv)) {
      nsAutoString appProgId;
      if (NS_SUCCEEDED(regKey->ReadStringValue(EmptyString(), appProgId))) {
        // Bug 358297 - ignore the embedded internet explorer handler
        if (appProgId != NS_LITERAL_STRING("XPSViewer.Document")) {
          nsAutoString appFilesystemCommand;
          if (GetProgIDVerbCommandHandler(appProgId,
                                          appFilesystemCommand,
                                          false) &&
              !IsPathInList(appFilesystemCommand, trackList)) {
            ProcessPath(appList, trackList, appFilesystemCommand);
          }
        }
      }
      regKey->Close();
    }


    // 2) list HKEY_CLASSES_ROOT\.ext\OpenWithList
    
    workingRegistryPath = fileExtToUse;
    workingRegistryPath.AppendLiteral("\\OpenWithList");

    rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
                      workingRegistryPath,
                      nsIWindowsRegKey::ACCESS_QUERY_VALUE);
    if (NS_SUCCEEDED(rv)) {
      uint32_t count = 0;
      if (NS_SUCCEEDED(regKey->GetValueCount(&count)) && count > 0) {
        for (uint32_t index = 0; index < count; index++) {
          nsAutoString appName;
          if (NS_FAILED(regKey->GetValueName(index, appName)))
            continue;

          // HKEY_CLASSES_ROOT\Applications\firefox.exe = "path params"
          nsAutoString appFilesystemCommand;
          if (!GetAppsVerbCommandHandler(appName,
                                         appFilesystemCommand,
                                         false) ||
              IsPathInList(appFilesystemCommand, trackList))
            continue;
          ProcessPath(appList, trackList, appFilesystemCommand);
        }
      }
      regKey->Close();
    }


    // 3) List HKEY_CLASSES_ROOT\.ext\OpenWithProgids, with the
    // different step of resolving the progids for the command handler.

    workingRegistryPath = fileExtToUse;
    workingRegistryPath.AppendLiteral("\\OpenWithProgids");

    rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
                      workingRegistryPath,
                      nsIWindowsRegKey::ACCESS_QUERY_VALUE);
    if (NS_SUCCEEDED(rv)) {
      uint32_t count = 0;
      if (NS_SUCCEEDED(regKey->GetValueCount(&count)) && count > 0) {
        for (uint32_t index = 0; index < count; index++) {
          // HKEY_CLASSES_ROOT\.ext\OpenWithProgids\Windows.XPSReachViewer
          nsAutoString appProgId;
          if (NS_FAILED(regKey->GetValueName(index, appProgId)))
            continue;

          nsAutoString appFilesystemCommand;
          if (!GetProgIDVerbCommandHandler(appProgId,
                                           appFilesystemCommand,
                                           false) ||
              IsPathInList(appFilesystemCommand, trackList))
            continue;
          ProcessPath(appList, trackList, appFilesystemCommand);
        }
      }
      regKey->Close();
    }


    // 4) Add any non configured applications located in the MRU list

    // HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion
    // \Explorer\FileExts\.ext\OpenWithList
    workingRegistryPath =
      NS_LITERAL_STRING("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\");
    workingRegistryPath += fileExtToUse;
    workingRegistryPath.AppendLiteral("\\OpenWithList");

    rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
                      workingRegistryPath,
                      nsIWindowsRegKey::ACCESS_QUERY_VALUE);
    if (NS_SUCCEEDED(rv)) {
      uint32_t count = 0;
      if (NS_SUCCEEDED(regKey->GetValueCount(&count)) && count > 0) {
        for (uint32_t index = 0; index < count; index++) {
          nsAutoString appName, appValue;
          if (NS_FAILED(regKey->GetValueName(index, appName)))
            continue;
          if (appName.EqualsLiteral("MRUList"))
            continue;
          if (NS_FAILED(regKey->ReadStringValue(appName, appValue)))
            continue;
          
          // HKEY_CLASSES_ROOT\Applications\firefox.exe = "path params"
          nsAutoString appFilesystemCommand;
          if (!GetAppsVerbCommandHandler(appValue,
                                         appFilesystemCommand,
                                         false) ||
              IsPathInList(appFilesystemCommand, trackList))
            continue;
          ProcessPath(appList, trackList, appFilesystemCommand);
        }
      }
    }
    

    // 5) Add any non configured progids in the MRU list, with the
    // different step of resolving the progids for the command handler.
    
    // HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion
    // \Explorer\FileExts\.ext\OpenWithProgids
    workingRegistryPath =
      NS_LITERAL_STRING("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\");
    workingRegistryPath += fileExtToUse;
    workingRegistryPath.AppendLiteral("\\OpenWithProgids");

    regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
                 workingRegistryPath,
                 nsIWindowsRegKey::ACCESS_QUERY_VALUE);
    if (NS_SUCCEEDED(rv)) {
      uint32_t count = 0;
      if (NS_SUCCEEDED(regKey->GetValueCount(&count)) && count > 0) {
        for (uint32_t index = 0; index < count; index++) {
          nsAutoString appIndex, appProgId;
          if (NS_FAILED(regKey->GetValueName(index, appProgId)))
            continue;

          nsAutoString appFilesystemCommand;
          if (!GetProgIDVerbCommandHandler(appProgId,
                                           appFilesystemCommand,
                                           false) ||
              IsPathInList(appFilesystemCommand, trackList))
            continue;
          ProcessPath(appList, trackList, appFilesystemCommand);
        }
      }
      regKey->Close();
    }


    // 6) Check the perceived type value, and use this to lookup the perceivedtype
    // open with list.
    // http://msdn2.microsoft.com/en-us/library/aa969373.aspx

    workingRegistryPath = fileExtToUse;

    regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
                 workingRegistryPath,
                 nsIWindowsRegKey::ACCESS_QUERY_VALUE);
    if (NS_SUCCEEDED(rv)) {
      nsAutoString perceivedType;
      rv = regKey->ReadStringValue(NS_LITERAL_STRING("PerceivedType"),
                                   perceivedType);
      if (NS_SUCCEEDED(rv)) {
        nsAutoString openWithListPath(NS_LITERAL_STRING("SystemFileAssociations\\"));
        openWithListPath.Append(perceivedType); // no period
        openWithListPath.AppendLiteral("\\OpenWithList");

        nsresult rv = appKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
                                   openWithListPath,
                                   nsIWindowsRegKey::ACCESS_QUERY_VALUE);
        if (NS_SUCCEEDED(rv)) {
          uint32_t count = 0;
          if (NS_SUCCEEDED(regKey->GetValueCount(&count)) && count > 0) {
            for (uint32_t index = 0; index < count; index++) {
              nsAutoString appName;
              if (NS_FAILED(regKey->GetValueName(index, appName)))
                continue;
              
              // HKEY_CLASSES_ROOT\Applications\firefox.exe = "path params"
              nsAutoString appFilesystemCommand;
              if (!GetAppsVerbCommandHandler(appName, appFilesystemCommand, 
                                             false) ||
                  IsPathInList(appFilesystemCommand, trackList))
                continue;
              ProcessPath(appList, trackList, appFilesystemCommand);
            }
          }
        }
      }
    }
  } // extKnown == false


  // 7) list global HKEY_CLASSES_ROOT\*\OpenWithList
  // Listing general purpose handlers, not specific to a mime type or file extension

  workingRegistryPath = NS_LITERAL_STRING("*\\OpenWithList");

  rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
                    workingRegistryPath,
                    nsIWindowsRegKey::ACCESS_QUERY_VALUE);
  if (NS_SUCCEEDED(rv)) {
    uint32_t count = 0;
    if (NS_SUCCEEDED(regKey->GetValueCount(&count)) && count > 0) {
      for (uint32_t index = 0; index < count; index++) {
        nsAutoString appName;
        if (NS_FAILED(regKey->GetValueName(index, appName)))
          continue;

        // HKEY_CLASSES_ROOT\Applications\firefox.exe = "path params"
        nsAutoString appFilesystemCommand;
        if (!GetAppsVerbCommandHandler(appName, appFilesystemCommand,
                                       false) ||
            IsPathInList(appFilesystemCommand, trackList))
          continue;
        ProcessPath(appList, trackList, appFilesystemCommand);
      }
    }
    regKey->Close();
  }


  // 8) General application's list - not file extension specific on windows
  workingRegistryPath = NS_LITERAL_STRING("Applications");

  rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
                    workingRegistryPath,
                    nsIWindowsRegKey::ACCESS_ENUMERATE_SUB_KEYS|
                    nsIWindowsRegKey::ACCESS_QUERY_VALUE);
  if (NS_SUCCEEDED(rv)) {
    uint32_t count = 0;
    if (NS_SUCCEEDED(regKey->GetChildCount(&count)) && count > 0) {
      for (uint32_t index = 0; index < count; index++) {
        nsAutoString appName;
        if (NS_FAILED(regKey->GetChildName(index, appName)))
          continue;

        // HKEY_CLASSES_ROOT\Applications\firefox.exe = "path params"
        nsAutoString appFilesystemCommand;
        if (!GetAppsVerbCommandHandler(appName, appFilesystemCommand,
                                       false) ||
            IsPathInList(appFilesystemCommand, trackList))
          continue;
        ProcessPath(appList, trackList, appFilesystemCommand);
      }
    }
  }

  // Return to the caller
  *_retval = appList;
  NS_ADDREF(*_retval);

  return NS_OK;
}
コード例 #22
0
bool
nsPropertiesParser::ParseValueCharacter(char16_t aChar, const char16_t* aCur,
                                        const char16_t*& aTokenStart,
                                        nsAString& aOldValue)
{
  switch (mSpecialState) {
    // the normal state - look for special characters
    case eParserSpecial_None:
      switch (aChar) {
        case '\\':
          if (mHaveMultiLine) {
            // there is nothing to append to mValue yet
            mHaveMultiLine = false;
          } else {
            mValue += Substring(aTokenStart, aCur);
          }

          mSpecialState = eParserSpecial_Escaped;
          break;

        case '\n':
          // if we detected multiline and got only "\\\r" ignore next "\n" if any
          if (mHaveMultiLine && mMultiLineCanSkipN) {
            // but don't allow another '\n' to be skipped
            mMultiLineCanSkipN = false;
            // Now there is nothing to append to the mValue since we are skipping
            // whitespaces at the beginning of the new line of the multiline
            // property. Set aTokenStart properly to ensure that nothing is appended
            // if we find regular line-end or the end of the buffer.
            aTokenStart = aCur + 1;
            break;
          }
        // no break

        case '\r':
          // we're done! We have a key and value
          mValue += Substring(aTokenStart, aCur);
          FinishValueState(aOldValue);
          mHaveMultiLine = false;
          break;

        default:
          // there is nothing to do with normal characters,
          // but handle multilines correctly
          if (mHaveMultiLine) {
            if (aChar == ' ' || aChar == '\t') {
              // don't allow another '\n' to be skipped
              mMultiLineCanSkipN = false;
              // Now there is nothing to append to the mValue since we are skipping
              // whitespaces at the beginning of the new line of the multiline
              // property. Set aTokenStart properly to ensure that nothing is appended
              // if we find regular line-end or the end of the buffer.
              aTokenStart = aCur + 1;
              break;
            }
            mHaveMultiLine = false;
            aTokenStart = aCur;
          }
          break; // from switch on (aChar)
      }
      break; // from switch on (mSpecialState)

    // saw a \ character, so parse the character after that
    case eParserSpecial_Escaped:
      // probably want to start parsing at the next token
      // other characters, like 'u' might override this
      aTokenStart = aCur + 1;
      mSpecialState = eParserSpecial_None;

      switch (aChar) {
        // the easy characters - \t, \n, and so forth
        case 't':
          mValue += char16_t('\t');
          mMinLength = mValue.Length();
          break;
        case 'n':
          mValue += char16_t('\n');
          mMinLength = mValue.Length();
          break;
        case 'r':
          mValue += char16_t('\r');
          mMinLength = mValue.Length();
          break;
        case '\\':
          mValue += char16_t('\\');
          break;

        // switch to unicode mode!
        case 'u':
        case 'U':
          mSpecialState = eParserSpecial_Unicode;
          mUnicodeValuesRead = 0;
          mUnicodeValue = 0;
          break;

        // a \ immediately followed by a newline means we're going multiline
        case '\r':
        case '\n':
          mHaveMultiLine = true;
          mMultiLineCanSkipN = (aChar == '\r');
          mSpecialState = eParserSpecial_None;
          break;

        default:
          // don't recognize the character, so just append it
          mValue += aChar;
          break;
      }
      break;

    // we're in the middle of parsing a 4-character unicode value
    // like \u5f39
    case eParserSpecial_Unicode:
      if ('0' <= aChar && aChar <= '9') {
        mUnicodeValue =
          (mUnicodeValue << 4) | (aChar - '0');
      } else if ('a' <= aChar && aChar <= 'f') {
        mUnicodeValue =
          (mUnicodeValue << 4) | (aChar - 'a' + 0x0a);
      } else if ('A' <= aChar && aChar <= 'F') {
        mUnicodeValue =
          (mUnicodeValue << 4) | (aChar - 'A' + 0x0a);
      } else {
        // non-hex character. Append what we have, and move on.
        mValue += mUnicodeValue;
        mMinLength = mValue.Length();
        mSpecialState = eParserSpecial_None;

        // leave aTokenStart at this unknown character, so it gets appended
        aTokenStart = aCur;

        // ensure parsing this non-hex character again
        return false;
      }

      if (++mUnicodeValuesRead >= 4) {
        aTokenStart = aCur + 1;
        mSpecialState = eParserSpecial_None;
        mValue += mUnicodeValue;
        mMinLength = mValue.Length();
      }

      break;
  }

  return true;
}
コード例 #23
0
nsresult
InternetCiter::Rewrap(const nsAString& aInString,
                      uint32_t aWrapCol,
                      uint32_t aFirstLineOffset,
                      bool aRespectNewlines,
                      nsAString& aOutString)
{
  // There shouldn't be returns in this string, only dom newlines.
  // Check to make sure:
#ifdef DEBUG
  int32_t cr = aInString.FindChar(char16_t('\r'));
  NS_ASSERTION((cr < 0), "Rewrap: CR in string gotten from DOM!\n");
#endif /* DEBUG */

  aOutString.Truncate();

  nsresult rv;

  RefPtr<mozilla::intl::LineBreaker> lineBreaker =
    mozilla::intl::LineBreaker::Create();
  MOZ_ASSERT(lineBreaker);

  // Loop over lines in the input string, rewrapping each one.
  uint32_t length;
  uint32_t posInString = 0;
  uint32_t outStringCol = 0;
  uint32_t citeLevel = 0;
  const nsPromiseFlatString &tString = PromiseFlatString(aInString);
  length = tString.Length();
  while (posInString < length) {
    // Get the new cite level here since we're at the beginning of a line
    uint32_t newCiteLevel = 0;
    while (posInString < length && tString[posInString] == gt) {
      ++newCiteLevel;
      ++posInString;
      while (posInString < length && tString[posInString] == space) {
        ++posInString;
      }
    }
    if (posInString >= length) {
      break;
    }

    // Special case: if this is a blank line, maintain a blank line
    // (retain the original paragraph breaks)
    if (tString[posInString] == nl && !aOutString.IsEmpty()) {
      if (aOutString.Last() != nl) {
        aOutString.Append(nl);
      }
      AddCite(aOutString, newCiteLevel);
      aOutString.Append(nl);

      ++posInString;
      outStringCol = 0;
      continue;
    }

    // If the cite level has changed, then start a new line with the
    // new cite level (but if we're at the beginning of the string,
    // don't bother).
    if (newCiteLevel != citeLevel && posInString > newCiteLevel+1 &&
        outStringCol) {
      BreakLine(aOutString, outStringCol, 0);
    }
    citeLevel = newCiteLevel;

    // Prepend the quote level to the out string if appropriate
    if (!outStringCol) {
      AddCite(aOutString, citeLevel);
      outStringCol = citeLevel + (citeLevel ? 1 : 0);
    }
    // If it's not a cite, and we're not at the beginning of a line in
    // the output string, add a space to separate new text from the
    // previous text.
    else if (outStringCol > citeLevel) {
      aOutString.Append(space);
      ++outStringCol;
    }

    // find the next newline -- don't want to go farther than that
    int32_t nextNewline = tString.FindChar(nl, posInString);
    if (nextNewline < 0) {
      nextNewline = length;
    }

    // For now, don't wrap unquoted lines at all.
    // This is because the plaintext edit window has already wrapped them
    // by the time we get them for rewrap, yet when we call the line
    // breaker, it will refuse to break backwards, and we'll end up
    // with a line that's too long and gets displayed as a lone word
    // on a line by itself.  Need special logic to detect this case
    // and break it ourselves without resorting to the line breaker.
    if (!citeLevel) {
      aOutString.Append(Substring(tString, posInString,
                                  nextNewline-posInString));
      outStringCol += nextNewline - posInString;
      if (nextNewline != (int32_t)length) {
        aOutString.Append(nl);
        outStringCol = 0;
      }
      posInString = nextNewline+1;
      continue;
    }

    // Otherwise we have to use the line breaker and loop
    // over this line of the input string to get all of it:
    while ((int32_t)posInString < nextNewline) {
      // Skip over initial spaces:
      while ((int32_t)posInString < nextNewline &&
             nsCRT::IsAsciiSpace(tString[posInString])) {
        ++posInString;
      }

      // If this is a short line, just append it and continue:
      if (outStringCol + nextNewline - posInString <= aWrapCol-citeLevel-1) {
        // If this short line is the final one in the in string,
        // then we need to include the final newline, if any:
        if (nextNewline+1 == (int32_t)length && tString[nextNewline-1] == nl) {
          ++nextNewline;
        }
        // Trim trailing spaces:
        int32_t lastRealChar = nextNewline;
        while ((uint32_t)lastRealChar > posInString &&
               nsCRT::IsAsciiSpace(tString[lastRealChar-1])) {
          --lastRealChar;
        }

        aOutString += Substring(tString,
                                posInString, lastRealChar - posInString);
        outStringCol += lastRealChar - posInString;
        posInString = nextNewline + 1;
        continue;
      }

      int32_t eol = posInString + aWrapCol - citeLevel - outStringCol;
      // eol is the prospective end of line.
      // We'll first look backwards from there for a place to break.
      // If it's already less than our current position,
      // then our line is already too long, so break now.
      if (eol <= (int32_t)posInString) {
        BreakLine(aOutString, outStringCol, citeLevel);
        continue;    // continue inner loop, with outStringCol now at bol
      }

      int32_t breakPt = 0;
      // XXX Why this uses NS_ERROR_"BASE"?
      rv = NS_ERROR_BASE;
      if (lineBreaker) {
        breakPt = lineBreaker->Prev(tString.get() + posInString,
                                 length - posInString, eol + 1 - posInString);
        if (breakPt == NS_LINEBREAKER_NEED_MORE_TEXT) {
          // if we couldn't find a breakpoint looking backwards,
          // and we're not starting a new line, then end this line
          // and loop around again:
          if (outStringCol > citeLevel + 1) {
            BreakLine(aOutString, outStringCol, citeLevel);
            continue;    // continue inner loop, with outStringCol now at bol
          }

          // Else try looking forwards:
          breakPt = lineBreaker->Next(tString.get() + posInString,
                                      length - posInString, eol - posInString);

          rv = breakPt == NS_LINEBREAKER_NEED_MORE_TEXT ? NS_ERROR_BASE :
                                                          NS_OK;
        } else {
          rv = NS_OK;
        }
      }
      // If rv is okay, then breakPt is the place to break.
      // If we get out here and rv is set, something went wrong with line
      // breaker.  Just break the line, hard.
      if (NS_FAILED(rv)) {
        breakPt = eol;
      }

      // Special case: maybe we should have wrapped last time.
      // If the first breakpoint here makes the current line too long,
      // then if we already have text on the current line,
      // break and loop around again.
      // If we're at the beginning of the current line, though,
      // don't force a break since the long word might be a url
      // and breaking it would make it unclickable on the other end.
      const int SLOP = 6;
      if (outStringCol + breakPt > aWrapCol + SLOP &&
          outStringCol > citeLevel+1) {
        BreakLine(aOutString, outStringCol, citeLevel);
        continue;
      }

      nsAutoString sub (Substring(tString, posInString, breakPt));
      // skip newlines or whitespace at the end of the string
      int32_t subend = sub.Length();
      while (subend > 0 && IsSpace(sub[subend-1])) {
        --subend;
      }
      sub.Left(sub, subend);
      aOutString += sub;
      outStringCol += sub.Length();
      // Advance past the whitespace which caused the wrap:
      posInString += breakPt;
      while (posInString < length && IsSpace(tString[posInString])) {
        ++posInString;
      }

      // Add a newline and the quote level to the out string
      if (posInString < length) {  // not for the last line, though
        BreakLine(aOutString, outStringCol, citeLevel);
      }
    } // end inner loop within one line of aInString
  } // end outer loop over lines of aInString

  return NS_OK;
}
コード例 #24
0
ファイル: nsMsgI18N.cpp プロジェクト: cmotc/spacehamster
nsresult nsMsgI18NConvertToUnicode(const char* aCharset,
                                   const nsCString& inString, 
                                   nsAString& outString,
                                   bool aIsCharsetCanonical)
{
  if (inString.IsEmpty()) {
    outString.Truncate();
    return NS_OK;
  }
  else if (!*aCharset || !PL_strcasecmp(aCharset, "us-ascii") ||
           !PL_strcasecmp(aCharset, "ISO-8859-1")) {
    // Despite its name, it also works for Latin-1.
    CopyASCIItoUTF16(inString, outString);
    return NS_OK;
  }
  else if (!PL_strcasecmp(aCharset, "UTF-8")) {
    if (MsgIsUTF8(inString)) {
      nsAutoString tmp;
      CopyUTF8toUTF16(inString, tmp);
      if (!tmp.IsEmpty() && tmp.First() == char16_t(0xFEFF))
        tmp.Cut(0, 1);
      outString.Assign(tmp);
      return NS_OK;
    }
    NS_WARNING("Invalid UTF-8 string");
    return NS_ERROR_UNEXPECTED;
  }

  nsresult rv;
  nsCOMPtr <nsICharsetConverterManager> ccm = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr <nsIUnicodeDecoder> decoder;

  // get an unicode converter
  if (aIsCharsetCanonical)  // optimize for modified UTF-7 used by IMAP
    rv = ccm->GetUnicodeDecoderRaw(aCharset, getter_AddRefs(decoder));
  else
    rv = ccm->GetUnicodeDecoderInternal(aCharset, getter_AddRefs(decoder));
  NS_ENSURE_SUCCESS(rv, rv);

  const char *originalSrcPtr = inString.get();
  const char *currentSrcPtr = originalSrcPtr;
  int32_t originalLength = inString.Length();
  int32_t srcLength;
  int32_t dstLength;
  char16_t localbuf[512];
  int32_t consumedLen = 0;

  outString.Truncate();

  // convert
  while (consumedLen < originalLength) {
    srcLength = originalLength - consumedLen;  
    dstLength = 512;
    rv = decoder->Convert(currentSrcPtr, &srcLength, localbuf, &dstLength);
    if (NS_FAILED(rv) || dstLength == 0)
      break;
    outString.Append(localbuf, dstLength);

    currentSrcPtr += srcLength;
    consumedLen = currentSrcPtr - originalSrcPtr; // src length used so far
  }
  return rv;
}
コード例 #25
0
nsresult
nsRDFXMLSerializer::SerializeProperty(nsIOutputStream* aStream,
                                      nsIRDFResource* aResource,
                                      nsIRDFResource* aProperty,
                                      bool aInline,
                                      int32_t* aSkipped)
{
    nsresult rv = NS_OK;

    int32_t skipped = 0;

    nsCOMPtr<nsISimpleEnumerator> assertions;
    mDataSource->GetTargets(aResource, aProperty, true, getter_AddRefs(assertions));
    if (! assertions)
        return NS_ERROR_FAILURE;

    // Serializing the assertion inline is ok as long as the property has
    // only one target value, and it is a literal that doesn't include line
    // breaks.
    bool needsChild = false;

    while (1) {
        bool hasMore = false;
        assertions->HasMoreElements(&hasMore);
        if (! hasMore)
            break;

        nsCOMPtr<nsISupports> isupports;
        assertions->GetNext(getter_AddRefs(isupports));
        nsCOMPtr<nsIRDFLiteral> literal = do_QueryInterface(isupports);
        needsChild |= (!literal);

        if (!needsChild) {
            assertions->HasMoreElements(&needsChild);
            if (!needsChild) {
                const char16_t* literalVal = nullptr;
                literal->GetValueConst(&literalVal);
                if (literalVal) {
                    for (; *literalVal; literalVal++) {
                        if (*literalVal == char16_t('\n') ||
                            *literalVal == char16_t('\r')) {
                            needsChild = true;
                            break;
                        }
                    }
                }
            }
        }

        if (aInline && !needsChild) {
            rv = SerializeInlineAssertion(aStream, aResource, aProperty, literal);
        }
        else if (!aInline && needsChild) {
            nsCOMPtr<nsIRDFNode> value = do_QueryInterface(isupports);
            rv = SerializeChildAssertion(aStream, aResource, aProperty, value);
        }
        else {
            ++skipped;
            rv = NS_OK;
        }

        if (NS_FAILED(rv))
            break;
    }

    *aSkipped += skipped;
    return rv;
}
void test_char16t(X<char16_t> x) {
    bool b = x == char16_t();
}
コード例 #27
0
NS_IMETHODIMP
nsIndexedToHTML::OnIndexAvailable(nsIRequest *aRequest,
                                  nsISupports *aCtxt,
                                  nsIDirIndex *aIndex) {
    nsresult rv;
    if (!aIndex)
        return NS_ERROR_NULL_POINTER;

    nsCString pushBuffer;
    pushBuffer.AppendLiteral("<tr");

    // We don't know the file's character set yet, so retrieve the raw bytes
    // which will be decoded by the HTML parser.
    nsXPIDLCString loc;
    aIndex->GetLocation(getter_Copies(loc));

    // Adjust the length in case unescaping shortened the string.
    loc.Truncate(nsUnescapeCount(loc.BeginWriting()));
    if (loc.First() == char16_t('.'))
        pushBuffer.AppendLiteral(" class=\"hidden-object\"");

    pushBuffer.AppendLiteral(">\n <td sortable-data=\"");

    // The sort key is the name of the item, prepended by either 0, 1 or 2
    // in order to group items.
    uint32_t type;
    aIndex->GetType(&type);
    switch (type) {
        case nsIDirIndex::TYPE_SYMLINK:
            pushBuffer.Append('0');
            break;
        case nsIDirIndex::TYPE_DIRECTORY:
            pushBuffer.Append('1');
            break;
        default:
            pushBuffer.Append('2');
            break;
    }
    nsAdoptingCString escaped(nsEscapeHTML(loc));
    pushBuffer.Append(escaped);

    pushBuffer.AppendLiteral("\"><table class=\"ellipsis\"><tbody><tr><td><a class=\"");
    switch (type) {
        case nsIDirIndex::TYPE_DIRECTORY:
            pushBuffer.AppendLiteral("dir");
            break;
        case nsIDirIndex::TYPE_SYMLINK:
            pushBuffer.AppendLiteral("symlink");
            break;
        default:
            pushBuffer.AppendLiteral("file");
            break;
    }

    pushBuffer.AppendLiteral("\" href=\"");

    // need to escape links
    nsAutoCString locEscaped;

    // Adding trailing slash helps to recognize whether the URL points to a file
    // or a directory (bug #214405).
    if ((type == nsIDirIndex::TYPE_DIRECTORY) && (loc.Last() != '/')) {
        loc.Append('/');
    }

    // now minimally re-escape the location...
    uint32_t escFlags;
    // for some protocols, we expect the location to be absolute.
    // if so, and if the location indeed appears to be a valid URI, then go
    // ahead and treat it like one.

    nsAutoCString scheme;
    if (mExpectAbsLoc &&
        NS_SUCCEEDED(net_ExtractURLScheme(loc, scheme))) {
        // escape as absolute 
        escFlags = esc_Forced | esc_AlwaysCopy | esc_Minimal;
    }
    else {
        // escape as relative
        // esc_Directory is needed because directories have a trailing slash.
        // Without it, the trailing '/' will be escaped, and links from within
        // that directory will be incorrect
        escFlags = esc_Forced | esc_AlwaysCopy | esc_FileBaseName | esc_Colon | esc_Directory;
    }
    NS_EscapeURL(loc.get(), loc.Length(), escFlags, locEscaped);
    // esc_Directory does not escape the semicolons, so if a filename
    // contains semicolons we need to manually escape them.
    // This replacement should be removed in bug #473280
    locEscaped.ReplaceSubstring(";", "%3b");
    nsAdoptingCString htmlEscapedURL(nsEscapeHTML(locEscaped.get()));
    pushBuffer.Append(htmlEscapedURL);

    pushBuffer.AppendLiteral("\">");

    if (type == nsIDirIndex::TYPE_FILE || type == nsIDirIndex::TYPE_UNKNOWN) {
        pushBuffer.AppendLiteral("<img src=\"moz-icon://");
        int32_t lastDot = locEscaped.RFindChar('.');
        if (lastDot != kNotFound) {
            locEscaped.Cut(0, lastDot);
            nsAdoptingCString htmlFileExt(nsEscapeHTML(locEscaped.get()));
            pushBuffer.Append(htmlFileExt);
        } else {
            pushBuffer.AppendLiteral("unknown");
        }
        pushBuffer.AppendLiteral("?size=16\" alt=\"");

        nsXPIDLString altText;
        rv = mBundle->GetStringFromName(MOZ_UTF16("DirFileLabel"),
                                        getter_Copies(altText));
        if (NS_FAILED(rv)) return rv;
        AppendNonAsciiToNCR(altText, pushBuffer);
        pushBuffer.AppendLiteral("\">");
    }

    pushBuffer.Append(escaped);
    pushBuffer.AppendLiteral("</a></td></tr></tbody></table></td>\n <td");

    if (type == nsIDirIndex::TYPE_DIRECTORY || type == nsIDirIndex::TYPE_SYMLINK) {
        pushBuffer.Append('>');
    } else {
        int64_t size;
        aIndex->GetSize(&size);

        if (uint64_t(size) != UINT64_MAX) {
            pushBuffer.AppendLiteral(" sortable-data=\"");
            pushBuffer.AppendInt(size);
            pushBuffer.AppendLiteral("\">");
            nsAutoCString sizeString;
            FormatSizeString(size, sizeString);
            pushBuffer.Append(sizeString);
        } else {
            pushBuffer.Append('>');
        }
    }
    pushBuffer.AppendLiteral("</td>\n <td");

    PRTime t;
    aIndex->GetLastModified(&t);

    if (t == -1LL) {
        pushBuffer.AppendLiteral("></td>\n <td>");
    } else {
        pushBuffer.AppendLiteral(" sortable-data=\"");
        pushBuffer.AppendInt(static_cast<int64_t>(t));
        pushBuffer.AppendLiteral("\">");
        nsAutoString formatted;
        mDateTime->FormatPRTime(nullptr,
                                kDateFormatShort,
                                kTimeFormatNone,
                                t,
                                formatted);
        AppendNonAsciiToNCR(formatted, pushBuffer);
        pushBuffer.AppendLiteral("</td>\n <td>");
        mDateTime->FormatPRTime(nullptr,
                                kDateFormatNone,
                                kTimeFormatSeconds,
                                t,
                                formatted);
        // use NCR to show date in any doc charset
        AppendNonAsciiToNCR(formatted, pushBuffer);
    }

    pushBuffer.AppendLiteral("</td>\n</tr>");

    return SendToListener(aRequest, aCtxt, pushBuffer);
}
コード例 #28
0
nsresult nsMsgSearchAdapter::EncodeImapTerm(nsIMsgSearchTerm *term,
                                            bool reallyDredd,
                                            const char16_t *srcCharset,
                                            const char16_t *destCharset,
                                            char **ppOutTerm) {
  NS_ENSURE_ARG_POINTER(term);
  NS_ENSURE_ARG_POINTER(ppOutTerm);

  nsresult err = NS_OK;
  bool useNot = false;
  bool useQuotes = false;
  bool ignoreValue = false;
  nsAutoCString arbitraryHeader;
  const char *whichMnemonic = nullptr;
  const char *orHeaderMnemonic = nullptr;

  *ppOutTerm = nullptr;

  nsCOMPtr<nsIMsgSearchValue> searchValue;
  nsresult rv = term->GetValue(getter_AddRefs(searchValue));

  NS_ENSURE_SUCCESS(rv, rv);

  nsMsgSearchOpValue op;
  term->GetOp(&op);

  if (op == nsMsgSearchOp::DoesntContain || op == nsMsgSearchOp::Isnt)
    useNot = true;

  nsMsgSearchAttribValue attrib;
  term->GetAttrib(&attrib);

  switch (attrib) {
    case nsMsgSearchAttrib::ToOrCC:
      orHeaderMnemonic = m_kImapCC;
      // fall through to case nsMsgSearchAttrib::To:
      MOZ_FALLTHROUGH;
    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!
      {
        // If we have a future date, the > and < are reversed.
        // e.g. ageInDays > 2 means more than 2 days old ("date before X")
        // whereas
        //      ageInDays > -2 should be more than 2 days in the future ("date
        //      after X")
        int32_t ageInDays;
        searchValue->GetAge(&ageInDays);
        bool dateInFuture = (ageInDays < 0);
        switch (op) {
          case nsMsgSearchOp::IsGreaterThan:
            whichMnemonic = (!dateInFuture) ? m_kImapBefore : m_kImapSince;
            break;
          case nsMsgSearchOp::IsLessThan:
            whichMnemonic = (!dateInFuture) ? m_kImapSince : m_kImapBefore;
            break;
          case nsMsgSearchOp::Is:
            whichMnemonic = m_kImapSentOn;
            break;
          default:
            NS_ASSERTION(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(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(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 = false;      // bizarrely, NOT SEEN is wrong, but UNSEEN is right.
      ignoreValue = true;  // the mnemonic is all we need
      uint32_t status;
      searchValue->GetStatus(&status);

      switch (status) {
        case nsMsgMessageFlags::Read:
          whichMnemonic =
              op == nsMsgSearchOp::Is ? m_kImapSeen : m_kImapNotSeen;
          break;
        case nsMsgMessageFlags::Replied:
          whichMnemonic =
              op == nsMsgSearchOp::Is ? m_kImapAnswered : m_kImapNotAnswered;
          break;
        case nsMsgMessageFlags::New:
          whichMnemonic = op == nsMsgSearchOp::Is ? m_kImapNew : m_kImapNotNew;
          break;
        case nsMsgMessageFlags::Marked:
          whichMnemonic =
              op == nsMsgSearchOp::Is ? m_kImapFlagged : m_kImapNotFlagged;
          break;
        default:
          NS_ASSERTION(false, "invalid search operator");
          return NS_ERROR_INVALID_ARG;
      }
      break;
    default:
      if (attrib > nsMsgSearchAttrib::OtherHeader &&
          attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes) {
        nsCString arbitraryHeaderTerm;
        term->GetArbitraryHeader(arbitraryHeaderTerm);
        if (!arbitraryHeaderTerm.IsEmpty()) {
          arbitraryHeader.AssignLiteral(" \"");
          arbitraryHeader.Append(arbitraryHeaderTerm);
          arbitraryHeader.AppendLiteral("\" ");
          whichMnemonic = arbitraryHeader.get();
        } else
          return NS_ERROR_FAILURE;
      } else {
        NS_ASSERTION(false, "invalid search operator");
        return NS_ERROR_INVALID_ARG;
      }
  }

  char *value = nullptr;
  char dateBuf[100];
  dateBuf[0] = '\0';

  bool valueWasAllocated = 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.
      adjustedDate += PR_USEC_PER_DAY;
    }

    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.
      int32_t ageInDays;

      searchValue->GetAge(&ageInDays);

      PRTime now = PR_Now();
      PRTime matchDay = now - ageInDays * PR_USEC_PER_DAY;

      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) {
      uint32_t sizeValue;
      nsAutoCString 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 = ToNewCString(searchTermValue);
      valueWasAllocated = true;
    } else

        if (IS_STRING_ATTRIBUTE(attrib)) {
      char16_t *
          convertedValue;  // = reallyDredd ? MSG_EscapeSearchUrl
                           // (term->m_value.u.string) :
                           // msg_EscapeImapSearchProtocol(term->m_value.u.string);
      nsString searchTermValue;
      searchValue->GetStr(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.get())
                           : EscapeImapSearchProtocol(searchTermValue.get());
      useQuotes =
          ((!reallyDredd ||
            (nsDependentString(convertedValue).FindChar(char16_t(' ')) !=
             -1)) &&
           (attrib != nsMsgSearchAttrib::Keywords));
      // now convert to char* and escape quoted_specials
      nsAutoCString valueStr;
      nsresult rv = nsMsgI18NConvertFromUnicode(
          NS_LossyConvertUTF16toASCII(destCharset),
          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.
        mozilla::UniquePtr<char[]> newValue =
            mozilla::MakeUnique<char[]>(2 * strlen(vptr) + 1);
        if (newValue) {
          char *p = newValue.get();
          while (1) {
            char ch = *vptr++;
            if (!ch) break;
            if ((useQuotes ? ch == '"' : 0) || ch == '\\') *p++ = '\\';
            *p++ = ch;
          }
          *p = '\0';
          value = strdup(newValue.get());  // realloc down to smaller size
        }
      } else
        value = strdup("");
      free(convertedValue);
      valueWasAllocated = true;
    }
  }

  // this should be rewritten to use nsCString
  int subLen = (value ? strlen(value) : 0) + (useNot ? strlen(m_kImapNot) : 0) +
               strlen(m_kImapHeader);
  int len =
      strlen(whichMnemonic) + subLen + (useQuotes ? 2 : 0) +
      (orHeaderMnemonic
           ? (subLen + strlen(m_kImapOr) + strlen(orHeaderMnemonic) + 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) free(value);

  *ppOutTerm = encoding;

  return err;
}
コード例 #29
0
ファイル: Helpers.cpp プロジェクト: ppbao/mozilla-os2
void
GetReversedHostname(const nsString& aForward, nsString& aRevHost)
{
  ReverseString(aForward, aRevHost);
  aRevHost.Append(char16_t('.'));
}
コード例 #30
0
ファイル: nsExpatDriver.cpp プロジェクト: cbrem/gecko-dev
int
nsExpatDriver::HandleExternalEntityRef(const char16_t *openEntityNames,
                                       const char16_t *base,
                                       const char16_t *systemId,
                                       const char16_t *publicId)
{
  if (mInInternalSubset && !mInExternalDTD && openEntityNames) {
    mInternalSubset.Append(char16_t('%'));
    mInternalSubset.Append(nsDependentString(openEntityNames));
    mInternalSubset.Append(char16_t(';'));
  }

  // Load the external entity into a buffer.
  nsCOMPtr<nsIInputStream> in;
  nsAutoString absURL;
  nsresult rv = OpenInputStreamFromExternalDTD(publicId, systemId, base,
                                               getter_AddRefs(in), absURL);
  if (NS_FAILED(rv)) {
#ifdef DEBUG
    nsCString message("Failed to open external DTD: publicId \"");
    AppendUTF16toUTF8(publicId, message);
    message += "\" systemId \"";
    AppendUTF16toUTF8(systemId, message);
    message += "\" base \"";
    AppendUTF16toUTF8(base, message);
    message += "\" URL \"";
    AppendUTF16toUTF8(absURL, message);
    message += "\"";
    NS_WARNING(message.get());
#endif
    return 1;
  }

  nsCOMPtr<nsIUnicharInputStream> uniIn;
  rv = nsSimpleUnicharStreamFactory::GetInstance()->
    CreateInstanceFromUTF8Stream(in, getter_AddRefs(uniIn));
  NS_ENSURE_SUCCESS(rv, 1);

  int result = 1;
  if (uniIn) {
    XML_Parser entParser = XML_ExternalEntityParserCreate(mExpatParser, 0,
                                                          kUTF16);
    if (entParser) {
      XML_SetBase(entParser, absURL.get());

      mInExternalDTD = true;

      uint32_t totalRead;
      do {
        rv = uniIn->ReadSegments(ExternalDTDStreamReaderFunc, entParser,
                                 uint32_t(-1), &totalRead);
      } while (NS_SUCCEEDED(rv) && totalRead > 0);

      result = XML_Parse(entParser, nullptr, 0, 1);

      mInExternalDTD = false;

      XML_ParserFree(entParser);
    }
  }

  return result;
}