LCOV - app.info - parser/xml/src/nsSAXXMLReader.cpp

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