FDO API Reference Feature Data Objects

Reader.h

Go to the documentation of this file.
00001 #ifndef FDO_XML_READER_H
00002 #define FDO_XML_READER_H
00003 // 
00004 
00005 //
00006 // Copyright (C) 2004-2006  Autodesk, Inc.
00007 // 
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of version 2.1 of the GNU Lesser
00010 // General Public License as published by the Free Software Foundation.
00011 // 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 // Lesser General Public License for more details.
00016 // 
00017 // You should have received a copy of the GNU Lesser General Public
00018 // License along with this library; if not, write to the Free Software
00019 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 //
00021 
00022 
00023 #include <FdoCommon.h>
00024 #include <Common/Stack.h>
00025 
00026 /// \brief
00027 /// FdoXmlReader reads an XML document from a text or binary stream. As various
00028 /// document fragments are read, it calls the appropriate SAX Handler callback on 
00029 /// the current SAX Handler. This object maintains a stack of SAX Handlers, with the 
00030 /// current one being the top handler in the stack. Callers provide this object with
00031 /// SAX Handlers to customize the processing of the XML document.
00032 /// FdoSAXHandler callbacks also provide a means to push other handlers onto the stack.
00033 /// For example, a SAX Handler for a particular XML element might push another handler
00034 /// to read a particular sub-element.
00035 class FdoXmlReader : public FdoDisposable
00036 {
00037 public:
00038     /// \brief
00039     /// Constructs an XML reader on a file
00040     /// 
00041     /// \param fileName 
00042     /// Input name of the file to read.
00043     /// 
00044     /// \return
00045     /// Returns FdoXmlReader
00046     /// 
00047     FDO_API_COMMON static FdoXmlReader* Create( FdoString* fileName );
00048 
00049     /// \brief
00050     /// Constructs an XML reader on a stream
00051     /// 
00052     /// \param stream 
00053     /// Input the stream to read.
00054     /// 
00055     /// \return
00056     /// Returns FdoXmlReader
00057     /// 
00058     FDO_API_COMMON static FdoXmlReader* Create( FdoIoStream* stream );
00059 
00060     /// \brief
00061     /// Constructs an XML reader on a text reader
00062     /// 
00063     /// \param reader 
00064     /// Input the text reader.
00065     /// 
00066     /// \return
00067     /// Returns FdoXmlReader
00068     /// 
00069     FDO_API_COMMON static FdoXmlReader* Create( FdoIoTextReader* reader );
00070 
00071     /// \brief
00072     /// Gets the underlying text reader. If a text reader was passed to this object
00073     /// then this text reader is returned.
00074     /// Otherwise, an auto-generated text reader is returned (a text reader
00075     /// wrapped around the file name or stream that was passed to this object)
00076     /// 
00077     /// \return
00078     /// Returns the underlying text reader
00079     /// 
00080     FDO_API_COMMON FdoIoTextReader* GetTextReader();
00081 
00082     /// \brief
00083     /// Gets the underlying stream. If a text reader was passed to this object
00084     /// then the stream for this text reader is returned.
00085     /// If a stream was passed to this object then this stream is returned.
00086     /// If a file name as passed then a auto-generated stream (wrapped around
00087     /// the file) is returned.
00088     /// 
00089     /// \return
00090     /// Returns the underlying stream
00091     /// 
00092     FDO_API_COMMON FdoIoStream* GetStream();
00093 
00094     /// \brief
00095     /// Parses the XML document.
00096     /// 
00097     /// \param saxHandler 
00098     /// Input SAX Handler to receive the FdoMathUtility events.
00099     /// This object is pushed onto the SAX Handler stack when parse() starts and popped
00100     /// when parse() is finished. If NULL then no handler is pushed, meaning that
00101     /// the current top SAX Handler receives the events. If saxHander is NULL
00102     /// and there is on current top SAX Handler then this function does a 
00103     /// parse and reports syntax errors, but does no semantic processing.
00104     /// \param saxContext 
00105     /// Input Caller-specific contextual information that is 
00106     /// pass to all SAX callbacks.
00107     /// \param incremental 
00108     /// Input 
00109     /// true: an incremental (progressive) parse is performed. The first call 
00110     /// to FdoXmlReader::Parse() causes the XML document to be read from the current 
00111     /// position  until the FdoXmlSaxHandler::EndElement() callback returns false 
00112     /// or the end of the document is reached. On subsequent calls to Parse() the 
00113     /// read continues where the previous call left off. 
00114     /// false: the whole document is parsed in a single call to FdoXmlReader::Parse(). 
00115     /// The FdoXmlSaxHandler::EndElement() return value is ignored. If a previous call 
00116     /// was made to FdoXmlReader::Parse(), with incremental = true, then the rest of the 
00117     /// document is parsed ( the EndElement() return value is ignored ).
00118     /// 
00119     /// \return
00120     /// Returns true if the end of the document has not yet been reached
00121     /// 
00122     FDO_API_COMMON virtual FdoBoolean Parse(
00123         FdoXmlSaxHandler* saxHandler = NULL, 
00124         FdoXmlSaxContext* saxContext = NULL, 
00125         FdoBoolean incremental = false
00126     ) = 0;
00127 
00128     /// \brief
00129     /// Utility function that is typically called for element names or 
00130     /// name type attributes that were adjusted when they were written to XML. 
00131     /// FDO names that correspond to XML names, but aren't valid XML names, are 
00132     /// adjusted. This function undoes the name adjustment.
00133     /// 
00134     /// \param name 
00135     /// Input the name to decode.
00136     /// 
00137     /// \return
00138     /// Returns the decoded name.
00139     /// 
00140     FDO_API_COMMON virtual FdoStringP DecodeName ( FdoStringP name ) = 0;
00141 
00142     /// \brief
00143     /// Indicates whether the end of the XML document has been reached.
00144     /// 
00145     /// \return
00146     /// Returns true if this reader is at the end of the document, false otherwise
00147     /// 
00148     FDO_API_COMMON FdoBoolean GetEOD();
00149 
00150     /// \brief
00151     /// Returns all of the XML namespace declarations that are currently
00152     /// in-scope for the current position in the XML document being read.
00153     /// 
00154     /// \return
00155     /// Returns FdoDictionary. The dictionary has one FdoDictionaryElement
00156     /// entry per namespace declaration. FdoDictionaryElement->GetName() returns
00157     /// the namespace prefix. FdoDictionaryElement->GetValue() returns the URI.
00158     /// 
00159     FDO_API_COMMON FdoDictionary* GetNamespaces();
00160 
00161     /// \brief
00162     /// Gets the URI for a namespace prefix.
00163     /// 
00164     /// \param prefix 
00165     /// Input the namespace prefix.
00166     /// 
00167     /// \return
00168     /// Returns the URI; L"" if the prefix is not in-scope at the
00169     /// current position in the XML document.
00170     /// 
00171     FDO_API_COMMON FdoString* PrefixToUri( FdoString* prefix );
00172 
00173 protected:
00174 /// \cond DOXYGEN-IGNORE
00175     FdoXmlReader() {}
00176     FdoXmlReader( FdoIoTextReader* reader );
00177 
00178     virtual ~FdoXmlReader(void);
00179 
00180     FDO_API_COMMON virtual void Dispose()
00181     {
00182         delete this;
00183     }
00184 
00185     /// \brief
00186     /// Pushes the given object onto the SAX Handler stack. This object will 
00187     /// now receive the SAX events.
00188     /// \param saxHandler 
00189     /// Input the SAX Handler to push.
00190     /// 
00191     void PushSaxHandler( FdoXmlSaxHandler* saxHandler );
00192 
00193     /// \brief
00194     /// Pops the top SAX Handler from the stack.
00195     /// \return
00196     /// Returns the SAX Handler that was popped.
00197     /// 
00198     FdoXmlSaxHandler* PopSaxHandler();
00199 
00200     /// \brief
00201     /// Gets the top SAX Handler from the stack without popping it.
00202     /// \return
00203     /// Returns the top SAX Handler.
00204     /// 
00205     FdoXmlSaxHandler* GetSaxHandler();
00206 
00207 
00208     /// These functions are invoked when various SAX events occur. They delegate these
00209     /// events to the current SAX Handler.
00210     void HandleStartDocument();
00211     void HandleEndDocument();
00212     void HandleStartElement(
00213         FdoString *pUri, 
00214         FdoString *pElementName, 
00215         FdoString *pElementQName, 
00216         FdoXmlAttributeCollection* pAttrs
00217     );
00218     void HandleEndElement(
00219         FdoString *pUri, 
00220         FdoString *pElementName, 
00221         FdoString *pElementQName
00222     );
00223     void HandleStartPrefixMapping(
00224         FdoString *pPrefix,
00225         FdoString *pUri
00226     );
00227     void HandleEndPrefixMapping(
00228         FdoString *pPrefix
00229     );
00230     void HandleCharacters(FdoString *chars);
00231 
00232     /// Sets the SAX Context for the current parse. 
00233     /// The SAX Context is passed to all FdoMathUtility callbacks.
00234     void SetSaxContext( FdoXmlSaxContext* saxContext );
00235 
00236     //Various functions for incremental parsing.
00237 
00238     /// true if parse must be stopped.
00239     FdoBoolean GetStopParse();
00240     /// set to true when parse is to be stopped
00241     void SetStopParse( FdoBoolean stopParse );
00242 
00243     /// true if the first parse has been performed
00244     FdoBoolean GetParsed();
00245     /// set to true when the first parse has been performed
00246     void SetParsed();
00247 /// \endcond
00248 
00249 private:
00250 
00251     /// SAX Handler stack element. Wraps around a SAX Handler.
00252     class StackElement : public FdoDisposable 
00253     {
00254     public:
00255         static StackElement* Create( FdoXmlSaxHandler* pHandler );
00256 
00257         FdoXmlSaxHandler* GetHandler()
00258         {
00259             return mpHandler;
00260         }
00261     
00262     protected:
00263         StackElement();
00264         StackElement( FdoXmlSaxHandler* pHandler );
00265         virtual ~StackElement() {}
00266 
00267     private:
00268         FdoXmlSaxHandler* mpHandler;
00269     };
00270 
00271     typedef FdoPtr<StackElement> StackElementP;
00272     
00273     /// SAX Handler stack definition.
00274     class HandlerStack : public FdoStack<StackElement,FdoXmlException>
00275     {
00276     public:
00277         static HandlerStack* Create() {return new HandlerStack();}
00278 
00279     protected:
00280         HandlerStack() {}
00281         ~HandlerStack() {}
00282         virtual void Dispose()
00283         {
00284             delete this;
00285         }
00286 
00287     };
00288 
00289     /// Tracks the scoped URI's for an XML namespace prefix
00290     class PrefixMapping : public FdoDisposable 
00291     {
00292     public:
00293         static PrefixMapping* Create( FdoString* pPrefix );
00294 
00295         FdoString* GetName();
00296 
00297         FdoString* GetUri();
00298 
00299     /// Called when a different URI comes into scope for this prefix
00300         void PushUri( FdoString* pUri );
00301 
00302     /// Called when current URI goes out of scope
00303         void PopUri();
00304 
00305         FdoBoolean CanSetName()
00306         {
00307             return false;
00308         }
00309     
00310     protected:
00311         PrefixMapping() {}
00312         PrefixMapping( FdoString* pPrefix );
00313         virtual ~PrefixMapping() {}
00314 
00315     private:
00316         FdoStringP mPrefix;
00317         FdoStringsP mUriStack;
00318     };
00319 
00320     typedef FdoPtr<PrefixMapping> PrefixMappingP;
00321     
00322     /// SAX Handler stack definition.
00323     class PrefixMappingCollection : public FdoNamedCollection<PrefixMapping,FdoXmlException>
00324     {
00325     public:
00326         static PrefixMappingCollection* Create() {return new PrefixMappingCollection();}
00327 
00328     protected:
00329         PrefixMappingCollection() {}
00330         ~PrefixMappingCollection() {}
00331         virtual void Dispose()
00332         {
00333             delete this;
00334         }
00335 
00336     };
00337 
00338     /// SAX handler stack
00339     FdoPtr<HandlerStack> mHandlerStack;
00340 
00341     /// current namespace prefixes.
00342     FdoPtr<PrefixMappingCollection> mPrefixes;
00343 
00344     /// Underlying text reader.
00345     FdoIoTextReaderP mTextReader;
00346 
00347     FdoBoolean mStopParse;
00348     FdoBoolean mParsed;
00349     FdoBoolean mEOD;
00350 
00351     FdoXmlSaxContextP mSaxContext;
00352 };
00353 
00354 /// \brief
00355 /// FdoXmlReaderP is a FdoPtr on FdoXmlReader, provided for convenience.
00356 typedef FdoPtr<FdoXmlReader> FdoXmlReaderP;
00357 
00358 #endif
00359 
00360 

Comments or suggestions? Send us feedback.