summaryrefslogtreecommitdiff
path: root/gpr/source/lib/xmp_core/XMLParserAdapter.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'gpr/source/lib/xmp_core/XMLParserAdapter.hpp')
-rw-r--r--gpr/source/lib/xmp_core/XMLParserAdapter.hpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/gpr/source/lib/xmp_core/XMLParserAdapter.hpp b/gpr/source/lib/xmp_core/XMLParserAdapter.hpp
new file mode 100644
index 0000000..ff9b877
--- /dev/null
+++ b/gpr/source/lib/xmp_core/XMLParserAdapter.hpp
@@ -0,0 +1,155 @@
+#ifndef __XMLParserAdapter_hpp__
+#define __XMLParserAdapter_hpp__
+
+// =================================================================================================
+// Copyright 2005 Adobe Systems Incorporated
+// All Rights Reserved.
+//
+// NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+#include "public/include/XMP_Environment.h" // ! Must be the first #include!
+#include "public/include/XMP_Const.h"
+
+#include "XMP_LibUtils.hpp"
+
+#include <string>
+#include <vector>
+
+// =================================================================================================
+// XML_Node details
+//
+// The XML_Nodes are used only during the XML/RDF parsing process. This presently uses an XML parser
+// to create an XML tree, then a recursive descent RDF recognizer to build the corresponding XMP.
+// This makes it easier to swap XML parsers and provides a clean separation of XML and RDF issues.
+// The overall parsing would be faster and use less memory if the RDF recognition were done on the
+// fly using a state machine. But it was much easier to write the recursive descent version. The
+// current implementation is pretty fast in absolute terms, so being faster might not be crucial.
+//
+// Like the XMP tree, the XML tree contains vectors of pointers for down links, and offspring have
+// a pointer to their parent. Unlike the XMP tree, this is an exact XML document tree. There are no
+// introduced top level namespace nodes or rearrangement of the nodes..
+//
+// The exact state of namespaces can vary during the XML parsing, depending on the parser in use.
+// By the time the RDF recognition is done though, the namespaces must be normalized. All of the
+// used namespaces must be registered, this is done automatically if necessary. All of the "live"
+// namespace prefixes will be unique. The ns field of an XML_Node is the namespace URI, the name
+// field contains a qualified name (prefix:local). This includes default namespace mapping, the
+// URI and prefix will be missing only for elements and attributes in no namespace.
+
+class XML_Node;
+
+typedef XML_Node * XML_NodePtr; // Handy for things like: XML_Node * a, b; - b is XML_Node, not XML_Node*!
+
+enum { kRootNode = 0, kElemNode = 1, kAttrNode = 2, kCDataNode = 3, kPINode = 4 };
+
+#define IsWhitespaceChar(ch) ( ((ch) == ' ') || ((ch) == 0x09) || ((ch) == 0x0A) || ((ch) == 0x0D) )
+
+typedef std::vector<XML_NodePtr> XML_NodeVector;
+typedef XML_NodeVector::iterator XML_NodePos;
+typedef XML_NodeVector::const_iterator XML_cNodePos;
+
+#if 0 // Pattern for iterating over the children or attributes:
+ for ( size_t xxNum = 0, xxLim = _node_->_offspring_.size(); xxNum < xxLim; ++xxNum ) {
+ const XML_NodePtr _curr_ = _node_->_offspring_[xxNum];
+ }
+#endif
+
+class XML_Node {
+public:
+
+ // Intended for lightweight internal use. Clients are expected to use the data directly.
+
+ XMP_Uns8 kind;
+ std::string ns, name, value;
+ size_t nsPrefixLen;
+ XML_NodePtr parent;
+ XML_NodeVector attrs;
+ XML_NodeVector content;
+
+ bool IsWhitespaceNode() const;
+ bool IsLeafContentNode() const; // An empty element or one with a single character data child node.
+ bool IsEmptyLeafNode() const;
+
+ XMP_StringPtr GetAttrValue ( XMP_StringPtr attrName ) const;
+ void SetAttrValue ( XMP_StringPtr attrName, XMP_StringPtr attrValue );
+
+ XMP_StringPtr GetLeafContentValue() const;
+ std::string* GetLeafContentPtr() const;
+ void SetLeafContentValue ( XMP_StringPtr value );
+
+ size_t CountNamedElements ( XMP_StringPtr nsURI, XMP_StringPtr localName ) const; // Number of child elements with this name.
+ XML_NodePtr GetNamedElement ( XMP_StringPtr nsURI, XMP_StringPtr localName, size_t which = 0 );
+
+ void Dump ( std::string * buffer );
+ void Serialize ( std::string * buffer );
+
+ void RemoveAttrs();
+ void RemoveContent();
+ void ClearNode();
+
+ XML_Node ( XML_NodePtr _parent, XMP_StringPtr _name, XMP_Uns8 _kind )
+ : kind(_kind), name(_name), parent(_parent), nsPrefixLen(0) {};
+
+ XML_Node ( XML_NodePtr _parent, const std::string & _name, XMP_Uns8 _kind )
+ : kind(_kind), name(_name), parent(_parent), nsPrefixLen(0) {};
+
+ virtual ~XML_Node() { RemoveAttrs(); RemoveContent(); };
+
+private:
+
+ XML_Node() : kind(0), parent(0) {}; // ! Hidden to make sure parent pointer is always set.
+
+};
+
+// =================================================================================================
+// Abstract base class for XML parser adapters used by the XMP toolkit.
+
+enum { kXMLPendingInputMax = 16 };
+
+class XMLParserAdapter {
+public:
+
+ XMLParserAdapter() : tree(0,"",kRootNode), rootNode(0), rootCount(0),
+ charEncoding(XMP_OptionBits(-1)), pendingCount(0),
+ errorCallback(0)
+ {
+ #if XMP_DebugBuild
+ parseLog = 0;
+ #endif
+ };
+
+ virtual ~XMLParserAdapter() {};
+
+ virtual void ParseBuffer ( const void * buffer, size_t length, bool last ) = 0;
+
+ virtual void SetErrorCallback ( GenericErrorCallback * ec )
+ { this->errorCallback = ec; };
+
+ virtual void NotifyClient ( XMP_ErrorSeverity severity, XMP_Error & error )
+ {
+ if (this->errorCallback)
+ this->errorCallback->NotifyClient( severity, error );
+ }
+
+ XML_Node tree;
+ XML_NodeVector parseStack;
+ XML_NodePtr rootNode;
+ size_t rootCount;
+
+ XMP_OptionBits charEncoding;
+ size_t pendingCount;
+ unsigned char pendingInput[kXMLPendingInputMax]; // Buffered input for character encoding checks.
+
+ GenericErrorCallback * errorCallback; // Set if the relevant XMPCore or XMPFiles object has one.
+
+ #if XMP_DebugBuild
+ FILE * parseLog;
+ #endif
+
+};
+
+// =================================================================================================
+
+#endif // __XMLParserAdapter_hpp__