/* ### * IP: GHIDRA * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /// \file xml.hh /// \brief Lightweight (and incomplete) XML parser for marshaling data to and from the decompiler #ifndef __CPUI_XML__ #define __CPUI_XML__ #include "types.h" #include #include #include #include #include using namespace std; /// \brief The \e attributes for a single XML element /// /// A container for name/value pairs (of strings) for the formal attributes, as collected during parsing. /// This object is used to initialize the Element object but is not part of the final, in memory, DOM model. /// This also holds other properties of the element that are unused in this implementation, /// including the \e namespace URI. class Attributes { static string bogus_uri; ///< A placeholder for the namespace URI that should be attached to the element // static string prefix; string *elementname; ///< The name of the XML element vector name; ///< List of names for each formal XML attribute vector value; ///< List of values for each formal XML attribute public: Attributes(string *el) { elementname = el; } ///< Construct from element name string ~Attributes(void) { for(uint4 i=0;i List; ///< A list of XML elements /// \brief An XML element. A node in the DOM tree. /// /// This is the main node for the in-memory representation of the XML (DOM) tree. class Element { string name; ///< The (local) name of the element string content; ///< Character content of the element vector attr; ///< A list of attribute names for \b this element vector value; ///< a (corresponding) list of attribute values for \b this element protected: Element *parent; ///< The parent Element (or null) List children; ///< A list of child Element objects public: Element(Element *par) { parent = par; } ///< Constructor given a parent Element ~Element(void); ///< Destructor void setName(const string &nm) { name = nm; } ///< Set the local name of the element /// \brief Append new character content to \b this element /// /// \param str is an array of character data /// \param start is the index of the first character to append /// \param length is the number of characters to append void addContent(const char *str,int4 start,int4 length) { // for(int4 i=0;i doclist; ///< The list of documents held by this container map tagmap; ///< The map from name to registered XML elements public: ~DocumentStorage(void); ///< Destructor /// \brief Parse an XML document from the given stream /// /// Parsing starts immediately on the stream, attempting to make an in-memory DOM tree. /// An XmlException is thrown for any parsing error. /// \param s is the given stream to parse /// \return the in-memory DOM tree Document *parseDocument(istream &s); /// \brief Open and parse an XML file /// /// The given filename is opened on the local filesystem and an attempt is made to parse /// its contents into an in-memory DOM tree. An XmlException is thrown for any parsing error. /// \param filename is the name of the XML document file /// \return the in-memory DOM tree Document *openDocument(const string &filename); /// \brief Register the given XML Element object under its tag name /// /// Only one Element can be stored on \b this object per tag name. /// \param el is the given XML element void registerTag(const Element *el); /// \brief Retrieve a registered XML Element by name /// /// \param nm is the XML tag name /// \return the matching registered Element or null const Element *getTag(const string &nm) const; }; /// \brief An exception thrown by the XML parser /// /// This object holds the error message as passed to the SAX interface callback /// and is thrown as a formal exception. struct XmlError { string explain; ///< Explanatory string XmlError(const string &s) { explain = s; } ///< Constructor }; /// \brief Start-up the XML parser given a stream and a handler /// /// This runs the low-level XML parser. /// \param i is the given stream to get character data from /// \param hand is the ContentHandler that stores or processes the XML content events /// \param dbg is non-zero if the parser should output debug information during its parse /// \return 0 if there is no error during parsing or a (non-zero) error condition extern int4 xml_parse(istream &i,ContentHandler *hand,int4 dbg=0); /// \brief Parse the given XML stream into an in-memory document /// /// The stream is parsed using the standard ContentHandler for producing an in-memory /// DOM representation of the XML document. /// \param i is the given stream /// \return the in-memory XML document extern Document *xml_tree(istream &i); /// \brief Send the given character array to a stream, escaping characters with special XML meaning /// /// This makes the following character substitutions: /// - '<' => "<" /// - '>' => ">" /// - '&' => "&" /// - '"' => """ /// - '\'' => "'" /// /// \param s is the stream to write to /// \param str is the given character array to escape extern void xml_escape(ostream &s,const char *str); // Some helper functions for writing XML documents directly to a stream /// \brief Output an XML attribute name/value pair to stream /// /// \param s is the output stream /// \param attr is the name of the attribute /// \param val is the attribute value inline void a_v(ostream &s,const string &attr,const string &val) { s << ' ' << attr << "=\""; xml_escape(s,val.c_str()); s << "\""; } /// \brief Output the given signed integer as an XML attribute value /// /// \param s is the output stream /// \param attr is the name of the attribute /// \param val is the given integer value inline void a_v_i(ostream &s,const string &attr,intb val) { s << ' ' << attr << "=\"" << dec << val << "\""; } /// \brief Output the given unsigned integer as an XML attribute value /// /// \param s is the output stream /// \param attr is the name of the attribute /// \param val is the given unsigned integer value inline void a_v_u(ostream &s,const string &attr,uintb val) { s << ' ' << attr << "=\"0x" << hex << val << "\""; } /// \brief Output the given boolean value as an XML attribute /// /// \param s is the output stream /// \param attr is the name of the attribute /// \param val is the given boolean value inline void a_v_b(ostream &s,const string &attr,bool val) { s << ' ' << attr << "=\""; if (val) s << "true"; else s << "false"; s << "\""; } /// \brief Read an XML attribute value as a boolean /// /// This method is intended to recognize the strings, "true", "yes", and "1" /// as a \b true value. Anything else is returned as \b false. /// \param attr is the given XML attribute value (as a string) /// \return either \b true or \b false inline bool xml_readbool(const string &attr) { if (attr.size()==0) return false; char firstc = attr[0]; if (firstc=='t') return true; if (firstc=='1') return true; if (firstc=='y') return true; // For backward compatibility return false; } #endif