/* **============================================================================== ** ** Open Management Infrastructure (OMI) ** ** Copyright (c) Microsoft Corporation ** ** 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 ** ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABLITY OR NON-INFRINGEMENT. ** ** See the Apache 2 License for the specific language governing permissions ** and limitations under the License. ** **============================================================================== */ #include "xmlcxx.h" #include #include #include #include #include using namespace std; //============================================================================== // // class XMLElement // //============================================================================== XMLCXX_BEGIN class XMLElementRep { public: XML_Elem elem; }; XMLElement::XMLElement() { _rep = new XMLElementRep; Clear(); } XMLElement::XMLElement(const XMLElement& x) { _rep = new XMLElementRep; memcpy(_rep, x._rep, sizeof(XMLElementRep)); } XMLElement::~XMLElement() { delete _rep; } XMLElement& XMLElement::operator=(const XMLElement& x) { if (&x != this) memcpy(_rep, x._rep, sizeof(XMLElementRep)); return *this; } void XMLElement::Clear() { // Element will have XMLElement::NONE type. memset(_rep, 0, sizeof(XMLElementRep)); } XMLElement::Type XMLElement::GetType() const { switch (_rep->elem.type) { case XML_NONE: return NONE; case XML_START: return START; case XML_END: return END; case XML_CHARS: return CHARS; case XML_INSTRUCTION: return INSTRUCTION; case XML_COMMENT: return COMMENT; default: return NONE; } } const char* XMLElement::GetData() const { return _rep->elem.data ? _rep->elem.data : ""; } size_t XMLElement::GetAttributeCount() const { return _rep->elem.attrsSize; } const char* XMLElement::GetAttributeName(size_t index) const { if (index < _rep->elem.attrsSize) return _rep->elem.attrs[index].name; else return NULL; } const char* XMLElement::GetAttributeValue(size_t index) const { if (index < _rep->elem.attrsSize) return _rep->elem.attrs[index].value; else return NULL; } const char* XMLElement::FindAttributeValue(const char* name) const { for (size_t i = 0; i < _rep->elem.attrsSize; i++) { if (strcmp(_rep->elem.attrs[i].name, name) == 0) return _rep->elem.attrs[i].value; } // Not found! return NULL; } void XMLElement::Dump() const { XML_Elem_Dump(&_rep->elem); } XMLCXX_END //============================================================================== // // class XMLReader // //============================================================================== XMLCXX_BEGIN class XMLReaderRep { public: vector text; XML xml; XMLReaderRep() { text.push_back('\0'); XML_Init(&xml); } void SetText(const char* text_) { text.clear(); text.insert(text.end(), text_, text_ + strlen(text_)); text.push_back('\0'); XML_SetText(&xml, &text[0]); } }; XMLReader::XMLReader() { _rep = new XMLReaderRep; } XMLReader::XMLReader(const char* text) { _rep = new XMLReaderRep; _rep->SetText(text); } XMLReader::~XMLReader() { delete _rep; } size_t XMLReader::GetLineNumber() const { return _rep->xml.line; } void XMLReader::SetText(const char* text) { _rep->SetText(text); } bool XMLReader::GetNext(XMLElement& elem) { return XML_Next(&_rep->xml, &elem._rep->elem) == 0 ? true : false; } bool XMLReader::Skip() { return XML_Skip(&_rep->xml) == 0 ? true : false; } bool XMLReader::PutBack(XMLElement& elem) { return XML_PutBack(&_rep->xml, &elem._rep->elem) == 0 ? true : false; } void XMLReader::Dump() const { XML_Dump(&_rep->xml); } string XMLReader::GetErrorMessage() const { char buf[512]; XML_FormatError(&_rep->xml, buf, sizeof(buf)); return string(buf); } void XMLReader::GetErrorMessage(char* buffer, size_t size) { XML_FormatError(&_rep->xml, buffer, size); } bool XMLReader::GetError() const { return _rep->xml.status == -1; } bool XMLReader::RegisterNameSpace(char id, const char* uri) { return XML_RegisterNameSpace(&_rep->xml, id, uri) == 0 ? true : false; } XMLCXX_END //============================================================================== // // class XMLWriter // //============================================================================== XMLCXX_BEGIN class XMLWriterRep { public: Buf buf; bool enableLineSeparators; XMLWriterRep() : enableLineSeparators(false) { Buf_Init(&buf, 4096); } ~XMLWriterRep() { Buf_Destroy(&buf); } }; static const struct { const char* str; size_t len; } _encode[256] = { { "�", sizeof("�")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { " ", sizeof(" ")-1 }, { " ", sizeof(" ")-1 }, { " ", sizeof(" ")-1 }, { " ", sizeof(" ")-1 }, { " ", sizeof(" ")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { " ", sizeof(" ")-1 }, { "!", sizeof("!")-1 }, { """, sizeof(""")-1 }, { "#", sizeof("#")-1 }, { "$", sizeof("$")-1 }, { "%", sizeof("%")-1 }, { "&", sizeof("&")-1 }, { "'", sizeof("'")-1 }, { "(", sizeof("(")-1 }, { ")", sizeof(")")-1 }, { "*", sizeof("*")-1 }, { "+", sizeof("+")-1 }, { ",", sizeof(",")-1 }, { "-", sizeof("-")-1 }, { ".", sizeof(".")-1 }, { "/", sizeof("/")-1 }, { "0", sizeof("0")-1 }, { "1", sizeof("1")-1 }, { "2", sizeof("2")-1 }, { "3", sizeof("3")-1 }, { "4", sizeof("4")-1 }, { "5", sizeof("5")-1 }, { "6", sizeof("6")-1 }, { "7", sizeof("7")-1 }, { "8", sizeof("8")-1 }, { "9", sizeof("9")-1 }, { ":", sizeof(":")-1 }, { ";", sizeof(";")-1 }, { "<", sizeof("<")-1 }, { "=", sizeof("=")-1 }, { ">", sizeof(">")-1 }, { "?", sizeof("?")-1 }, { "@", sizeof("@")-1 }, { "A", sizeof("A")-1 }, { "B", sizeof("B")-1 }, { "C", sizeof("C")-1 }, { "D", sizeof("D")-1 }, { "E", sizeof("E")-1 }, { "F", sizeof("F")-1 }, { "G", sizeof("G")-1 }, { "H", sizeof("H")-1 }, { "I", sizeof("I")-1 }, { "J", sizeof("J")-1 }, { "K", sizeof("K")-1 }, { "L", sizeof("L")-1 }, { "M", sizeof("M")-1 }, { "N", sizeof("N")-1 }, { "O", sizeof("O")-1 }, { "P", sizeof("P")-1 }, { "Q", sizeof("Q")-1 }, { "R", sizeof("R")-1 }, { "S", sizeof("S")-1 }, { "T", sizeof("T")-1 }, { "U", sizeof("U")-1 }, { "V", sizeof("V")-1 }, { "W", sizeof("W")-1 }, { "X", sizeof("X")-1 }, { "Y", sizeof("Y")-1 }, { "Z", sizeof("Z")-1 }, { "[", sizeof("[")-1 }, { "\\", sizeof("\\")-1 }, { "]", sizeof("]")-1 }, { "^", sizeof("^")-1 }, { "_", sizeof("_")-1 }, { "`", sizeof("`")-1 }, { "a", sizeof("a")-1 }, { "b", sizeof("b")-1 }, { "c", sizeof("c")-1 }, { "d", sizeof("d")-1 }, { "e", sizeof("e")-1 }, { "f", sizeof("f")-1 }, { "g", sizeof("g")-1 }, { "h", sizeof("h")-1 }, { "i", sizeof("i")-1 }, { "j", sizeof("j")-1 }, { "k", sizeof("k")-1 }, { "l", sizeof("l")-1 }, { "m", sizeof("m")-1 }, { "n", sizeof("n")-1 }, { "o", sizeof("o")-1 }, { "p", sizeof("p")-1 }, { "q", sizeof("q")-1 }, { "r", sizeof("r")-1 }, { "s", sizeof("s")-1 }, { "t", sizeof("t")-1 }, { "u", sizeof("u")-1 }, { "v", sizeof("v")-1 }, { "w", sizeof("w")-1 }, { "x", sizeof("x")-1 }, { "y", sizeof("y")-1 }, { "z", sizeof("z")-1 }, { "{", sizeof("{")-1 }, { "|", sizeof("|")-1 }, { "}", sizeof("}")-1 }, { "~", sizeof("~")-1 }, { "", sizeof("")-1 }, { "€", sizeof("€")-1 }, { "", sizeof("")-1 }, { "‚", sizeof("‚")-1 }, { "ƒ", sizeof("ƒ")-1 }, { "„", sizeof("„")-1 }, { "…", sizeof("…")-1 }, { "†", sizeof("†")-1 }, { "‡", sizeof("‡")-1 }, { "ˆ", sizeof("ˆ")-1 }, { "‰", sizeof("‰")-1 }, { "Š", sizeof("Š")-1 }, { "‹", sizeof("‹")-1 }, { "Œ", sizeof("Œ")-1 }, { "", sizeof("")-1 }, { "Ž", sizeof("Ž")-1 }, { "", sizeof("")-1 }, { "", sizeof("")-1 }, { "‘", sizeof("‘")-1 }, { "’", sizeof("’")-1 }, { "“", sizeof("“")-1 }, { "”", sizeof("”")-1 }, { "•", sizeof("•")-1 }, { "–", sizeof("–")-1 }, { "—", sizeof("—")-1 }, { "˜", sizeof("˜")-1 }, { "™", sizeof("™")-1 }, { "š", sizeof("š")-1 }, { "›", sizeof("›")-1 }, { "œ", sizeof("œ")-1 }, { "", sizeof("")-1 }, { "ž", sizeof("ž")-1 }, { "Ÿ", sizeof("Ÿ")-1 }, { " ", sizeof(" ")-1 }, { "¡", sizeof("¡")-1 }, { "¢", sizeof("¢")-1 }, { "£", sizeof("£")-1 }, { "¤", sizeof("¤")-1 }, { "¥", sizeof("¥")-1 }, { "¦", sizeof("¦")-1 }, { "§", sizeof("§")-1 }, { "¨", sizeof("¨")-1 }, { "©", sizeof("©")-1 }, { "ª", sizeof("ª")-1 }, { "«", sizeof("«")-1 }, { "¬", sizeof("¬")-1 }, { "­", sizeof("­")-1 }, { "®", sizeof("®")-1 }, { "¯", sizeof("¯")-1 }, { "°", sizeof("°")-1 }, { "±", sizeof("±")-1 }, { "²", sizeof("²")-1 }, { "³", sizeof("³")-1 }, { "´", sizeof("´")-1 }, { "µ", sizeof("µ")-1 }, { "¶", sizeof("¶")-1 }, { "·", sizeof("·")-1 }, { "¸", sizeof("¸")-1 }, { "¹", sizeof("¹")-1 }, { "º", sizeof("º")-1 }, { "»", sizeof("»")-1 }, { "¼", sizeof("¼")-1 }, { "½", sizeof("½")-1 }, { "¾", sizeof("¾")-1 }, { "¿", sizeof("¿")-1 }, { "À", sizeof("À")-1 }, { "Á", sizeof("Á")-1 }, { "Â", sizeof("Â")-1 }, { "Ã", sizeof("Ã")-1 }, { "Ä", sizeof("Ä")-1 }, { "Å", sizeof("Å")-1 }, { "Æ", sizeof("Æ")-1 }, { "Ç", sizeof("Ç")-1 }, { "È", sizeof("È")-1 }, { "É", sizeof("É")-1 }, { "Ê", sizeof("Ê")-1 }, { "Ë", sizeof("Ë")-1 }, { "Ì", sizeof("Ì")-1 }, { "Í", sizeof("Í")-1 }, { "Î", sizeof("Î")-1 }, { "Ï", sizeof("Ï")-1 }, { "Ð", sizeof("Ð")-1 }, { "Ñ", sizeof("Ñ")-1 }, { "Ò", sizeof("Ò")-1 }, { "Ó", sizeof("Ó")-1 }, { "Ô", sizeof("Ô")-1 }, { "Õ", sizeof("Õ")-1 }, { "Ö", sizeof("Ö")-1 }, { "×", sizeof("×")-1 }, { "Ø", sizeof("Ø")-1 }, { "Ù", sizeof("Ù")-1 }, { "Ú", sizeof("Ú")-1 }, { "Û", sizeof("Û")-1 }, { "Ü", sizeof("Ü")-1 }, { "Ý", sizeof("Ý")-1 }, { "Þ", sizeof("Þ")-1 }, { "ß", sizeof("ß")-1 }, { "à", sizeof("à")-1 }, { "á", sizeof("á")-1 }, { "â", sizeof("â")-1 }, { "ã", sizeof("ã")-1 }, { "ä", sizeof("ä")-1 }, { "å", sizeof("å")-1 }, { "æ", sizeof("æ")-1 }, { "ç", sizeof("ç")-1 }, { "è", sizeof("è")-1 }, { "é", sizeof("é")-1 }, { "ê", sizeof("ê")-1 }, { "ë", sizeof("ë")-1 }, { "ì", sizeof("ì")-1 }, { "í", sizeof("í")-1 }, { "î", sizeof("î")-1 }, { "ï", sizeof("ï")-1 }, { "ð", sizeof("ð")-1 }, { "ñ", sizeof("ñ")-1 }, { "ò", sizeof("ò")-1 }, { "ó", sizeof("ó")-1 }, { "ô", sizeof("ô")-1 }, { "õ", sizeof("õ")-1 }, { "ö", sizeof("ö")-1 }, { "÷", sizeof("÷")-1 }, { "ø", sizeof("ø")-1 }, { "ù", sizeof("ù")-1 }, { "ú", sizeof("ú")-1 }, { "û", sizeof("û")-1 }, { "ü", sizeof("ü")-1 }, { "ý", sizeof("ý")-1 }, { "þ", sizeof("þ")-1 }, { "ÿ", sizeof("ÿ")-1 }, }; /* [A-Za-z_] */ static inline bool _IsFirst(char c) { if (isalpha(c) || c == '_') return true; return false; //return (_nameChar[(unsigned int)c] & 2) ? true : false; } /* [A-Za-z0-9_-.:] */ static inline bool _IsInner(char c) { if (isalpha(c) || isdigit(c) || c=='_' || c=='-' || c=='.' || c==':') return true; return false; } static bool _ValidIdentifier(const char* p) { if (!_IsFirst(*p)) return false; p++; while (*p) { if (!_IsInner(*p)) return false; p++; } return true; } static void _PutRaw(XMLWriterRep* rep, const char* str) { size_t len = strlen(str); if (len) Buf_App(&rep->buf, str, len); } static void _PutChars(XMLWriterRep* _rep, const char* str) { const unsigned char* p = reinterpret_cast(str); while (*p) { Buf_App(&_rep->buf, _encode[*p].str, _encode[*p].len); p++; } } // // Helper function to put start tag, empty tag, or processing instruction. // // The 'type' parameter is one of these: // 's' -- start tag // 'e' -- empty tag // 'p' -- processing instruction. // bool _PutTag( XMLWriterRep* _rep, const char* tagName, const std::vector& attrs, char type) { if (!_ValidIdentifier(tagName)) return false; if (type == 'p') _PutRaw(_rep, ""); else if (type == 'e') _PutRaw(_rep, "/>"); else _PutRaw(_rep, ">"); return true; } XMLWriter::XMLWriter() { _rep = new XMLWriterRep(); } XMLWriter::~XMLWriter() { delete _rep; } std::string XMLWriter::GetText() const { return string( reinterpret_cast(_rep->buf.data), _rep->buf.size); } void XMLWriter::EnableLineSeparators() { _rep->enableLineSeparators = true; } void XMLWriter::DisableLineSeparators() { _rep->enableLineSeparators = false; } bool XMLWriter::PutStartTag( const char* tagName, const std::vector& attrs) { if (!_PutTag(_rep, tagName, attrs, 's')) return false; if (_rep->enableLineSeparators) PutLineSeparator(); return true; } bool XMLWriter::PutStartTag(const char* tagName) { vector attrs; if (!_PutTag(_rep, tagName, attrs, 's')) return false; if (_rep->enableLineSeparators) PutLineSeparator(); return true; } bool XMLWriter::PutEmptyTag( const char* tagName, const std::vector& attrs) { if (!_PutTag(_rep, tagName, attrs, 'e')) return false; if (_rep->enableLineSeparators) PutLineSeparator(); return true; } bool XMLWriter::PutProcessingInstruction( const char* tagName, const std::vector& attrs) { if (!_PutTag(_rep, tagName, attrs, 'p')) return false; if (_rep->enableLineSeparators) PutLineSeparator(); return true; } bool XMLWriter::PutEndTag(const char* tagName) { if (!_ValidIdentifier(tagName)) return false; _PutRaw(_rep, ""); if (_rep->enableLineSeparators) PutLineSeparator(); return true; } void XMLWriter::PutCharacterData(const char* str) { _PutChars(_rep, str); if (_rep->enableLineSeparators) PutLineSeparator(); } void XMLWriter::PutComment(const char* str) { _PutRaw(_rep, ""); if (_rep->enableLineSeparators) PutLineSeparator(); } void XMLWriter::PutCDATA(const char* str) { _PutRaw(_rep, ""); if (_rep->enableLineSeparators) PutLineSeparator(); } void XMLWriter::PutLineSeparator() { _PutRaw(_rep, "\r\n"); } XMLCXX_END