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 struct nsCatalogData;
21 
22 class nsExpatDriver : public nsIDTD, public nsITokenizer {
23   virtual ~nsExpatDriver();
24 
25  public:
26   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
27   NS_DECL_NSIDTD
28   NS_DECL_NSITOKENIZER
29   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsExpatDriver, nsIDTD)
30 
31   nsExpatDriver();
32 
33   int HandleExternalEntityRef(const char16_t* aOpenEntityNames,
34                               const char16_t* aBase, const char16_t* aSystemId,
35                               const char16_t* aPublicId);
36   static void HandleStartElement(void* aUserData, const char16_t* aName,
37                                  const char16_t** aAtts);
38   static void HandleStartElementForSystemPrincipal(void* aUserData,
39                                                    const char16_t* aName,
40                                                    const char16_t** aAtts);
41   static void HandleEndElement(void* aUserData, const char16_t* aName);
42   static void HandleEndElementForSystemPrincipal(void* aUserData,
43                                                  const char16_t* aName);
44   nsresult HandleCharacterData(const char16_t* aCData, const uint32_t aLength);
45   nsresult HandleComment(const char16_t* aName);
46   nsresult HandleProcessingInstruction(const char16_t* aTarget,
47                                        const char16_t* aData);
48   nsresult HandleXMLDeclaration(const char16_t* aVersion,
49                                 const char16_t* aEncoding, int32_t aStandalone);
50   nsresult HandleDefault(const char16_t* aData, const uint32_t aLength);
51   nsresult HandleStartCdataSection();
52   nsresult HandleEndCdataSection();
53   nsresult HandleStartDoctypeDecl(const char16_t* aDoctypeName,
54                                   const char16_t* aSysid,
55                                   const char16_t* aPubid,
56                                   bool aHasInternalSubset);
57   nsresult HandleEndDoctypeDecl();
58 
59  private:
60   // Load up an external stream to get external entity information
61   nsresult OpenInputStreamFromExternalDTD(const char16_t* aFPIStr,
62                                           const char16_t* aURLStr,
63                                           const char16_t* aBaseURL,
64                                           nsIInputStream** aStream,
65                                           nsAString& aAbsURL);
66 
67   /**
68    * Pass a buffer to Expat. If Expat is blocked aBuffer should be null and
69    * aLength should be 0. The result of the call will be stored in
70    * mInternalState. Expat will parse as much of the buffer as it can and store
71    * the rest in its internal buffer.
72    *
73    * @param aBuffer the buffer to pass to Expat. May be null.
74    * @param aLength the length of the buffer to pass to Expat (in number of
75    *                char16_t's). Must be 0 if aBuffer is null and > 0 if
76    *                aBuffer is not null.
77    * @param aIsFinal whether there will definitely not be any more new buffers
78    *                 passed in to ParseBuffer
79    * @param aConsumed [out] the number of PRUnichars that Expat consumed. This
80    *                        doesn't include the PRUnichars that Expat stored in
81    *                        its buffer but didn't parse yet.
82    */
83   void ParseBuffer(const char16_t* aBuffer, uint32_t aLength, bool aIsFinal,
84                    uint32_t* aConsumed);
85   nsresult HandleError();
86 
87   void MaybeStopParser(nsresult aState);
88 
BlockedOrInterrupted()89   bool BlockedOrInterrupted() {
90     return mInternalState == NS_ERROR_HTMLPARSER_BLOCK ||
91            mInternalState == NS_ERROR_HTMLPARSER_INTERRUPTED;
92   }
93 
94   XML_Parser mExpatParser;
95   nsString mLastLine;
96   nsString mCDataText;
97   // Various parts of a doctype
98   nsString mDoctypeName;
99   nsString mSystemID;
100   nsString mPublicID;
101   nsString mInternalSubset;
102   bool mInCData;
103   bool mInInternalSubset;
104   bool mInExternalDTD;
105   bool mMadeFinalCallToExpat;
106 
107   // Whether we're sure that we won't be getting more buffers to parse from
108   // Necko
109   bool mIsFinalChunk;
110 
111   nsresult mInternalState;
112 
113   // The length of the data in Expat's buffer (in number of PRUnichars).
114   uint32_t mExpatBuffered;
115 
116   uint16_t mTagDepth;
117 
118   // These sinks all refer the same conceptual object. mOriginalSink is
119   // identical with the nsIContentSink* passed to WillBuildModel, and exists
120   // only to avoid QI-ing back to nsIContentSink*.
121   nsCOMPtr<nsIContentSink> mOriginalSink;
122   nsCOMPtr<nsIExpatSink> mSink;
123 
124   const nsCatalogData* mCatalogData;  // weak
125   nsString mURISpec;
126 
127   // Used for error reporting.
128   uint64_t mInnerWindowID;
129 };
130 
131 #endif
132