LCOV - code coverage report
Current view: directory - parser/xml/src - nsSAXXMLReader.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 335 190 56.7 %
Date: 2012-04-21 Functions: 50 29 58.0 %

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

Generated by: LCOV version 1.7