LCOV - code coverage report
Current view: directory - parser/xml/src - nsSAXXMLReader.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 335 225 67.2 %
Date: 2012-06-02 Functions: 50 33 66.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            1464 : 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            2052 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSAXXMLReader)
      75            2257 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSAXXMLReader)
      76            3897 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSAXXMLReader)
      77            2872 :   NS_INTERFACE_MAP_ENTRY(nsISAXXMLReader)
      78            2462 :   NS_INTERFACE_MAP_ENTRY(nsIExpatSink)
      79            2255 :   NS_INTERFACE_MAP_ENTRY(nsIExtendedExpatSink)
      80            2050 :   NS_INTERFACE_MAP_ENTRY(nsIContentSink)
      81            1640 :   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
      82            1640 :   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
      83            1640 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISAXXMLReader)
      84            1435 : NS_INTERFACE_MAP_END
      85                 : 
      86             205 : nsSAXXMLReader::nsSAXXMLReader() : mIsAsyncParse(false)
      87                 : {
      88             205 : }
      89                 : 
      90                 : // nsIContentSink
      91                 : NS_IMETHODIMP
      92             205 : nsSAXXMLReader::WillBuildModel(nsDTDMode)
      93                 : {
      94             205 :   if (mContentHandler)
      95             205 :     return mContentHandler->StartDocument();
      96                 : 
      97               0 :   return NS_OK;
      98                 : }
      99                 : 
     100                 : NS_IMETHODIMP
     101             205 : nsSAXXMLReader::DidBuildModel(bool aTerminated)
     102                 : {
     103             205 :   if (mContentHandler)
     104             205 :     return mContentHandler->EndDocument();
     105                 : 
     106               0 :   return NS_OK;
     107                 : }
     108                 : 
     109                 : NS_IMETHODIMP
     110             205 : nsSAXXMLReader::SetParser(nsParserBase *aParser)
     111                 : {
     112             205 :   return NS_OK;
     113                 : }
     114                 : 
     115                 : // nsIExtendedExpatSink
     116                 : NS_IMETHODIMP
     117            2563 : nsSAXXMLReader::HandleStartElement(const PRUnichar *aName,
     118                 :                                    const PRUnichar **aAtts,
     119                 :                                    PRUint32 aAttsCount,
     120                 :                                    PRInt32 aIndex,
     121                 :                                    PRUint32 aLineNumber)
     122                 : {
     123            2563 :   if (!mContentHandler)
     124               0 :     return NS_OK;
     125                 : 
     126            5126 :   nsCOMPtr<nsSAXAttributes> atts = new nsSAXAttributes();
     127            2563 :   if (!atts)
     128               0 :     return NS_ERROR_OUT_OF_MEMORY;
     129            5126 :   nsAutoString uri, localName, qName;
     130            3901 :   for (; *aAtts; aAtts += 2) {
     131            1338 :     SplitExpatName(aAtts[0], uri, localName, qName);
     132                 :     // XXX don't have attr type information
     133            2676 :     NS_NAMED_LITERAL_STRING(cdataType, "CDATA");
     134                 :     // could support xmlns reporting, it's a standard SAX feature
     135            1338 :     if (!uri.EqualsLiteral(XMLNS_URI)) {
     136            1018 :       NS_ASSERTION(aAtts[1], "null passed to handler");
     137            1018 :       atts->AddAttribute(uri, localName, qName, cdataType,
     138            1018 :                          nsDependentString(aAtts[1]));
     139                 :     }
     140                 :   }
     141                 : 
     142                 :   // Deal with the element name
     143            2563 :   SplitExpatName(aName, uri, localName, qName);
     144            2563 :   return mContentHandler->StartElement(uri, localName, qName, atts);
     145                 : }
     146                 : 
     147                 : NS_IMETHODIMP
     148            2559 : nsSAXXMLReader::HandleEndElement(const PRUnichar *aName)
     149                 : {
     150            2559 :   if (mContentHandler) {
     151            5118 :     nsAutoString uri, localName, qName;
     152            2559 :     SplitExpatName(aName, uri, localName, qName);
     153            2559 :     return mContentHandler->EndElement(uri, localName, qName);
     154                 :   }
     155               0 :   return NS_OK;
     156                 : }
     157                 : 
     158                 : NS_IMETHODIMP
     159             224 : nsSAXXMLReader::HandleComment(const PRUnichar *aName)
     160                 : {
     161             224 :   NS_ASSERTION(aName, "null passed to handler");
     162             224 :   if (mLexicalHandler)
     163               2 :     return mLexicalHandler->Comment(nsDependentString(aName));
     164                 :  
     165             222 :   return NS_OK;
     166                 : }
     167                 : 
     168                 : NS_IMETHODIMP
     169              25 : nsSAXXMLReader::HandleCDataSection(const PRUnichar *aData,
     170                 :                                    PRUint32 aLength)
     171                 : {
     172                 :   nsresult rv;
     173              25 :   if (mLexicalHandler) {
     174               2 :     rv = mLexicalHandler->StartCDATA();
     175               2 :     NS_ENSURE_SUCCESS(rv, rv);
     176                 :   }
     177                 : 
     178              25 :   if (mContentHandler) {
     179              25 :     rv = mContentHandler->Characters(Substring(aData, aData+aLength));
     180              25 :     NS_ENSURE_SUCCESS(rv, rv);
     181                 :   }
     182                 : 
     183              25 :   if (mLexicalHandler) {
     184               2 :     rv = mLexicalHandler->EndCDATA();
     185               2 :     NS_ENSURE_SUCCESS(rv, rv);
     186                 :   }
     187                 : 
     188              25 :   return NS_OK;
     189                 : }
     190                 : 
     191                 : NS_IMETHODIMP
     192               4 : nsSAXXMLReader::HandleStartDTD(const PRUnichar *aName,
     193                 :                                const PRUnichar *aSystemId,
     194                 :                                const PRUnichar *aPublicId)
     195                 : {
     196               4 :   PRUnichar nullChar = PRUnichar(0);
     197               4 :   if (!aName)
     198               0 :     aName = &nullChar;
     199               4 :   if (!aSystemId)
     200               2 :     aSystemId = &nullChar;
     201               4 :   if (!aPublicId)
     202               4 :     aPublicId = &nullChar;
     203                 : 
     204               4 :   mSystemId = aSystemId;
     205               4 :   mPublicId = aPublicId;
     206               4 :   if (mLexicalHandler) {
     207               4 :     return mLexicalHandler->StartDTD(nsDependentString(aName),
     208               2 :                                      nsDependentString(aSystemId),
     209               4 :                                      nsDependentString(aPublicId));
     210                 :   }
     211                 : 
     212               2 :   return NS_OK;
     213                 : }
     214                 : 
     215                 : NS_IMETHODIMP
     216               4 : nsSAXXMLReader::HandleDoctypeDecl(const nsAString & aSubset,
     217                 :                                   const nsAString & aName,
     218                 :                                   const nsAString & aSystemId,
     219                 :                                   const nsAString & aPublicId,
     220                 :                                   nsISupports* aCatalogData)
     221                 : {
     222               4 :   if (mLexicalHandler)
     223               2 :     return mLexicalHandler->EndDTD();
     224                 : 
     225               2 :   return NS_OK;
     226                 : }
     227                 : 
     228                 : NS_IMETHODIMP
     229            8362 : nsSAXXMLReader::HandleCharacterData(const PRUnichar *aData,
     230                 :                                     PRUint32 aLength)
     231                 : {
     232            8362 :   if (mContentHandler)
     233            8362 :     return mContentHandler->Characters(Substring(aData, aData+aLength));
     234                 : 
     235               0 :   return NS_OK;
     236                 : }
     237                 : 
     238                 : NS_IMETHODIMP
     239             320 : nsSAXXMLReader::HandleStartNamespaceDecl(const PRUnichar *aPrefix,
     240                 :                                          const PRUnichar *aUri)
     241                 : {
     242             320 :   if (!mContentHandler)
     243               0 :     return NS_OK;
     244                 :   
     245             320 :   PRUnichar nullChar = PRUnichar(0);
     246             320 :   if (!aPrefix)
     247             180 :     aPrefix = &nullChar;
     248             320 :   if (!aUri)
     249               0 :     aUri = &nullChar;
     250                 : 
     251             640 :   return mContentHandler->StartPrefixMapping(nsDependentString(aPrefix),
     252             640 :                                              nsDependentString(aUri));
     253                 : }
     254                 : 
     255                 : NS_IMETHODIMP
     256             314 : nsSAXXMLReader::HandleEndNamespaceDecl(const PRUnichar *aPrefix)
     257                 : {
     258             314 :   if (!mContentHandler)
     259               0 :     return NS_OK;
     260                 :   
     261             314 :   if (aPrefix)
     262             135 :     return mContentHandler->EndPrefixMapping(nsDependentString(aPrefix));
     263                 : 
     264             179 :   return mContentHandler->EndPrefixMapping(EmptyString());
     265                 : }
     266                 : 
     267                 : NS_IMETHODIMP
     268               3 : nsSAXXMLReader::HandleProcessingInstruction(const PRUnichar *aTarget,
     269                 :                                             const PRUnichar *aData)
     270                 : {
     271               3 :   NS_ASSERTION(aTarget && aData, "null passed to handler");
     272               3 :   if (mContentHandler) {
     273               6 :     return mContentHandler->ProcessingInstruction(nsDependentString(aTarget),
     274               6 :                                                   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             201 : 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             201 :   return NS_OK;
     332                 : }
     333                 : 
     334                 : NS_IMETHODIMP
     335               2 : nsSAXXMLReader::ReportError(const PRUnichar* aErrorText,
     336                 :                             const PRUnichar* aSourceText,
     337                 :                             nsIScriptError *aError,
     338                 :                             bool *_retval)
     339                 : {
     340               2 :   NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!");
     341                 :   // Normally, the expat driver should report the error.
     342               2 :   *_retval = true;
     343                 : 
     344               2 :   if (mErrorHandler) {
     345                 :     PRUint32 lineNumber;
     346               2 :     nsresult rv = aError->GetLineNumber(&lineNumber);
     347               2 :     NS_ENSURE_SUCCESS(rv, rv);
     348                 : 
     349                 :     PRUint32 columnNumber;
     350               2 :     rv = aError->GetColumnNumber(&columnNumber);
     351               2 :     NS_ENSURE_SUCCESS(rv, rv);
     352                 : 
     353                 :     nsCOMPtr<nsISAXLocator> locator = new nsSAXLocator(mPublicId,
     354                 :                                                        mSystemId,
     355                 :                                                        lineNumber,
     356               4 :                                                        columnNumber);
     357               2 :     if (!locator)
     358               0 :       return NS_ERROR_OUT_OF_MEMORY;
     359                 : 
     360               2 :     rv = mErrorHandler->FatalError(locator, nsDependentString(aErrorText));
     361               2 :     if (NS_SUCCEEDED(rv)) {
     362                 :       // The error handler has handled the script error.  Don't log to console.
     363               2 :       *_retval = false;
     364                 :     }
     365                 :   }
     366                 : 
     367               2 :   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             203 : nsSAXXMLReader::SetBaseURI(nsIURI *aBaseURI)
     381                 : {
     382             203 :   mBaseURI = aBaseURI;
     383             203 :   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            2548 : nsSAXXMLReader::SetContentHandler(nsISAXContentHandler *aContentHandler)
     395                 : {
     396            2548 :   mContentHandler = aContentHandler;
     397            2548 :   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             207 : nsSAXXMLReader::SetErrorHandler(nsISAXErrorHandler *aErrorHandler)
     423                 : {
     424             207 :   mErrorHandler = aErrorHandler;
     425             207 :   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             205 : 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             205 :   NS_ENSURE_TRUE(!mIsAsyncParse, NS_ERROR_FAILURE);
     491                 : 
     492             205 :   NS_ENSURE_ARG(aStream);
     493             205 :   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             410 :   nsCOMPtr<nsIInputStream> bufferedStream;
     498             205 :   if (!NS_InputStreamIsBuffered(aStream)) {
     499             203 :     rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
     500             203 :                                    aStream, 4096);
     501             203 :     NS_ENSURE_SUCCESS(rv, rv);
     502             203 :     aStream = bufferedStream;
     503                 :   }
     504                 :  
     505             205 :   rv = EnsureBaseURI();
     506             205 :   NS_ENSURE_SUCCESS(rv, rv);
     507                 : 
     508             410 :   nsCOMPtr<nsIChannel> parserChannel;
     509             205 :   rv = NS_NewInputStreamChannel(getter_AddRefs(parserChannel), mBaseURI,
     510             410 :                                 aStream, nsDependentCString(aContentType));
     511             205 :   if (!parserChannel || NS_FAILED(rv))
     512               0 :     return NS_ERROR_FAILURE;
     513                 : 
     514             205 :   if (aCharset)
     515               2 :     parserChannel->SetContentCharset(nsDependentCString(aCharset));
     516                 : 
     517             205 :   rv = InitParser(nsnull, parserChannel);
     518             205 :   NS_ENSURE_SUCCESS(rv, rv);
     519                 : 
     520             205 :   rv = mListener->OnStartRequest(parserChannel, nsnull);
     521             205 :   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             205 :   mSystemId.Truncate();
     530             205 :   mPublicId.Truncate();
     531                 : 
     532                 :   nsresult status;
     533             205 :   parserChannel->GetStatus(&status);
     534                 :   
     535             205 :   PRUint32 offset = 0;
     536             615 :   while (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
     537                 :     PRUint32 available;
     538             410 :     rv = aStream->Available(&available);
     539             410 :     if (rv == NS_BASE_STREAM_CLOSED) {
     540               0 :       rv = NS_OK;
     541               0 :       available = 0;
     542                 :     }
     543             410 :     if (NS_FAILED(rv)) {
     544               0 :       parserChannel->Cancel(rv);
     545               0 :       break;
     546                 :     }
     547             410 :     if (! available)
     548             205 :       break; // blocking input stream has none available when done
     549                 : 
     550             205 :     rv = mListener->OnDataAvailable(parserChannel, nsnull,
     551             205 :                                     aStream, offset, available);
     552             205 :     if (NS_SUCCEEDED(rv))
     553             205 :       offset += available;
     554                 :     else
     555               0 :       parserChannel->Cancel(rv);
     556             205 :     parserChannel->GetStatus(&status);
     557                 :   }
     558             205 :   rv = mListener->OnStopRequest(parserChannel, nsnull, status);
     559             205 :   mListener = nsnull;
     560                 : 
     561             205 :   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             205 : nsSAXXMLReader::InitParser(nsIRequestObserver *aObserver, nsIChannel *aChannel)
     616                 : {
     617                 :   nsresult rv;
     618                 : 
     619                 :   // setup the parser
     620             410 :   nsCOMPtr<nsIParser> parser = do_CreateInstance(kParserCID, &rv);
     621             205 :   NS_ENSURE_SUCCESS(rv, rv);
     622                 : 
     623             205 :   parser->SetContentSink(this);
     624                 : 
     625             205 :   PRInt32 charsetSource = kCharsetFromDocTypeDefault;
     626             410 :   nsCAutoString charset(NS_LITERAL_CSTRING("UTF-8"));
     627             205 :   TryChannelCharset(aChannel, charsetSource, charset);
     628             205 :   parser->SetDocumentCharset(charset, charsetSource);
     629                 : 
     630             205 :   rv = parser->Parse(mBaseURI, aObserver);
     631             205 :   NS_ENSURE_SUCCESS(rv, rv);
     632                 : 
     633             205 :   mListener = do_QueryInterface(parser, &rv);
     634                 : 
     635             205 :   return rv;
     636                 : }
     637                 : 
     638                 : // from nsDocument.cpp
     639                 : bool
     640             205 : nsSAXXMLReader::TryChannelCharset(nsIChannel *aChannel,
     641                 :                                   PRInt32& aCharsetSource,
     642                 :                                   nsACString& aCharset)
     643                 : {
     644             205 :   if (aCharsetSource >= kCharsetFromChannel)
     645               0 :     return true;
     646                 :   
     647             205 :   if (aChannel) {
     648             410 :     nsCAutoString charsetVal;
     649             205 :     nsresult rv = aChannel->GetContentCharset(charsetVal);
     650             205 :     if (NS_SUCCEEDED(rv)) {
     651             410 :       nsCAutoString preferred;
     652             205 :       if (NS_FAILED(nsCharsetAlias::GetPreferred(charsetVal, preferred)))
     653             203 :         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             205 : nsSAXXMLReader::EnsureBaseURI()
     666                 : {
     667             205 :   if (mBaseURI) 
     668             203 :     return NS_OK;
     669                 : 
     670               2 :   return NS_NewURI(getter_AddRefs(mBaseURI), "about:blank");
     671                 : }
     672                 : 
     673                 : nsresult
     674            6460 : 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            6460 :   NS_ASSERTION(aExpatName, "null passed to handler");
     692           12920 :   nsDependentString expatStr(aExpatName);
     693            6460 :   PRInt32 break1, break2 = kNotFound;
     694            6460 :   break1 = expatStr.FindChar(PRUnichar(0xFFFF));
     695                 : 
     696            6460 :   if (break1 == kNotFound) {
     697            2081 :     aLocalName = expatStr; // no namespace
     698            2081 :     aURI.Truncate();
     699            2081 :     aQName = expatStr;
     700                 :   } else {
     701            4379 :     aURI = StringHead(expatStr, break1);
     702            4379 :     break2 = expatStr.FindChar(PRUnichar(0xFFFF), break1 + 1);
     703            4379 :     if (break2 == kNotFound) { // namespace, but no prefix
     704            3598 :       aLocalName = Substring(expatStr, break1 + 1);
     705            3598 :       aQName = aLocalName;
     706                 :     } else { // namespace with prefix
     707             781 :       aLocalName = Substring(expatStr, break1 + 1, break2 - break1 - 1);
     708             781 :       aQName = Substring(expatStr, break2 + 1) +
     709            1562 :         NS_LITERAL_STRING(":") + aLocalName;
     710                 :     }
     711                 :   }
     712                 : 
     713            6460 :   return NS_OK;
     714            4392 : }

Generated by: LCOV version 1.7