parser/xml/src/nsSAXXMLReader.cpp

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsIInputStream.h"
     7 #include "nsNetCID.h"
     8 #include "nsNetUtil.h"
     9 #include "nsIParser.h"
    10 #include "nsParserCIID.h"
    11 #include "nsStreamUtils.h"
    12 #include "nsStringStream.h"
    13 #include "nsIScriptError.h"
    14 #include "nsSAXAttributes.h"
    15 #include "nsSAXLocator.h"
    16 #include "nsSAXXMLReader.h"
    17 #include "nsCharsetSource.h"
    19 #include "mozilla/dom/EncodingUtils.h"
    21 using mozilla::dom::EncodingUtils;
    23 #define XMLNS_URI "http://www.w3.org/2000/xmlns/"
    25 static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
    27 NS_IMPL_CYCLE_COLLECTION(nsSAXXMLReader,
    28                          mContentHandler,
    29                          mDTDHandler,
    30                          mErrorHandler,
    31                          mLexicalHandler,
    32                          mDeclarationHandler,
    33                          mBaseURI,
    34                          mListener,
    35                          mParserObserver)
    36 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSAXXMLReader)
    37 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSAXXMLReader)
    38 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSAXXMLReader)
    39   NS_INTERFACE_MAP_ENTRY(nsISAXXMLReader)
    40   NS_INTERFACE_MAP_ENTRY(nsIExpatSink)
    41   NS_INTERFACE_MAP_ENTRY(nsIExtendedExpatSink)
    42   NS_INTERFACE_MAP_ENTRY(nsIContentSink)
    43   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
    44   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
    45   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISAXXMLReader)
    46 NS_INTERFACE_MAP_END
    48 nsSAXXMLReader::nsSAXXMLReader() :
    49     mIsAsyncParse(false),
    50     mEnableNamespacePrefixes(false)
    51 {
    52 }
    54 // nsIContentSink
    55 NS_IMETHODIMP
    56 nsSAXXMLReader::WillBuildModel(nsDTDMode)
    57 {
    58   if (mContentHandler)
    59     return mContentHandler->StartDocument();
    61   return NS_OK;
    62 }
    64 NS_IMETHODIMP
    65 nsSAXXMLReader::DidBuildModel(bool aTerminated)
    66 {
    67   if (mContentHandler)
    68     return mContentHandler->EndDocument();
    70   return NS_OK;
    71 }
    73 NS_IMETHODIMP
    74 nsSAXXMLReader::SetParser(nsParserBase *aParser)
    75 {
    76   return NS_OK;
    77 }
    79 // nsIExtendedExpatSink
    80 NS_IMETHODIMP
    81 nsSAXXMLReader::HandleStartElement(const char16_t *aName,
    82                                    const char16_t **aAtts,
    83                                    uint32_t aAttsCount,
    84                                    int32_t aIndex,
    85                                    uint32_t aLineNumber)
    86 {
    87   if (!mContentHandler)
    88     return NS_OK;
    90   nsRefPtr<nsSAXAttributes> atts = new nsSAXAttributes();
    91   if (!atts)
    92     return NS_ERROR_OUT_OF_MEMORY;
    93   nsAutoString uri, localName, qName;
    94   for (; *aAtts; aAtts += 2) {
    95     SplitExpatName(aAtts[0], uri, localName, qName);
    96     // XXX don't have attr type information
    97     NS_NAMED_LITERAL_STRING(cdataType, "CDATA");
    98     // could support xmlns reporting, it's a standard SAX feature
    99     if (mEnableNamespacePrefixes || !uri.EqualsLiteral(XMLNS_URI)) {
   100       NS_ASSERTION(aAtts[1], "null passed to handler");
   101       atts->AddAttribute(uri, localName, qName, cdataType,
   102                          nsDependentString(aAtts[1]));
   103     }
   104   }
   106   // Deal with the element name
   107   SplitExpatName(aName, uri, localName, qName);
   108   return mContentHandler->StartElement(uri, localName, qName, atts);
   109 }
   111 NS_IMETHODIMP
   112 nsSAXXMLReader::HandleEndElement(const char16_t *aName)
   113 {
   114   if (mContentHandler) {
   115     nsAutoString uri, localName, qName;
   116     SplitExpatName(aName, uri, localName, qName);
   117     return mContentHandler->EndElement(uri, localName, qName);
   118   }
   119   return NS_OK;
   120 }
   122 NS_IMETHODIMP
   123 nsSAXXMLReader::HandleComment(const char16_t *aName)
   124 {
   125   NS_ASSERTION(aName, "null passed to handler");
   126   if (mLexicalHandler)
   127     return mLexicalHandler->Comment(nsDependentString(aName));
   129   return NS_OK;
   130 }
   132 NS_IMETHODIMP
   133 nsSAXXMLReader::HandleCDataSection(const char16_t *aData,
   134                                    uint32_t aLength)
   135 {
   136   nsresult rv;
   137   if (mLexicalHandler) {
   138     rv = mLexicalHandler->StartCDATA();
   139     NS_ENSURE_SUCCESS(rv, rv);
   140   }
   142   if (mContentHandler) {
   143     rv = mContentHandler->Characters(Substring(aData, aData+aLength));
   144     NS_ENSURE_SUCCESS(rv, rv);
   145   }
   147   if (mLexicalHandler) {
   148     rv = mLexicalHandler->EndCDATA();
   149     NS_ENSURE_SUCCESS(rv, rv);
   150   }
   152   return NS_OK;
   153 }
   155 NS_IMETHODIMP
   156 nsSAXXMLReader::HandleStartDTD(const char16_t *aName,
   157                                const char16_t *aSystemId,
   158                                const char16_t *aPublicId)
   159 {
   160   char16_t nullChar = char16_t(0);
   161   if (!aName)
   162     aName = &nullChar;
   163   if (!aSystemId)
   164     aSystemId = &nullChar;
   165   if (!aPublicId)
   166     aPublicId = &nullChar;
   168   mSystemId = aSystemId;
   169   mPublicId = aPublicId;
   170   if (mLexicalHandler) {
   171     return mLexicalHandler->StartDTD(nsDependentString(aName),
   172                                      nsDependentString(aPublicId),
   173                                      nsDependentString(aSystemId));
   174   }
   176   return NS_OK;
   177 }
   179 NS_IMETHODIMP
   180 nsSAXXMLReader::HandleDoctypeDecl(const nsAString & aSubset,
   181                                   const nsAString & aName,
   182                                   const nsAString & aSystemId,
   183                                   const nsAString & aPublicId,
   184                                   nsISupports* aCatalogData)
   185 {
   186   if (mLexicalHandler)
   187     return mLexicalHandler->EndDTD();
   189   return NS_OK;
   190 }
   192 NS_IMETHODIMP
   193 nsSAXXMLReader::HandleCharacterData(const char16_t *aData,
   194                                     uint32_t aLength)
   195 {
   196   if (mContentHandler)
   197     return mContentHandler->Characters(Substring(aData, aData+aLength));
   199   return NS_OK;
   200 }
   202 NS_IMETHODIMP
   203 nsSAXXMLReader::HandleStartNamespaceDecl(const char16_t *aPrefix,
   204                                          const char16_t *aUri)
   205 {
   206   if (!mContentHandler)
   207     return NS_OK;
   209   char16_t nullChar = char16_t(0);
   210   if (!aPrefix)
   211     aPrefix = &nullChar;
   212   if (!aUri)
   213     aUri = &nullChar;
   215   return mContentHandler->StartPrefixMapping(nsDependentString(aPrefix),
   216                                              nsDependentString(aUri));
   217 }
   219 NS_IMETHODIMP
   220 nsSAXXMLReader::HandleEndNamespaceDecl(const char16_t *aPrefix)
   221 {
   222   if (!mContentHandler)
   223     return NS_OK;
   225   if (aPrefix)
   226     return mContentHandler->EndPrefixMapping(nsDependentString(aPrefix));
   228   return mContentHandler->EndPrefixMapping(EmptyString());
   229 }
   231 NS_IMETHODIMP
   232 nsSAXXMLReader::HandleProcessingInstruction(const char16_t *aTarget,
   233                                             const char16_t *aData)
   234 {
   235   NS_ASSERTION(aTarget && aData, "null passed to handler");
   236   if (mContentHandler) {
   237     return mContentHandler->ProcessingInstruction(nsDependentString(aTarget),
   238                                                   nsDependentString(aData));
   239   }
   241   return NS_OK;
   242 }
   244 NS_IMETHODIMP
   245 nsSAXXMLReader::HandleNotationDecl(const char16_t *aNotationName,
   246                                    const char16_t *aSystemId,
   247                                    const char16_t *aPublicId)
   248 {
   249   NS_ASSERTION(aNotationName, "null passed to handler");
   250   if (mDTDHandler) {
   251     char16_t nullChar = char16_t(0);
   252     if (!aSystemId)
   253       aSystemId = &nullChar;
   254     if (!aPublicId)
   255       aPublicId = &nullChar;
   257     return mDTDHandler->NotationDecl(nsDependentString(aNotationName),
   258                                      nsDependentString(aSystemId),
   259                                      nsDependentString(aPublicId));
   260   }
   262   return NS_OK;
   263 }
   265 NS_IMETHODIMP
   266 nsSAXXMLReader::HandleUnparsedEntityDecl(const char16_t *aEntityName,
   267                                          const char16_t *aSystemId,
   268                                          const char16_t *aPublicId,
   269                                          const char16_t *aNotationName)
   270 {
   271   NS_ASSERTION(aEntityName && aNotationName, "null passed to handler");
   272   if (mDTDHandler) {
   273     char16_t nullChar = char16_t(0);
   274     if (!aSystemId)
   275       aSystemId = &nullChar;
   276     if (!aPublicId)
   277       aPublicId = &nullChar;
   279     return mDTDHandler->UnparsedEntityDecl(nsDependentString(aEntityName),
   280                                            nsDependentString(aSystemId),
   281                                            nsDependentString(aPublicId),
   282                                            nsDependentString(aNotationName));
   283   }
   285   return NS_OK;
   286 }
   288 NS_IMETHODIMP
   289 nsSAXXMLReader::HandleXMLDeclaration(const char16_t *aVersion,
   290                                      const char16_t *aEncoding,
   291                                      int32_t aStandalone)
   292 {
   293   NS_ASSERTION(aVersion, "null passed to handler");
   294   if (mDeclarationHandler) {
   295     char16_t nullChar = char16_t(0);
   296     if (!aEncoding)
   297       aEncoding = &nullChar;
   298     mDeclarationHandler->HandleXMLDeclaration(nsDependentString(aVersion),
   299                                               nsDependentString(aEncoding),
   300                                               aStandalone > 0);
   301   }
   302   return NS_OK;
   303 }
   305 NS_IMETHODIMP
   306 nsSAXXMLReader::ReportError(const char16_t* aErrorText,
   307                             const char16_t* aSourceText,
   308                             nsIScriptError *aError,
   309                             bool *_retval)
   310 {
   311   NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!");
   312   // Normally, the expat driver should report the error.
   313   *_retval = true;
   315   if (mErrorHandler) {
   316     uint32_t lineNumber;
   317     nsresult rv = aError->GetLineNumber(&lineNumber);
   318     NS_ENSURE_SUCCESS(rv, rv);
   320     uint32_t columnNumber;
   321     rv = aError->GetColumnNumber(&columnNumber);
   322     NS_ENSURE_SUCCESS(rv, rv);
   324     nsCOMPtr<nsISAXLocator> locator = new nsSAXLocator(mPublicId,
   325                                                        mSystemId,
   326                                                        lineNumber,
   327                                                        columnNumber);
   328     if (!locator)
   329       return NS_ERROR_OUT_OF_MEMORY;
   331     rv = mErrorHandler->FatalError(locator, nsDependentString(aErrorText));
   332     if (NS_SUCCEEDED(rv)) {
   333       // The error handler has handled the script error.  Don't log to console.
   334       *_retval = false;
   335     }
   336   }
   338   return NS_OK;
   339 }
   341 // nsISAXXMLReader
   343 NS_IMETHODIMP
   344 nsSAXXMLReader::GetBaseURI(nsIURI **aBaseURI)
   345 {
   346   NS_IF_ADDREF(*aBaseURI = mBaseURI);
   347   return NS_OK;
   348 }
   350 NS_IMETHODIMP
   351 nsSAXXMLReader::SetBaseURI(nsIURI *aBaseURI)
   352 {
   353   mBaseURI = aBaseURI;
   354   return NS_OK;
   355 }
   357 NS_IMETHODIMP
   358 nsSAXXMLReader::GetContentHandler(nsISAXContentHandler **aContentHandler)
   359 {
   360   NS_IF_ADDREF(*aContentHandler = mContentHandler);
   361   return NS_OK;
   362 }
   364 NS_IMETHODIMP
   365 nsSAXXMLReader::SetContentHandler(nsISAXContentHandler *aContentHandler)
   366 {
   367   mContentHandler = aContentHandler;
   368   return NS_OK;
   369 }
   371 NS_IMETHODIMP
   372 nsSAXXMLReader::GetDtdHandler(nsISAXDTDHandler **aDtdHandler)
   373 {
   374   NS_IF_ADDREF(*aDtdHandler = mDTDHandler);
   375   return NS_OK;
   376 }
   378 NS_IMETHODIMP
   379 nsSAXXMLReader::SetDtdHandler(nsISAXDTDHandler *aDtdHandler)
   380 {
   381   mDTDHandler = aDtdHandler;
   382   return NS_OK;
   383 }
   385 NS_IMETHODIMP
   386 nsSAXXMLReader::GetErrorHandler(nsISAXErrorHandler **aErrorHandler)
   387 {
   388   NS_IF_ADDREF(*aErrorHandler = mErrorHandler);
   389   return NS_OK;
   390 }
   392 NS_IMETHODIMP
   393 nsSAXXMLReader::SetErrorHandler(nsISAXErrorHandler *aErrorHandler)
   394 {
   395   mErrorHandler = aErrorHandler;
   396   return NS_OK;
   397 }
   399 NS_IMETHODIMP
   400 nsSAXXMLReader::SetFeature(const nsAString &aName, bool aValue)
   401 {
   402   if (aName.EqualsLiteral("http://xml.org/sax/features/namespace-prefixes")) {
   403     mEnableNamespacePrefixes = aValue;
   404     return NS_OK;
   405   }
   406   return NS_ERROR_NOT_IMPLEMENTED;
   407 }
   409 NS_IMETHODIMP
   410 nsSAXXMLReader::GetFeature(const nsAString &aName, bool *aResult)
   411 {
   412   if (aName.EqualsLiteral("http://xml.org/sax/features/namespace-prefixes")) {
   413     *aResult = mEnableNamespacePrefixes;
   414     return NS_OK;
   415   }
   416   return NS_ERROR_NOT_IMPLEMENTED;
   417 }
   419 NS_IMETHODIMP
   420 nsSAXXMLReader::GetDeclarationHandler(nsIMozSAXXMLDeclarationHandler **aDeclarationHandler) {
   421   NS_IF_ADDREF(*aDeclarationHandler = mDeclarationHandler);
   422   return NS_OK;
   423 }
   425 NS_IMETHODIMP
   426 nsSAXXMLReader::SetDeclarationHandler(nsIMozSAXXMLDeclarationHandler *aDeclarationHandler) {
   427   mDeclarationHandler = aDeclarationHandler;
   428   return NS_OK;
   429 }
   431 NS_IMETHODIMP
   432 nsSAXXMLReader::GetLexicalHandler(nsISAXLexicalHandler **aLexicalHandler)
   433 {
   434   NS_IF_ADDREF(*aLexicalHandler = mLexicalHandler);
   435   return NS_OK;
   436 }
   438 NS_IMETHODIMP
   439 nsSAXXMLReader::SetLexicalHandler(nsISAXLexicalHandler *aLexicalHandler)
   440 {
   441   mLexicalHandler = aLexicalHandler;
   442   return NS_OK;
   443 }
   445 NS_IMETHODIMP
   446 nsSAXXMLReader::SetProperty(const nsAString &aName, nsISupports* aValue)
   447 {
   448   return NS_ERROR_NOT_IMPLEMENTED;
   449 }
   451 NS_IMETHODIMP
   452 nsSAXXMLReader::GetProperty(const nsAString &aName, bool *aResult)
   453 {
   454   return NS_ERROR_NOT_IMPLEMENTED;
   455 }
   457 NS_IMETHODIMP
   458 nsSAXXMLReader::ParseFromString(const nsAString &aStr,
   459                                 const char *aContentType)
   460 {
   461   // Don't call this in the middle of an async parse
   462   NS_ENSURE_TRUE(!mIsAsyncParse, NS_ERROR_FAILURE);
   464   NS_ConvertUTF16toUTF8 data(aStr);
   466   // The new stream holds a reference to the buffer
   467   nsCOMPtr<nsIInputStream> stream;
   468   nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream),
   469                                       data.get(), data.Length(),
   470                                       NS_ASSIGNMENT_DEPEND);
   471   NS_ENSURE_SUCCESS(rv, rv);
   472   return ParseFromStream(stream, "UTF-8", aContentType);
   473 }
   475 NS_IMETHODIMP
   476 nsSAXXMLReader::ParseFromStream(nsIInputStream *aStream,
   477                                 const char *aCharset,
   478                                 const char *aContentType)
   479 {
   480   // Don't call this in the middle of an async parse
   481   NS_ENSURE_TRUE(!mIsAsyncParse, NS_ERROR_FAILURE);
   483   NS_ENSURE_ARG(aStream);
   484   NS_ENSURE_ARG(aContentType);
   486   // Put the nsCOMPtr out here so we hold a ref to the stream as needed
   487   nsresult rv;
   488   nsCOMPtr<nsIInputStream> bufferedStream;
   489   if (!NS_InputStreamIsBuffered(aStream)) {
   490     rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
   491                                    aStream, 4096);
   492     NS_ENSURE_SUCCESS(rv, rv);
   493     aStream = bufferedStream;
   494   }
   496   rv = EnsureBaseURI();
   497   NS_ENSURE_SUCCESS(rv, rv);
   499   nsCOMPtr<nsIChannel> parserChannel;
   500   rv = NS_NewInputStreamChannel(getter_AddRefs(parserChannel), mBaseURI,
   501                                 aStream, nsDependentCString(aContentType));
   502   if (!parserChannel || NS_FAILED(rv))
   503     return NS_ERROR_FAILURE;
   505   if (aCharset)
   506     parserChannel->SetContentCharset(nsDependentCString(aCharset));
   508   rv = InitParser(nullptr, parserChannel);
   509   NS_ENSURE_SUCCESS(rv, rv);
   511   rv = mListener->OnStartRequest(parserChannel, nullptr);
   512   if (NS_FAILED(rv))
   513     parserChannel->Cancel(rv);
   515   /* When parsing a new document, we need to clear the XML identifiers.
   516      HandleStartDTD will set these values from the DTD declaration tag.
   517      We won't have them, of course, if there's a well-formedness error
   518      before the DTD tag (such as a space before an XML declaration).
   519    */
   520   mSystemId.Truncate();
   521   mPublicId.Truncate();
   523   nsresult status;
   524   parserChannel->GetStatus(&status);
   526   uint64_t offset = 0;
   527   while (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
   528     uint64_t available;
   529     rv = aStream->Available(&available);
   530     if (rv == NS_BASE_STREAM_CLOSED) {
   531       rv = NS_OK;
   532       available = 0;
   533     }
   534     if (NS_FAILED(rv)) {
   535       parserChannel->Cancel(rv);
   536       break;
   537     }
   538     if (! available)
   539       break; // blocking input stream has none available when done
   541     if (available > UINT32_MAX)
   542       available = UINT32_MAX;
   544     rv = mListener->OnDataAvailable(parserChannel, nullptr,
   545                                     aStream,
   546                                     offset,
   547                                     (uint32_t)available);
   548     if (NS_SUCCEEDED(rv))
   549       offset += available;
   550     else
   551       parserChannel->Cancel(rv);
   552     parserChannel->GetStatus(&status);
   553   }
   554   rv = mListener->OnStopRequest(parserChannel, nullptr, status);
   555   mListener = nullptr;
   557   return rv;
   558 }
   560 NS_IMETHODIMP
   561 nsSAXXMLReader::ParseAsync(nsIRequestObserver *aObserver)
   562 {
   563   mParserObserver = aObserver;
   564   mIsAsyncParse = true;
   565   return NS_OK;
   566 }
   568 // nsIRequestObserver
   570 NS_IMETHODIMP
   571 nsSAXXMLReader::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
   572 {
   573   NS_ENSURE_TRUE(mIsAsyncParse, NS_ERROR_FAILURE);
   574   nsresult rv;
   575   rv = EnsureBaseURI();
   576   NS_ENSURE_SUCCESS(rv, rv);
   577   nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
   578   rv = InitParser(mParserObserver, channel);
   579   NS_ENSURE_SUCCESS(rv, rv);
   580   // we don't need or want this anymore
   581   mParserObserver = nullptr;
   582   return mListener->OnStartRequest(aRequest, aContext);
   583 }
   585 NS_IMETHODIMP
   586 nsSAXXMLReader::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
   587                               nsresult status)
   588 {
   589   NS_ENSURE_TRUE(mIsAsyncParse, NS_ERROR_FAILURE);
   590   NS_ENSURE_STATE(mListener);
   591   nsresult rv = mListener->OnStopRequest(aRequest, aContext, status);
   592   mListener = nullptr;
   593   mIsAsyncParse = false;
   594   return rv;
   595 }
   597 // nsIStreamListener
   599 NS_IMETHODIMP
   600 nsSAXXMLReader::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
   601                                 nsIInputStream *aInputStream, uint64_t offset,
   602                                 uint32_t count)
   603 {
   604   NS_ENSURE_TRUE(mIsAsyncParse, NS_ERROR_FAILURE);
   605   NS_ENSURE_STATE(mListener);
   606   return mListener->OnDataAvailable(aRequest, aContext, aInputStream, offset,
   607                                     count);
   608 }
   610 nsresult
   611 nsSAXXMLReader::InitParser(nsIRequestObserver *aObserver, nsIChannel *aChannel)
   612 {
   613   nsresult rv;
   615   // setup the parser
   616   nsCOMPtr<nsIParser> parser = do_CreateInstance(kParserCID, &rv);
   617   NS_ENSURE_SUCCESS(rv, rv);
   619   parser->SetContentSink(this);
   621   int32_t charsetSource = kCharsetFromDocTypeDefault;
   622   nsAutoCString charset(NS_LITERAL_CSTRING("UTF-8"));
   623   TryChannelCharset(aChannel, charsetSource, charset);
   624   parser->SetDocumentCharset(charset, charsetSource);
   626   rv = parser->Parse(mBaseURI, aObserver);
   627   NS_ENSURE_SUCCESS(rv, rv);
   629   mListener = do_QueryInterface(parser, &rv);
   631   return rv;
   632 }
   634 // from nsDocument.cpp
   635 bool
   636 nsSAXXMLReader::TryChannelCharset(nsIChannel *aChannel,
   637                                   int32_t& aCharsetSource,
   638                                   nsACString& aCharset)
   639 {
   640   if (aCharsetSource >= kCharsetFromChannel)
   641     return true;
   643   if (aChannel) {
   644     nsAutoCString charsetVal;
   645     nsresult rv = aChannel->GetContentCharset(charsetVal);
   646     if (NS_SUCCEEDED(rv)) {
   647       nsAutoCString preferred;
   648       if (!EncodingUtils::FindEncodingForLabel(charsetVal, preferred))
   649         return false;
   651       aCharset = preferred;
   652       aCharsetSource = kCharsetFromChannel;
   653       return true;
   654     }
   655   }
   657   return false;
   658 }
   660 nsresult
   661 nsSAXXMLReader::EnsureBaseURI()
   662 {
   663   if (mBaseURI) 
   664     return NS_OK;
   666   return NS_NewURI(getter_AddRefs(mBaseURI), "about:blank");
   667 }
   669 nsresult
   670 nsSAXXMLReader::SplitExpatName(const char16_t *aExpatName,
   671                                nsString &aURI,
   672                                nsString &aLocalName,
   673                                nsString &aQName)
   674 {
   675   /**
   676    * Adapted from RDFContentSinkImpl
   677    *
   678    * Expat can send the following:
   679    *    localName
   680    *    namespaceURI<separator>localName
   681    *    namespaceURI<separator>localName<separator>prefix
   682    *
   683    * and we use 0xFFFF for the <separator>.
   684    *
   685    */
   687   NS_ASSERTION(aExpatName, "null passed to handler");
   688   nsDependentString expatStr(aExpatName);
   689   int32_t break1, break2 = kNotFound;
   690   break1 = expatStr.FindChar(char16_t(0xFFFF));
   692   if (break1 == kNotFound) {
   693     aLocalName = expatStr; // no namespace
   694     aURI.Truncate();
   695     aQName = expatStr;
   696   } else {
   697     aURI = StringHead(expatStr, break1);
   698     break2 = expatStr.FindChar(char16_t(0xFFFF), break1 + 1);
   699     if (break2 == kNotFound) { // namespace, but no prefix
   700       aLocalName = Substring(expatStr, break1 + 1);
   701       aQName = aLocalName;
   702     } else { // namespace with prefix
   703       aLocalName = Substring(expatStr, break1 + 1, break2 - break1 - 1);
   704       aQName = Substring(expatStr, break2 + 1) +
   705         NS_LITERAL_STRING(":") + aLocalName;
   706     }
   707   }
   709   return NS_OK;
   710 }

mercurial