LCOV - code coverage report
Current view: top level - rdf/base - nsRDFXMLDataSource.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 392 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 65 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : /*
       7             : 
       8             :   A data source that can read itself from and write itself to an
       9             :   RDF/XML stream.
      10             : 
      11             :   For more information on the RDF/XML syntax,
      12             :   see http://www.w3.org/TR/REC-rdf-syntax/.
      13             : 
      14             :   This code is based on the final W3C Recommendation,
      15             :   http://www.w3.org/TR/1999/REC-rdf-syntax-19990222.
      16             : 
      17             : 
      18             :   TO DO
      19             :   -----
      20             : 
      21             :   1) Right now, the only kind of stream data sources that are _really_
      22             :      writable are "file:" URIs. (In fact, _all_ "file:" URIs are
      23             :      writable, modulo file system permissions; this may lead to some
      24             :      surprising behavior.) Eventually, it'd be great if we could open
      25             :      an arbitrary nsIOutputStream on *any* URL, and Netlib could just
      26             :      do the magic.
      27             : 
      28             :   2) Implement a more terse output for "typed" nodes; that is, instead
      29             :      of "RDF:Description type='ns:foo'", just output "ns:foo".
      30             : 
      31             :   3) When re-serializing, we "cheat" for Descriptions that talk about
      32             :      inline resources (i.e.., using the `ID' attribute specified in
      33             :      [6.21]). Instead of writing an `ID="foo"' for the first instance,
      34             :      and then `about="#foo"' for each subsequent instance, we just
      35             :      _always_ write `about="#foo"'.
      36             : 
      37             :      We do this so that we can handle the case where an RDF container
      38             :      has been assigned arbitrary properties: the spec says we can't
      39             :      dangle the attributes directly off the container, so we need to
      40             :      refer to it. Of course, with a little cleverness, we could fix
      41             :      this. But who cares?
      42             : 
      43             :   4) When re-serializing containers. We have to cheat on some
      44             :      containers, and use an illegal "about=" construct. We do this to
      45             :      handle containers that have been assigned URIs outside of the
      46             :      local document.
      47             : 
      48             : 
      49             :   Logging
      50             :   -------
      51             : 
      52             :   To turn on logging for this module, set
      53             : 
      54             :     MOZ_LOG=nsRDFXMLDataSource:5
      55             : 
      56             :  */
      57             : 
      58             : #include "nsIFileStreams.h"
      59             : #include "nsIOutputStream.h"
      60             : #include "nsIFile.h"
      61             : #include "nsIFileChannel.h"
      62             : #include "nsIDTD.h"
      63             : #include "nsIRDFPurgeableDataSource.h"
      64             : #include "nsIInputStream.h"
      65             : #include "nsIOutputStream.h"
      66             : #include "nsIRDFContainerUtils.h"
      67             : #include "nsIRDFNode.h"
      68             : #include "nsIRDFRemoteDataSource.h"
      69             : #include "nsIRDFService.h"
      70             : #include "nsIRDFXMLParser.h"
      71             : #include "nsIRDFXMLSerializer.h"
      72             : #include "nsIRDFXMLSink.h"
      73             : #include "nsIRDFXMLSource.h"
      74             : #include "nsISafeOutputStream.h"
      75             : #include "nsIServiceManager.h"
      76             : #include "nsIStreamListener.h"
      77             : #include "nsIURL.h"
      78             : #include "nsIFileURL.h"
      79             : #include "nsISafeOutputStream.h"
      80             : #include "nsIChannel.h"
      81             : #include "nsRDFCID.h"
      82             : #include "nsRDFBaseDataSources.h"
      83             : #include "nsCOMArray.h"
      84             : #include "nsXPIDLString.h"
      85             : #include "plstr.h"
      86             : #include "prio.h"
      87             : #include "prthread.h"
      88             : #include "rdf.h"
      89             : #include "rdfutil.h"
      90             : #include "mozilla/Logging.h"
      91             : #include "nsNameSpaceMap.h"
      92             : #include "nsCRT.h"
      93             : #include "nsCycleCollectionParticipant.h"
      94             : #include "nsIScriptSecurityManager.h"
      95             : #include "nsIChannelEventSink.h"
      96             : #include "nsIAsyncVerifyRedirectCallback.h"
      97             : #include "nsNetUtil.h"
      98             : #include "nsIContentPolicy.h"
      99             : #include "nsContentUtils.h"
     100             : 
     101             : #include "rdfIDataSource.h"
     102             : 
     103             : //----------------------------------------------------------------------
     104             : //
     105             : // RDFXMLDataSourceImpl
     106             : //
     107             : 
     108             : class RDFXMLDataSourceImpl : public nsIRDFDataSource,
     109             :                              public nsIRDFRemoteDataSource,
     110             :                              public nsIRDFXMLSink,
     111             :                              public nsIRDFXMLSource,
     112             :                              public nsIStreamListener,
     113             :                              public rdfIDataSource,
     114             :                              public nsIInterfaceRequestor,
     115             :                              public nsIChannelEventSink
     116             : {
     117             : protected:
     118             :     enum LoadState {
     119             :         eLoadState_Unloaded,
     120             :         eLoadState_Pending,
     121             :         eLoadState_Loading,
     122             :         eLoadState_Loaded
     123             :     };
     124             : 
     125             :     nsCOMPtr<nsIRDFDataSource> mInner;
     126             :     bool                mIsWritable;    // true if the document can be written back
     127             :     bool                mIsDirty;       // true if the document should be written back
     128             :     LoadState           mLoadState;     // what we're doing now
     129             :     nsCOMArray<nsIRDFXMLSinkObserver> mObservers;
     130             :     nsCOMPtr<nsIURI>    mURL;
     131             :     nsCOMPtr<nsIStreamListener> mListener;
     132             :     nsNameSpaceMap      mNameSpaces;
     133             : 
     134             :     // pseudo-constants
     135             :     static int32_t gRefCnt;
     136             :     static nsIRDFService* gRDFService;
     137             : 
     138             :     static mozilla::LazyLogModule gLog;
     139             : 
     140             :     nsresult Init();
     141             :     RDFXMLDataSourceImpl(void);
     142             :     virtual ~RDFXMLDataSourceImpl(void);
     143             :     nsresult rdfXMLFlush(nsIURI *aURI);
     144             : 
     145             :     friend nsresult
     146             :     NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult);
     147             : 
     148           0 :     inline bool IsLoading() {
     149           0 :         return (mLoadState == eLoadState_Pending) ||
     150           0 :                (mLoadState == eLoadState_Loading);
     151             :     }
     152             : 
     153             : public:
     154             :     // nsISupports
     155             :     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     156           0 :     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(RDFXMLDataSourceImpl,
     157             :                                              nsIRDFDataSource)
     158             : 
     159             :     // nsIRDFDataSource
     160             :     NS_IMETHOD GetURI(char* *uri) override;
     161             : 
     162           0 :     NS_IMETHOD GetSource(nsIRDFResource* property,
     163             :                          nsIRDFNode* target,
     164             :                          bool tv,
     165             :                          nsIRDFResource** source) override {
     166           0 :         return mInner->GetSource(property, target, tv, source);
     167             :     }
     168             : 
     169           0 :     NS_IMETHOD GetSources(nsIRDFResource* property,
     170             :                           nsIRDFNode* target,
     171             :                           bool tv,
     172             :                           nsISimpleEnumerator** sources) override {
     173           0 :         return mInner->GetSources(property, target, tv, sources);
     174             :     }
     175             : 
     176           0 :     NS_IMETHOD GetTarget(nsIRDFResource* source,
     177             :                          nsIRDFResource* property,
     178             :                          bool tv,
     179             :                          nsIRDFNode** target) override {
     180           0 :         return mInner->GetTarget(source, property, tv, target);
     181             :     }
     182             : 
     183           0 :     NS_IMETHOD GetTargets(nsIRDFResource* source,
     184             :                           nsIRDFResource* property,
     185             :                           bool tv,
     186             :                           nsISimpleEnumerator** targets) override {
     187           0 :         return mInner->GetTargets(source, property, tv, targets);
     188             :     }
     189             : 
     190             :     NS_IMETHOD Assert(nsIRDFResource* aSource,
     191             :                       nsIRDFResource* aProperty,
     192             :                       nsIRDFNode* aTarget,
     193             :                       bool tv) override;
     194             : 
     195             :     NS_IMETHOD Unassert(nsIRDFResource* source,
     196             :                         nsIRDFResource* property,
     197             :                         nsIRDFNode* target) override;
     198             : 
     199             :     NS_IMETHOD Change(nsIRDFResource* aSource,
     200             :                       nsIRDFResource* aProperty,
     201             :                       nsIRDFNode* aOldTarget,
     202             :                       nsIRDFNode* aNewTarget) override;
     203             : 
     204             :     NS_IMETHOD Move(nsIRDFResource* aOldSource,
     205             :                     nsIRDFResource* aNewSource,
     206             :                     nsIRDFResource* aProperty,
     207             :                     nsIRDFNode* aTarget) override;
     208             : 
     209           0 :     NS_IMETHOD HasAssertion(nsIRDFResource* source,
     210             :                             nsIRDFResource* property,
     211             :                             nsIRDFNode* target,
     212             :                             bool tv,
     213             :                             bool* hasAssertion) override {
     214           0 :         return mInner->HasAssertion(source, property, target, tv, hasAssertion);
     215             :     }
     216             : 
     217           0 :     NS_IMETHOD AddObserver(nsIRDFObserver* aObserver) override {
     218           0 :         return mInner->AddObserver(aObserver);
     219             :     }
     220             : 
     221           0 :     NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver) override {
     222           0 :         return mInner->RemoveObserver(aObserver);
     223             :     }
     224             : 
     225           0 :     NS_IMETHOD HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *_retval) override {
     226           0 :         return mInner->HasArcIn(aNode, aArc, _retval);
     227             :     }
     228             : 
     229           0 :     NS_IMETHOD HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *_retval) override {
     230           0 :         return mInner->HasArcOut(aSource, aArc, _retval);
     231             :     }
     232             : 
     233           0 :     NS_IMETHOD ArcLabelsIn(nsIRDFNode* node,
     234             :                            nsISimpleEnumerator** labels) override {
     235           0 :         return mInner->ArcLabelsIn(node, labels);
     236             :     }
     237             : 
     238           0 :     NS_IMETHOD ArcLabelsOut(nsIRDFResource* source,
     239             :                             nsISimpleEnumerator** labels) override {
     240           0 :         return mInner->ArcLabelsOut(source, labels);
     241             :     }
     242             : 
     243           0 :     NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult) override {
     244           0 :         return mInner->GetAllResources(aResult);
     245             :     }
     246             : 
     247           0 :     NS_IMETHOD GetAllCmds(nsIRDFResource* source,
     248             :                               nsISimpleEnumerator/*<nsIRDFResource>*/** commands) override {
     249           0 :         return mInner->GetAllCmds(source, commands);
     250             :     }
     251             : 
     252           0 :     NS_IMETHOD IsCommandEnabled(nsISupports* aSources,
     253             :                                 nsIRDFResource*   aCommand,
     254             :                                 nsISupports* aArguments,
     255             :                                 bool* aResult) override {
     256           0 :         return NS_ERROR_NOT_IMPLEMENTED;
     257             :     }
     258             : 
     259           0 :     NS_IMETHOD DoCommand(nsISupports* aSources,
     260             :                          nsIRDFResource*   aCommand,
     261             :                          nsISupports* aArguments) override {
     262           0 :         return NS_ERROR_NOT_IMPLEMENTED;
     263             :     }
     264             : 
     265           0 :     NS_IMETHOD BeginUpdateBatch() override {
     266           0 :         return mInner->BeginUpdateBatch();
     267             :     }
     268             : 
     269           0 :     NS_IMETHOD EndUpdateBatch() override {
     270           0 :         return mInner->EndUpdateBatch();
     271             :     }
     272             : 
     273             :     // nsIRDFRemoteDataSource interface
     274             :     NS_DECL_NSIRDFREMOTEDATASOURCE
     275             : 
     276             :     // nsIRDFXMLSink interface
     277             :     NS_DECL_NSIRDFXMLSINK
     278             : 
     279             :     // nsIRDFXMLSource interface
     280             :     NS_DECL_NSIRDFXMLSOURCE
     281             : 
     282             :     // nsIRequestObserver
     283             :     NS_DECL_NSIREQUESTOBSERVER
     284             : 
     285             :     // nsIStreamListener
     286             :     NS_DECL_NSISTREAMLISTENER
     287             : 
     288             :     // nsIInterfaceRequestor
     289             :     NS_DECL_NSIINTERFACEREQUESTOR
     290             : 
     291             :     // nsIChannelEventSink
     292             :     NS_DECL_NSICHANNELEVENTSINK
     293             : 
     294             :     // rdfIDataSource
     295           0 :     NS_IMETHOD VisitAllSubjects(rdfITripleVisitor *aVisitor) override {
     296             :         nsresult rv;
     297           0 :         nsCOMPtr<rdfIDataSource> rdfds = do_QueryInterface(mInner, &rv);
     298           0 :         if (NS_FAILED(rv)) return rv;
     299           0 :         return rdfds->VisitAllSubjects(aVisitor);
     300             :     }
     301             : 
     302           0 :     NS_IMETHOD VisitAllTriples(rdfITripleVisitor *aVisitor) override {
     303             :         nsresult rv;
     304           0 :         nsCOMPtr<rdfIDataSource> rdfds = do_QueryInterface(mInner, &rv);
     305           0 :         if (NS_FAILED(rv)) return rv;
     306           0 :         return rdfds->VisitAllTriples(aVisitor);
     307             :     }
     308             : 
     309             :     // Implementation methods
     310             :     bool
     311             :     MakeQName(nsIRDFResource* aResource,
     312             :               nsString& property,
     313             :               nsString& nameSpacePrefix,
     314             :               nsString& nameSpaceURI);
     315             : 
     316             :     nsresult
     317             :     SerializeAssertion(nsIOutputStream* aStream,
     318             :                        nsIRDFResource* aResource,
     319             :                        nsIRDFResource* aProperty,
     320             :                        nsIRDFNode* aValue);
     321             : 
     322             :     nsresult
     323             :     SerializeProperty(nsIOutputStream* aStream,
     324             :                       nsIRDFResource* aResource,
     325             :                       nsIRDFResource* aProperty);
     326             : 
     327             :     bool
     328             :     IsContainerProperty(nsIRDFResource* aProperty);
     329             : 
     330             :     nsresult
     331             :     SerializeDescription(nsIOutputStream* aStream,
     332             :                          nsIRDFResource* aResource);
     333             : 
     334             :     nsresult
     335             :     SerializeMember(nsIOutputStream* aStream,
     336             :                     nsIRDFResource* aContainer,
     337             :                     nsIRDFNode* aMember);
     338             : 
     339             :     nsresult
     340             :     SerializeContainer(nsIOutputStream* aStream,
     341             :                        nsIRDFResource* aContainer);
     342             : 
     343             :     nsresult
     344             :     SerializePrologue(nsIOutputStream* aStream);
     345             : 
     346             :     nsresult
     347             :     SerializeEpilogue(nsIOutputStream* aStream);
     348             : 
     349             :     bool
     350             :     IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType);
     351             : 
     352             : protected:
     353             :     nsresult
     354             :     BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer);
     355             : };
     356             : 
     357             : int32_t         RDFXMLDataSourceImpl::gRefCnt = 0;
     358             : nsIRDFService*  RDFXMLDataSourceImpl::gRDFService;
     359             : 
     360             : mozilla::LazyLogModule RDFXMLDataSourceImpl::gLog("nsRDFXMLDataSource");
     361             : 
     362             : static const char kFileURIPrefix[] = "file:";
     363             : static const char kResourceURIPrefix[] = "resource:";
     364             : 
     365             : 
     366             : //----------------------------------------------------------------------
     367             : 
     368             : nsresult
     369           0 : NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult)
     370             : {
     371           0 :     NS_PRECONDITION(aResult != nullptr, "null ptr");
     372           0 :     if (! aResult)
     373           0 :         return NS_ERROR_NULL_POINTER;
     374             : 
     375           0 :     RDFXMLDataSourceImpl* datasource = new RDFXMLDataSourceImpl();
     376           0 :     if (! datasource)
     377           0 :         return NS_ERROR_OUT_OF_MEMORY;
     378             : 
     379             :     nsresult rv;
     380           0 :     rv = datasource->Init();
     381             : 
     382           0 :     if (NS_FAILED(rv)) {
     383           0 :         delete datasource;
     384           0 :         return rv;
     385             :     }
     386             : 
     387           0 :     NS_ADDREF(datasource);
     388           0 :     *aResult = datasource;
     389           0 :     return NS_OK;
     390             : }
     391             : 
     392             : 
     393           0 : RDFXMLDataSourceImpl::RDFXMLDataSourceImpl(void)
     394             :     : mIsWritable(true),
     395             :       mIsDirty(false),
     396           0 :       mLoadState(eLoadState_Unloaded)
     397             : {
     398           0 : }
     399             : 
     400             : 
     401             : nsresult
     402           0 : RDFXMLDataSourceImpl::Init()
     403             : {
     404             :     nsresult rv;
     405           0 :     NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
     406           0 :     mInner = do_CreateInstance(kRDFInMemoryDataSourceCID, &rv);
     407           0 :     if (NS_FAILED(rv)) return rv;
     408             : 
     409           0 :     if (gRefCnt++ == 0) {
     410           0 :         NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
     411           0 :         rv = CallGetService(kRDFServiceCID, &gRDFService);
     412             : 
     413           0 :         NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
     414           0 :         if (NS_FAILED(rv)) return rv;
     415             :     }
     416             : 
     417           0 :     return NS_OK;
     418             : }
     419             : 
     420             : 
     421           0 : RDFXMLDataSourceImpl::~RDFXMLDataSourceImpl(void)
     422             : {
     423             :     // Unregister first so that nobody else tries to get us.
     424           0 :     (void) gRDFService->UnregisterDataSource(this);
     425             : 
     426             :     // Now flush contents
     427           0 :     (void) Flush();
     428             : 
     429             :     // Release RDF/XML sink observers
     430           0 :     mObservers.Clear();
     431             : 
     432           0 :     if (--gRefCnt == 0)
     433           0 :         NS_IF_RELEASE(gRDFService);
     434           0 : }
     435             : 
     436             : NS_IMPL_CYCLE_COLLECTION_CLASS(RDFXMLDataSourceImpl)
     437             : 
     438           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_0(RDFXMLDataSourceImpl)
     439           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(RDFXMLDataSourceImpl)
     440           0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInner)
     441           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     442             : 
     443           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(RDFXMLDataSourceImpl)
     444           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(RDFXMLDataSourceImpl)
     445             : 
     446           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RDFXMLDataSourceImpl)
     447           0 :     NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
     448           0 :     NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource)
     449           0 :     NS_INTERFACE_MAP_ENTRY(nsIRDFXMLSink)
     450           0 :     NS_INTERFACE_MAP_ENTRY(nsIRDFXMLSource)
     451           0 :     NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
     452           0 :     NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
     453           0 :     NS_INTERFACE_MAP_ENTRY(rdfIDataSource)
     454           0 :     NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
     455           0 :     NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
     456           0 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFDataSource)
     457           0 : NS_INTERFACE_MAP_END
     458             : 
     459             : // nsIInterfaceRequestor
     460             : NS_IMETHODIMP
     461           0 : RDFXMLDataSourceImpl::GetInterface(const nsIID& aIID, void** aSink)
     462             : {
     463           0 :   return QueryInterface(aIID, aSink);
     464             : }
     465             : 
     466             : nsresult
     467           0 : RDFXMLDataSourceImpl::BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer)
     468             : {
     469             :     nsresult rv;
     470             : 
     471             :     // XXX I really hate the way that we're spoon-feeding this stuff
     472             :     // to the parser: it seems like this is something that netlib
     473             :     // should be able to do by itself.
     474             : 
     475           0 :     nsCOMPtr<nsIChannel> channel;
     476             : 
     477             :     // Null LoadGroup ?
     478           0 :     rv = NS_NewChannel(getter_AddRefs(channel),
     479             :                        aURL,
     480             :                        nsContentUtils::GetSystemPrincipal(),
     481             :                        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
     482             :                        nsIContentPolicy::TYPE_OTHER);
     483             : 
     484           0 :     if (NS_FAILED(rv)) return rv;
     485           0 :     nsCOMPtr<nsIInputStream> in;
     486           0 :     rv = channel->Open2(getter_AddRefs(in));
     487             : 
     488             :     // Report success if the file doesn't exist, but propagate other errors.
     489           0 :     if (rv == NS_ERROR_FILE_NOT_FOUND) return NS_OK;
     490           0 :     if (NS_FAILED(rv)) return rv;
     491             : 
     492           0 :     if (! in) {
     493           0 :         NS_ERROR("no input stream");
     494           0 :         return NS_ERROR_FAILURE;
     495             :     }
     496             : 
     497             :     // Wrap the channel's input stream in a buffered stream to ensure that
     498             :     // ReadSegments is implemented (which OnDataAvailable expects).
     499           0 :     nsCOMPtr<nsIInputStream> bufStream;
     500           0 :     rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), in,
     501             :                                    4096 /* buffer size */);
     502           0 :     if (NS_FAILED(rv)) return rv;
     503             : 
     504             :     // Notify load observers
     505             :     int32_t i;
     506           0 :     for (i = mObservers.Count() - 1; i >= 0; --i) {
     507             :         // Make sure to hold a strong reference to the observer so
     508             :         // that it doesn't go away in this call if it removes itself
     509             :         // as an observer
     510           0 :         nsCOMPtr<nsIRDFXMLSinkObserver> obs = mObservers[i];
     511             : 
     512           0 :         if (obs) {
     513           0 :             obs->OnBeginLoad(this);
     514             :         }
     515             :     }
     516             : 
     517           0 :     rv = aConsumer->OnStartRequest(channel, nullptr);
     518             : 
     519           0 :     uint64_t offset = 0;
     520           0 :     while (NS_SUCCEEDED(rv)) {
     521             :         // Skip ODA if the channel is canceled
     522           0 :         channel->GetStatus(&rv);
     523           0 :         if (NS_FAILED(rv))
     524           0 :             break;
     525             : 
     526             :         uint64_t avail;
     527           0 :         if (NS_FAILED(rv = bufStream->Available(&avail)))
     528           0 :             break; // error
     529             : 
     530           0 :         if (avail == 0)
     531           0 :             break; // eof
     532             : 
     533           0 :         if (avail > UINT32_MAX)
     534           0 :             avail = UINT32_MAX;
     535             : 
     536           0 :         rv = aConsumer->OnDataAvailable(channel, nullptr, bufStream, offset, (uint32_t)avail);
     537           0 :         if (NS_SUCCEEDED(rv))
     538           0 :             offset += avail;
     539             :     }
     540             : 
     541           0 :     if (NS_FAILED(rv))
     542           0 :         channel->Cancel(rv);
     543             : 
     544           0 :     channel->GetStatus(&rv);
     545           0 :     aConsumer->OnStopRequest(channel, nullptr, rv);
     546             : 
     547             :     // Notify load observers
     548           0 :     for (i = mObservers.Count() - 1; i >= 0; --i) {
     549             :         // Make sure to hold a strong reference to the observer so
     550             :         // that it doesn't go away in this call if it removes itself
     551             :         // as an observer
     552           0 :         nsCOMPtr<nsIRDFXMLSinkObserver> obs = mObservers[i];
     553             : 
     554           0 :         if (obs) {
     555           0 :             if (NS_FAILED(rv))
     556           0 :                 obs->OnError(this, rv, nullptr);
     557             : 
     558           0 :             obs->OnEndLoad(this);
     559             :         }
     560             :     }
     561             : 
     562           0 :     return rv;
     563             : }
     564             : 
     565             : NS_IMETHODIMP
     566           0 : RDFXMLDataSourceImpl::GetLoaded(bool* _result)
     567             : {
     568           0 :     *_result = (mLoadState == eLoadState_Loaded);
     569           0 :     return NS_OK;
     570             : }
     571             : 
     572             : NS_IMETHODIMP
     573           0 : RDFXMLDataSourceImpl::Init(const char* uri)
     574             : {
     575           0 :     NS_PRECONDITION(mInner != nullptr, "not initialized");
     576           0 :     if (! mInner)
     577           0 :         return NS_ERROR_OUT_OF_MEMORY;
     578             : 
     579             :     nsresult rv;
     580             : 
     581           0 :     rv = NS_NewURI(getter_AddRefs(mURL), nsDependentCString(uri));
     582           0 :     if (NS_FAILED(rv)) return rv;
     583             : 
     584             :     // XXX this is a hack: any "file:" URI is considered writable. All
     585             :     // others are considered read-only.
     586           0 :     if ((PL_strncmp(uri, kFileURIPrefix, sizeof(kFileURIPrefix) - 1) != 0) &&
     587           0 :         (PL_strncmp(uri, kResourceURIPrefix, sizeof(kResourceURIPrefix) - 1) != 0)) {
     588           0 :         mIsWritable = false;
     589             :     }
     590             : 
     591           0 :     rv = gRDFService->RegisterDataSource(this, false);
     592           0 :     if (NS_FAILED(rv)) return rv;
     593             : 
     594           0 :     return NS_OK;
     595             : }
     596             : 
     597             : 
     598             : NS_IMETHODIMP
     599           0 : RDFXMLDataSourceImpl::GetURI(char* *aURI)
     600             : {
     601           0 :     *aURI = nullptr;
     602           0 :     if (!mURL) {
     603           0 :         return NS_OK;
     604             :     }
     605             : 
     606           0 :     nsAutoCString spec;
     607           0 :     nsresult rv = mURL->GetSpec(spec);
     608           0 :     NS_ENSURE_SUCCESS(rv, rv);
     609           0 :     *aURI = ToNewCString(spec);
     610           0 :     if (!*aURI) {
     611           0 :         return NS_ERROR_OUT_OF_MEMORY;
     612             :     }
     613             : 
     614           0 :     return NS_OK;
     615             : }
     616             : 
     617             : NS_IMETHODIMP
     618           0 : RDFXMLDataSourceImpl::Assert(nsIRDFResource* aSource,
     619             :                              nsIRDFResource* aProperty,
     620             :                              nsIRDFNode* aTarget,
     621             :                              bool aTruthValue)
     622             : {
     623             :     // We don't accept assertions unless we're writable (except in the
     624             :     // case that we're actually _reading_ the datasource in).
     625             :     nsresult rv;
     626             : 
     627           0 :     if (IsLoading()) {
     628           0 :         bool hasAssertion = false;
     629             : 
     630           0 :         nsCOMPtr<nsIRDFPurgeableDataSource> gcable = do_QueryInterface(mInner);
     631           0 :         if (gcable) {
     632           0 :             rv = gcable->Mark(aSource, aProperty, aTarget, aTruthValue, &hasAssertion);
     633           0 :             if (NS_FAILED(rv)) return rv;
     634             :         }
     635             : 
     636           0 :         rv = NS_RDF_ASSERTION_ACCEPTED;
     637             : 
     638           0 :         if (! hasAssertion) {
     639           0 :             rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
     640             : 
     641           0 :             if (NS_SUCCEEDED(rv) && gcable) {
     642             :                 // Now mark the new assertion, so it doesn't get
     643             :                 // removed when we sweep. Ignore rv, because we want
     644             :                 // to return what mInner->Assert() gave us.
     645             :                 bool didMark;
     646           0 :                 (void) gcable->Mark(aSource, aProperty, aTarget, aTruthValue, &didMark);
     647             :             }
     648             : 
     649           0 :             if (NS_FAILED(rv)) return rv;
     650             :         }
     651             : 
     652           0 :         return rv;
     653             :     }
     654           0 :     else if (mIsWritable) {
     655           0 :         rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
     656             : 
     657           0 :         if (rv == NS_RDF_ASSERTION_ACCEPTED)
     658           0 :             mIsDirty = true;
     659             : 
     660           0 :         return rv;
     661             :     }
     662             :     else {
     663           0 :         return NS_RDF_ASSERTION_REJECTED;
     664             :     }
     665             : }
     666             : 
     667             : 
     668             : NS_IMETHODIMP
     669           0 : RDFXMLDataSourceImpl::Unassert(nsIRDFResource* source,
     670             :                                nsIRDFResource* property,
     671             :                                nsIRDFNode* target)
     672             : {
     673             :     // We don't accept assertions unless we're writable (except in the
     674             :     // case that we're actually _reading_ the datasource in).
     675             :     nsresult rv;
     676             : 
     677           0 :     if (IsLoading() || mIsWritable) {
     678           0 :         rv = mInner->Unassert(source, property, target);
     679           0 :         if (!IsLoading() && rv == NS_RDF_ASSERTION_ACCEPTED)
     680           0 :             mIsDirty = true;
     681             :     }
     682             :     else {
     683           0 :         rv = NS_RDF_ASSERTION_REJECTED;
     684             :     }
     685             : 
     686           0 :     return rv;
     687             : }
     688             : 
     689             : NS_IMETHODIMP
     690           0 : RDFXMLDataSourceImpl::Change(nsIRDFResource* aSource,
     691             :                              nsIRDFResource* aProperty,
     692             :                              nsIRDFNode* aOldTarget,
     693             :                              nsIRDFNode* aNewTarget)
     694             : {
     695             :     nsresult rv;
     696             : 
     697           0 :     if (IsLoading() || mIsWritable) {
     698           0 :         rv = mInner->Change(aSource, aProperty, aOldTarget, aNewTarget);
     699             : 
     700           0 :         if (!IsLoading() && rv == NS_RDF_ASSERTION_ACCEPTED)
     701           0 :             mIsDirty = true;
     702             :     }
     703             :     else {
     704           0 :         rv = NS_RDF_ASSERTION_REJECTED;
     705             :     }
     706             : 
     707           0 :     return rv;
     708             : }
     709             : 
     710             : NS_IMETHODIMP
     711           0 : RDFXMLDataSourceImpl::Move(nsIRDFResource* aOldSource,
     712             :                            nsIRDFResource* aNewSource,
     713             :                            nsIRDFResource* aProperty,
     714             :                            nsIRDFNode* aTarget)
     715             : {
     716             :     nsresult rv;
     717             : 
     718           0 :     if (IsLoading() || mIsWritable) {
     719           0 :         rv = mInner->Move(aOldSource, aNewSource, aProperty, aTarget);
     720           0 :         if (!IsLoading() && rv == NS_RDF_ASSERTION_ACCEPTED)
     721           0 :             mIsDirty = true;
     722             :     }
     723             :     else {
     724           0 :         rv = NS_RDF_ASSERTION_REJECTED;
     725             :     }
     726             : 
     727           0 :     return rv;
     728             : }
     729             : 
     730             : 
     731             : nsresult
     732           0 : RDFXMLDataSourceImpl::rdfXMLFlush(nsIURI *aURI)
     733             : {
     734             : 
     735             :     nsresult rv;
     736             : 
     737             :     {
     738             :         // Quick and dirty check to see if we're in XPCOM shutdown. If
     739             :         // we are, we're screwed: it's too late to serialize because
     740             :         // many of the services that we'll need to acquire to properly
     741             :         // write the file will be unaquirable.
     742           0 :         NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
     743           0 :         nsCOMPtr<nsIRDFService> dummy = do_GetService(kRDFServiceCID, &rv);
     744           0 :         if (NS_FAILED(rv)) {
     745           0 :             NS_WARNING("unable to Flush() dirty datasource during XPCOM shutdown");
     746           0 :             return rv;
     747             :         }
     748             :     }
     749             : 
     750             :     // Is it a file? If so, we can write to it. Some day, it'd be nice
     751             :     // if we didn't care what kind of stream this was...
     752           0 :     nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI);
     753             : 
     754           0 :     if (fileURL) {
     755           0 :         nsCOMPtr<nsIFile> file;
     756           0 :         fileURL->GetFile(getter_AddRefs(file));
     757           0 :         if (file) {
     758             :             // get a safe output stream, so we don't clobber the datasource file unless
     759             :             // all the writes succeeded.
     760           0 :             nsCOMPtr<nsIOutputStream> out;
     761           0 :             rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(out),
     762             :                                                  file,
     763             :                                                  PR_WRONLY | PR_CREATE_FILE,
     764             :                                                  /*octal*/ 0666,
     765             :                                                  0);
     766           0 :             if (NS_FAILED(rv)) return rv;
     767             : 
     768           0 :             nsCOMPtr<nsIOutputStream> bufferedOut;
     769           0 :             rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOut), out, 4096);
     770           0 :             if (NS_FAILED(rv)) return rv;
     771             : 
     772           0 :             rv = Serialize(bufferedOut);
     773           0 :             if (NS_FAILED(rv)) return rv;
     774             : 
     775             :             // All went ok. Maybe except for problems in Write(), but the stream detects
     776             :             // that for us
     777           0 :             nsCOMPtr<nsISafeOutputStream> safeStream = do_QueryInterface(bufferedOut, &rv);
     778           0 :             if (NS_FAILED(rv)) return rv;
     779             : 
     780           0 :             rv = safeStream->Finish();
     781           0 :             if (NS_FAILED(rv)) {
     782           0 :                 NS_WARNING("failed to save datasource file! possible dataloss");
     783           0 :                 return rv;
     784             :             }
     785             :         }
     786             :     }
     787             : 
     788           0 :     return NS_OK;
     789             : }
     790             : 
     791             : 
     792             : NS_IMETHODIMP
     793           0 : RDFXMLDataSourceImpl::FlushTo(const char *aURI)
     794             : {
     795           0 :     NS_PRECONDITION(aURI != nullptr, "not initialized");
     796           0 :     if (!aURI)
     797           0 :         return NS_ERROR_NULL_POINTER;
     798             : 
     799             :     // XXX this is a hack: any "file:" URI is considered writable. All
     800             :     // others are considered read-only.
     801           0 :     if ((PL_strncmp(aURI, kFileURIPrefix, sizeof(kFileURIPrefix) - 1) != 0) &&
     802           0 :         (PL_strncmp(aURI, kResourceURIPrefix, sizeof(kResourceURIPrefix) - 1) != 0))
     803             :     {
     804           0 :         return NS_ERROR_ILLEGAL_VALUE;
     805             :     }
     806             : 
     807           0 :     nsCOMPtr<nsIURI>  url;
     808           0 :     nsresult rv = NS_NewURI(getter_AddRefs(url), aURI);
     809           0 :     if (NS_FAILED(rv))
     810           0 :       return rv;
     811           0 :     rv = rdfXMLFlush(url);
     812           0 :     return rv;
     813             : }
     814             : 
     815             : 
     816             : NS_IMETHODIMP
     817           0 : RDFXMLDataSourceImpl::Flush(void)
     818             : {
     819           0 :     if (!mIsWritable || !mIsDirty)
     820           0 :         return NS_OK;
     821             : 
     822             :     // while it is not fatal if mURL is not set,
     823             :     // indicate failure since we can't flush back to an unknown origin
     824           0 :     if (! mURL)
     825           0 :         return NS_ERROR_NOT_INITIALIZED;
     826             : 
     827           0 :     if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) {
     828           0 :       MOZ_LOG(gLog, LogLevel::Debug,
     829             :               ("rdfxml[%p] flush(%s)", this, mURL->GetSpecOrDefault().get()));
     830             :     }
     831             : 
     832             :     nsresult rv;
     833           0 :     if (NS_SUCCEEDED(rv = rdfXMLFlush(mURL)))
     834             :     {
     835           0 :       mIsDirty = false;
     836             :     }
     837           0 :     return rv;
     838             : }
     839             : 
     840             : 
     841             : //----------------------------------------------------------------------
     842             : //
     843             : // nsIRDFXMLDataSource methods
     844             : //
     845             : 
     846             : NS_IMETHODIMP
     847           0 : RDFXMLDataSourceImpl::GetReadOnly(bool* aIsReadOnly)
     848             : {
     849           0 :     *aIsReadOnly = !mIsWritable;
     850           0 :     return NS_OK;
     851             : }
     852             : 
     853             : 
     854             : NS_IMETHODIMP
     855           0 : RDFXMLDataSourceImpl::SetReadOnly(bool aIsReadOnly)
     856             : {
     857           0 :     if (mIsWritable && aIsReadOnly)
     858           0 :         mIsWritable = false;
     859             : 
     860           0 :     return NS_OK;
     861             : }
     862             : 
     863             : // nsIChannelEventSink
     864             : 
     865             : // This code is copied from nsSameOriginChecker::OnChannelRedirect. See
     866             : // bug 475940 on providing this code in a shared location.
     867             : NS_IMETHODIMP
     868           0 : RDFXMLDataSourceImpl::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
     869             :                                              nsIChannel *aNewChannel,
     870             :                                              uint32_t aFlags,
     871             :                                              nsIAsyncVerifyRedirectCallback *cb)
     872             : {
     873           0 :     NS_PRECONDITION(aNewChannel, "Redirecting to null channel?");
     874             : 
     875             :     nsresult rv;
     876             :     nsCOMPtr<nsIScriptSecurityManager> secMan =
     877           0 :         do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
     878           0 :     NS_ENSURE_SUCCESS(rv, rv);
     879             : 
     880           0 :     nsCOMPtr<nsIPrincipal> oldPrincipal;
     881           0 :     secMan->GetChannelResultPrincipal(aOldChannel, getter_AddRefs(oldPrincipal));
     882             : 
     883           0 :     nsCOMPtr<nsIURI> newURI;
     884           0 :     aNewChannel->GetURI(getter_AddRefs(newURI));
     885           0 :     nsCOMPtr<nsIURI> newOriginalURI;
     886           0 :     aNewChannel->GetOriginalURI(getter_AddRefs(newOriginalURI));
     887             : 
     888           0 :     NS_ENSURE_STATE(oldPrincipal && newURI && newOriginalURI);
     889             : 
     890           0 :     rv = oldPrincipal->CheckMayLoad(newURI, false, false);
     891           0 :     if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) {
     892           0 :         rv = oldPrincipal->CheckMayLoad(newOriginalURI, false, false);
     893             :     }
     894             : 
     895           0 :     if (NS_FAILED(rv))
     896           0 :         return rv;
     897             : 
     898           0 :     cb->OnRedirectVerifyCallback(NS_OK);
     899           0 :     return NS_OK;
     900             : }
     901             : 
     902             : NS_IMETHODIMP
     903           0 : RDFXMLDataSourceImpl::Refresh(bool aBlocking)
     904             : {
     905           0 :     nsAutoCString spec;
     906           0 :     if (mURL) {
     907           0 :         spec = mURL->GetSpecOrDefault();
     908             :     }
     909           0 :     MOZ_LOG(gLog, LogLevel::Debug,
     910             :            ("rdfxml[%p] refresh(%s) %sblocking", this, spec.get(), (aBlocking ? "" : "non")));
     911             : 
     912             :     // If an asynchronous load is already pending, then just let it do
     913             :     // the honors.
     914           0 :     if (IsLoading()) {
     915           0 :         MOZ_LOG(gLog, LogLevel::Debug,
     916             :                ("rdfxml[%p] refresh(%s) a load was pending", this, spec.get()));
     917             : 
     918           0 :         if (aBlocking) {
     919           0 :             NS_WARNING("blocking load requested when async load pending");
     920           0 :             return NS_ERROR_FAILURE;
     921             :         }
     922             :         else {
     923           0 :             return NS_OK;
     924             :         }
     925             :     }
     926             : 
     927           0 :     if (! mURL)
     928           0 :         return NS_ERROR_FAILURE;
     929           0 :     nsCOMPtr<nsIRDFXMLParser> parser = do_CreateInstance("@mozilla.org/rdf/xml-parser;1");
     930           0 :     if (! parser)
     931           0 :         return NS_ERROR_FAILURE;
     932             : 
     933           0 :     nsresult rv = parser->ParseAsync(this, mURL, getter_AddRefs(mListener));
     934           0 :     if (NS_FAILED(rv)) return rv;
     935             : 
     936           0 :     if (aBlocking) {
     937           0 :         rv = BlockingParse(mURL, this);
     938             : 
     939           0 :         mListener = nullptr; // release the parser
     940             : 
     941           0 :         if (NS_FAILED(rv)) return rv;
     942             :     }
     943             :     else {
     944             :         // Null LoadGroup ?
     945           0 :         nsCOMPtr<nsIChannel> channel;
     946           0 :         rv = NS_NewChannel(getter_AddRefs(channel),
     947             :                            mURL,
     948             :                            nsContentUtils::GetSystemPrincipal(),
     949             :                            nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
     950             :                            nsIContentPolicy::TYPE_OTHER,
     951             :                            nullptr, // aLoadGroup
     952           0 :                            this);   // aCallbacks
     953           0 :         NS_ENSURE_SUCCESS(rv, rv);
     954           0 :         rv = channel->AsyncOpen2(this);
     955           0 :         NS_ENSURE_SUCCESS(rv, rv);
     956             : 
     957             :         // So we don't try to issue two asynchronous loads at once.
     958           0 :         mLoadState = eLoadState_Pending;
     959             :     }
     960             : 
     961           0 :     return NS_OK;
     962             : }
     963             : 
     964             : NS_IMETHODIMP
     965           0 : RDFXMLDataSourceImpl::BeginLoad(void)
     966             : {
     967           0 :     if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) {
     968           0 :       MOZ_LOG(gLog, LogLevel::Debug,
     969             :               ("rdfxml[%p] begin-load(%s)", this,
     970             :                mURL ? mURL->GetSpecOrDefault().get() : ""));
     971             :     }
     972             : 
     973           0 :     mLoadState = eLoadState_Loading;
     974           0 :     for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
     975             :         // Make sure to hold a strong reference to the observer so
     976             :         // that it doesn't go away in this call if it removes itself
     977             :         // as an observer
     978           0 :         nsCOMPtr<nsIRDFXMLSinkObserver> obs = mObservers[i];
     979             : 
     980           0 :         if (obs) {
     981           0 :             obs->OnBeginLoad(this);
     982             :         }
     983             :     }
     984           0 :     return NS_OK;
     985             : }
     986             : 
     987             : NS_IMETHODIMP
     988           0 : RDFXMLDataSourceImpl::Interrupt(void)
     989             : {
     990           0 :     if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) {
     991           0 :       MOZ_LOG(gLog, LogLevel::Debug,
     992             :               ("rdfxml[%p] interrupt(%s)", this,
     993             :                mURL ? mURL->GetSpecOrDefault().get() : ""));
     994             :     }
     995             : 
     996           0 :     for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
     997             :         // Make sure to hold a strong reference to the observer so
     998             :         // that it doesn't go away in this call if it removes itself
     999             :         // as an observer
    1000           0 :         nsCOMPtr<nsIRDFXMLSinkObserver> obs = mObservers[i];
    1001             : 
    1002           0 :         if (obs) {
    1003           0 :             obs->OnInterrupt(this);
    1004             :         }
    1005             :     }
    1006           0 :     return NS_OK;
    1007             : }
    1008             : 
    1009             : NS_IMETHODIMP
    1010           0 : RDFXMLDataSourceImpl::Resume(void)
    1011             : {
    1012           0 :     if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) {
    1013           0 :       MOZ_LOG(gLog, LogLevel::Debug,
    1014             :              ("rdfxml[%p] resume(%s)", this,
    1015             :               mURL ? mURL->GetSpecOrDefault().get() : ""));
    1016             :     }
    1017             : 
    1018           0 :     for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
    1019             :         // Make sure to hold a strong reference to the observer so
    1020             :         // that it doesn't go away in this call if it removes itself
    1021             :         // as an observer
    1022           0 :         nsCOMPtr<nsIRDFXMLSinkObserver> obs = mObservers[i];
    1023             : 
    1024           0 :         if (obs) {
    1025           0 :             obs->OnResume(this);
    1026             :         }
    1027             :     }
    1028           0 :     return NS_OK;
    1029             : }
    1030             : 
    1031             : NS_IMETHODIMP
    1032           0 : RDFXMLDataSourceImpl::EndLoad(void)
    1033             : {
    1034           0 :     if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) {
    1035           0 :       MOZ_LOG(gLog, LogLevel::Debug,
    1036             :               ("rdfxml[%p] end-load(%s)", this,
    1037             :                mURL ? mURL->GetSpecOrDefault().get() : ""));
    1038             :     }
    1039             : 
    1040           0 :     mLoadState = eLoadState_Loaded;
    1041             : 
    1042             :     // Clear out any unmarked assertions from the datasource.
    1043           0 :     nsCOMPtr<nsIRDFPurgeableDataSource> gcable = do_QueryInterface(mInner);
    1044           0 :     if (gcable) {
    1045           0 :         gcable->Sweep();
    1046             :     }
    1047             : 
    1048             :     // Notify load observers
    1049           0 :     for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
    1050             :         // Make sure to hold a strong reference to the observer so
    1051             :         // that it doesn't go away in this call if it removes itself
    1052             :         // as an observer
    1053           0 :         nsCOMPtr<nsIRDFXMLSinkObserver> obs = mObservers[i];
    1054             : 
    1055           0 :         if (obs) {
    1056           0 :             obs->OnEndLoad(this);
    1057             :         }
    1058             :     }
    1059           0 :     return NS_OK;
    1060             : }
    1061             : 
    1062             : NS_IMETHODIMP
    1063           0 : RDFXMLDataSourceImpl::AddNameSpace(nsIAtom* aPrefix, const nsString& aURI)
    1064             : {
    1065           0 :     mNameSpaces.Put(aURI, aPrefix);
    1066           0 :     return NS_OK;
    1067             : }
    1068             : 
    1069             : 
    1070             : NS_IMETHODIMP
    1071           0 : RDFXMLDataSourceImpl::AddXMLSinkObserver(nsIRDFXMLSinkObserver* aObserver)
    1072             : {
    1073           0 :     if (! aObserver)
    1074           0 :         return NS_ERROR_NULL_POINTER;
    1075             : 
    1076           0 :     mObservers.AppendObject(aObserver);
    1077           0 :     return NS_OK;
    1078             : }
    1079             : 
    1080             : NS_IMETHODIMP
    1081           0 : RDFXMLDataSourceImpl::RemoveXMLSinkObserver(nsIRDFXMLSinkObserver* aObserver)
    1082             : {
    1083           0 :     if (! aObserver)
    1084           0 :         return NS_ERROR_NULL_POINTER;
    1085             : 
    1086           0 :     mObservers.RemoveObject(aObserver);
    1087             : 
    1088           0 :     return NS_OK;
    1089             : }
    1090             : 
    1091             : 
    1092             : //----------------------------------------------------------------------
    1093             : //
    1094             : // nsIRequestObserver
    1095             : //
    1096             : 
    1097             : NS_IMETHODIMP
    1098           0 : RDFXMLDataSourceImpl::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
    1099             : {
    1100           0 :     return mListener->OnStartRequest(request, ctxt);
    1101             : }
    1102             : 
    1103             : NS_IMETHODIMP
    1104           0 : RDFXMLDataSourceImpl::OnStopRequest(nsIRequest *request,
    1105             :                                     nsISupports *ctxt,
    1106             :                                     nsresult status)
    1107             : {
    1108           0 :     if (NS_FAILED(status)) {
    1109           0 :         for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
    1110             :             // Make sure to hold a strong reference to the observer so
    1111             :             // that it doesn't go away in this call if it removes
    1112             :             // itself as an observer
    1113           0 :             nsCOMPtr<nsIRDFXMLSinkObserver> obs = mObservers[i];
    1114             : 
    1115           0 :             if (obs) {
    1116           0 :                 obs->OnError(this, status, nullptr);
    1117             :             }
    1118             :         }
    1119             :     }
    1120             : 
    1121             :     nsresult rv;
    1122           0 :     rv = mListener->OnStopRequest(request, ctxt, status);
    1123             : 
    1124           0 :     mListener = nullptr; // release the parser
    1125             : 
    1126           0 :     return rv;
    1127             : }
    1128             : 
    1129             : //----------------------------------------------------------------------
    1130             : //
    1131             : // nsIStreamListener
    1132             : //
    1133             : 
    1134             : NS_IMETHODIMP
    1135           0 : RDFXMLDataSourceImpl::OnDataAvailable(nsIRequest *request,
    1136             :                                       nsISupports *ctxt,
    1137             :                                       nsIInputStream *inStr,
    1138             :                                       uint64_t sourceOffset,
    1139             :                                       uint32_t count)
    1140             : {
    1141           0 :     return mListener->OnDataAvailable(request, ctxt, inStr, sourceOffset, count);
    1142             : }
    1143             : 
    1144             : //----------------------------------------------------------------------
    1145             : //
    1146             : // nsIRDFXMLSource
    1147             : //
    1148             : 
    1149             : NS_IMETHODIMP
    1150           0 : RDFXMLDataSourceImpl::Serialize(nsIOutputStream* aStream)
    1151             : {
    1152             :     nsresult rv;
    1153             :     nsCOMPtr<nsIRDFXMLSerializer> serializer
    1154           0 :         = do_CreateInstance("@mozilla.org/rdf/xml-serializer;1", &rv);
    1155             : 
    1156           0 :     if (! serializer)
    1157           0 :         return rv;
    1158             : 
    1159           0 :     rv = serializer->Init(this);
    1160           0 :     if (NS_FAILED(rv)) return rv;
    1161             : 
    1162             :     // Add any namespace information that we picked up when reading
    1163             :     // the RDF/XML
    1164           0 :     nsNameSpaceMap::const_iterator last = mNameSpaces.last();
    1165           0 :     for (nsNameSpaceMap::const_iterator iter = mNameSpaces.first();
    1166             :          iter != last; ++iter) {
    1167             :         // We might wanna change nsIRDFXMLSerializer to nsACString and
    1168             :         // use a heap allocated buffer here in the future.
    1169           0 :         NS_ConvertUTF8toUTF16 uri(iter->mURI);
    1170           0 :         serializer->AddNameSpace(iter->mPrefix, uri);
    1171             :     }
    1172             : 
    1173             :     // Serialize!
    1174           0 :     nsCOMPtr<nsIRDFXMLSource> source = do_QueryInterface(serializer);
    1175           0 :     if (! source)
    1176           0 :         return NS_ERROR_FAILURE;
    1177             : 
    1178           0 :     return source->Serialize(aStream);
    1179             : }

Generated by: LCOV version 1.13