Implementing a Custom Parser

Scaleform provides a default parser implementation using the expat library. If the target application already provides an XML parser, it can be plugged into the Scaleform XML subsystem by wrapping the parser in the GFx::XML::Parser interface, which is defined in XML_Support.h. The XML_Parser.h file defines the GFx::XML::ParserHandler class as a SAX2 interface mechanism.

namespace Scaleform { namespace GFx { namespace XML {
// 
// The pluggable XML parser
//
// Creates instances of parsers for each parse file/string call.
// This was added for thread safety. Each parser instance is guaranteed
// to be used within a single thread. An instance of a parser is expected
// by the XML state.
// 
class Parser : public RefCountBaseNTS<Parser, Stat_Default_Mem>
{
  public:    
    virtual ~Parser() {}

    // Parse methods
   
    virtual bool    ParseFile(const char* pfilename, FileOpenerBase* pfo, 
                               ParserHandler* pphandler) = 0;
    virtual bool    ParseString(const char* pdata, UPInt len, 
                                 ParserHandler* pphandler) = 0;
};
}}} //SF::GFx::XML

All XML parser implementations must register a GFx::XML::ParserLocator instance with the DOM builder object passed to the ParseFile and ParseString methods, before any parsing occurs. For all appropriate parsing events, the complementary GFx::XML::ParserHandler callback method should be invoked with the required parameters. If an error occurs, the appropriate error handler method should be invoked based on its severity.

namespace Scaleform { namespace GFx { namespace XML {
//
// SAX2 Consolidated Handler
//
// The DOM builder is an interface similar to a SAX2 parser handler. 
// The parser implementation is expected to call the appropriate callback
// method for certain events.
//
class ParserHandler : public RefCountBase<ParserHandler, StatMV_XML_Mem>
{
  public:
    ParserHandler() {}
    virtual ~ParserHandler() {}

    // Beginning and end of documents
    virtual void        StartDocument() = 0;
    virtual void        EndDocument() = 0;

    // Start and end of a tag element
    virtual void        StartElement(const StringRef& prefix,
                                     const StringRef& localname,
                                     const ParserAttributes& atts) = 0;
    virtual void        EndElement(const StringRef& prefix,
                                   const StringRef& localname) = 0;

    // Namespace declaration. Next element will be the parent of the mappings
    virtual void        PrefixMapping(const StringRef& prefix, 
                                      const StringRef& uri) = 0;
    // Text data, in between tag elements
    virtual void        Characters(const StringRef& text) = 0;

    
    // Whitespace
    virtual void        IgnorableWhitespace(const StringRef& ws) = 0;

    
    // Unprocessed elements
    virtual void        SkippedEntity(const StringRef& name) = 0;

    
    // GFx::XML::Parser implementors are REQURIED to set a document locator
    // before any callbacks occur. GFx::XML::ParserHandler implementations
    // require a locator object for error reporting and correctly processing
    // the encoding, xmlversion and standalone properties.
    virtual void    SetDocumentLocator(const ParserLocator* plocator) = 0;

    // Comments
    virtual void        Comment(const StringRef& text) = 0;

    // ErrorHandler Callbacks
    virtual void        Error(const ParserException& exception) = 0;
    virtual void        FatalError(const ParserException& exception) = 0;
    virtual void        Warning(const ParserException& exception) = 0;
};

}}} //SF::GFx::XML