1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef NS_EXPAT_DRIVER__
7 #define NS_EXPAT_DRIVER__
8 
9 #include "expat_config.h"
10 #include "expat.h"
11 #include "nsCOMPtr.h"
12 #include "nsString.h"
13 #include "nsIDTD.h"
14 #include "nsITokenizer.h"
15 #include "nsIInputStream.h"
16 #include "nsIParser.h"
17 #include "nsCycleCollectionParticipant.h"
18 
19 class nsIExpatSink;
20 class nsIExtendedExpatSink;
21 struct nsCatalogData;
22 
23 class nsExpatDriver : public nsIDTD,
24                       public nsITokenizer
25 {
26   virtual ~nsExpatDriver();
27 
28 public:
29   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
30   NS_DECL_NSIDTD
31   NS_DECL_NSITOKENIZER
32   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsExpatDriver, nsIDTD)
33 
34   nsExpatDriver();
35 
36   int HandleExternalEntityRef(const char16_t *aOpenEntityNames,
37                               const char16_t *aBase,
38                               const char16_t *aSystemId,
39                               const char16_t *aPublicId);
40   nsresult HandleStartElement(const char16_t *aName, const char16_t **aAtts);
41   nsresult HandleEndElement(const char16_t *aName);
42   nsresult HandleCharacterData(const char16_t *aCData, const uint32_t aLength);
43   nsresult HandleComment(const char16_t *aName);
44   nsresult HandleProcessingInstruction(const char16_t *aTarget,
45                                        const char16_t *aData);
46   nsresult HandleXMLDeclaration(const char16_t *aVersion,
47                                 const char16_t *aEncoding,
48                                 int32_t aStandalone);
49   nsresult HandleDefault(const char16_t *aData, const uint32_t aLength);
50   nsresult HandleStartCdataSection();
51   nsresult HandleEndCdataSection();
52   nsresult HandleStartDoctypeDecl(const char16_t* aDoctypeName,
53                                   const char16_t* aSysid,
54                                   const char16_t* aPubid,
55                                   bool aHasInternalSubset);
56   nsresult HandleEndDoctypeDecl();
57   nsresult HandleStartNamespaceDecl(const char16_t* aPrefix,
58                                     const char16_t* aUri);
59   nsresult HandleEndNamespaceDecl(const char16_t* aPrefix);
60   nsresult HandleNotationDecl(const char16_t* aNotationName,
61                               const char16_t* aBase,
62                               const char16_t* aSysid,
63                               const char16_t* aPubid);
64   nsresult HandleUnparsedEntityDecl(const char16_t* aEntityName,
65                                     const char16_t* aBase,
66                                     const char16_t* aSysid,
67                                     const char16_t* aPubid,
68                                     const char16_t* aNotationName);
69 
70 private:
71   // Load up an external stream to get external entity information
72   nsresult OpenInputStreamFromExternalDTD(const char16_t* aFPIStr,
73                                           const char16_t* aURLStr,
74                                           const char16_t* aBaseURL,
75                                           nsIInputStream** aStream,
76                                           nsAString& aAbsURL);
77 
78   /**
79    * Pass a buffer to Expat. If Expat is blocked aBuffer should be null and
80    * aLength should be 0. The result of the call will be stored in
81    * mInternalState. Expat will parse as much of the buffer as it can and store
82    * the rest in its internal buffer.
83    *
84    * @param aBuffer the buffer to pass to Expat. May be null.
85    * @param aLength the length of the buffer to pass to Expat (in number of
86    *                char16_t's). Must be 0 if aBuffer is null and > 0 if
87    *                aBuffer is not null.
88    * @param aIsFinal whether there will definitely not be any more new buffers
89    *                 passed in to ParseBuffer
90    * @param aConsumed [out] the number of PRUnichars that Expat consumed. This
91    *                        doesn't include the PRUnichars that Expat stored in
92    *                        its buffer but didn't parse yet.
93    */
94   void ParseBuffer(const char16_t *aBuffer, uint32_t aLength, bool aIsFinal,
95                    uint32_t *aConsumed);
96   nsresult HandleError();
97 
98   void MaybeStopParser(nsresult aState);
99 
BlockedOrInterrupted()100   bool BlockedOrInterrupted()
101   {
102     return mInternalState == NS_ERROR_HTMLPARSER_BLOCK ||
103            mInternalState == NS_ERROR_HTMLPARSER_INTERRUPTED;
104   }
105 
106   XML_Parser       mExpatParser;
107   nsString         mLastLine;
108   nsString         mCDataText;
109   // Various parts of a doctype
110   nsString         mDoctypeName;
111   nsString         mSystemID;
112   nsString         mPublicID;
113   nsString         mInternalSubset;
114   bool             mInCData;
115   bool             mInInternalSubset;
116   bool             mInExternalDTD;
117   bool             mMadeFinalCallToExpat;
118 
119   // Whether we're sure that we won't be getting more buffers to parse from
120   // Necko
121   bool             mIsFinalChunk;
122 
123   nsresult         mInternalState;
124 
125   // The length of the data in Expat's buffer (in number of PRUnichars).
126   uint32_t         mExpatBuffered;
127 
128   // These sinks all refer the same conceptual object. mOriginalSink is
129   // identical with the nsIContentSink* passed to WillBuildModel, and exists
130   // only to avoid QI-ing back to nsIContentSink*.
131   nsCOMPtr<nsIContentSink> mOriginalSink;
132   nsCOMPtr<nsIExpatSink> mSink;
133   nsCOMPtr<nsIExtendedExpatSink> mExtendedSink;
134 
135   const nsCatalogData* mCatalogData; // weak
136   nsString         mURISpec;
137 
138   // Used for error reporting.
139   uint64_t         mInnerWindowID;
140 };
141 
142 #endif
143