1e5c31af7Sopenharmony_ci#ifndef _XEXMLPARSER_HPP 2e5c31af7Sopenharmony_ci#define _XEXMLPARSER_HPP 3e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 4e5c31af7Sopenharmony_ci * drawElements Quality Program Test Executor 5e5c31af7Sopenharmony_ci * ------------------------------------------ 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 8e5c31af7Sopenharmony_ci * 9e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 10e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 11e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 14e5c31af7Sopenharmony_ci * 15e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 16e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 17e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 19e5c31af7Sopenharmony_ci * limitations under the License. 20e5c31af7Sopenharmony_ci * 21e5c31af7Sopenharmony_ci *//*! 22e5c31af7Sopenharmony_ci * \file 23e5c31af7Sopenharmony_ci * \brief XML Parser. 24e5c31af7Sopenharmony_ci * 25e5c31af7Sopenharmony_ci * \todo [2012-06-07 pyry] Not supported / handled properly: 26e5c31af7Sopenharmony_ci * - xml namespaces (<ns:Element>) 27e5c31af7Sopenharmony_ci * - backslash escapes in strings 28e5c31af7Sopenharmony_ci * - " -style escapes 29e5c31af7Sopenharmony_ci * - utf-8 30e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ci#include "xeDefs.hpp" 33e5c31af7Sopenharmony_ci#include "deRingBuffer.hpp" 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_ci#include <string> 36e5c31af7Sopenharmony_ci#include <map> 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_cinamespace xe 39e5c31af7Sopenharmony_ci{ 40e5c31af7Sopenharmony_cinamespace xml 41e5c31af7Sopenharmony_ci{ 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_cienum Token 44e5c31af7Sopenharmony_ci{ 45e5c31af7Sopenharmony_ci TOKEN_INCOMPLETE = 0, //!< Not enough data to determine token. 46e5c31af7Sopenharmony_ci TOKEN_END_OF_STRING, //!< End of document string. 47e5c31af7Sopenharmony_ci TOKEN_DATA, //!< Block of data (anything outside tags). 48e5c31af7Sopenharmony_ci TOKEN_COMMENT, //!< <!-- comment --> 49e5c31af7Sopenharmony_ci TOKEN_IDENTIFIER, //!< Identifier (in tags). 50e5c31af7Sopenharmony_ci TOKEN_STRING, //!< String (in tags). 51e5c31af7Sopenharmony_ci TOKEN_TAG_START, //!< < 52e5c31af7Sopenharmony_ci TOKEN_TAG_END, //!< > 53e5c31af7Sopenharmony_ci TOKEN_END_TAG_START, //!< </ 54e5c31af7Sopenharmony_ci TOKEN_EMPTY_ELEMENT_END, //!< /> 55e5c31af7Sopenharmony_ci TOKEN_PROCESSING_INSTRUCTION_START, //!< <? 56e5c31af7Sopenharmony_ci TOKEN_PROCESSING_INSTRUCTION_END, //!< ?> 57e5c31af7Sopenharmony_ci TOKEN_EQUAL, //!< = 58e5c31af7Sopenharmony_ci TOKEN_ENTITY, //!< Entity reference, such as & 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_ci TOKEN_LAST 61e5c31af7Sopenharmony_ci}; 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_cienum Element 64e5c31af7Sopenharmony_ci{ 65e5c31af7Sopenharmony_ci ELEMENT_INCOMPLETE = 0, //!< Incomplete element. 66e5c31af7Sopenharmony_ci ELEMENT_START, //!< Element start. 67e5c31af7Sopenharmony_ci ELEMENT_END, //!< Element end. 68e5c31af7Sopenharmony_ci ELEMENT_DATA, //!< Data element. 69e5c31af7Sopenharmony_ci ELEMENT_END_OF_STRING, //!< End of document string. 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_ci ELEMENT_LAST 72e5c31af7Sopenharmony_ci}; 73e5c31af7Sopenharmony_ci 74e5c31af7Sopenharmony_ciconst char* getTokenName (Token token); 75e5c31af7Sopenharmony_ci 76e5c31af7Sopenharmony_ci// \todo [2012-10-17 pyry] Add line number etc. 77e5c31af7Sopenharmony_ciclass ParseError : public xe::ParseError 78e5c31af7Sopenharmony_ci{ 79e5c31af7Sopenharmony_cipublic: 80e5c31af7Sopenharmony_ci ParseError (const std::string& message) : xe::ParseError(message) {} 81e5c31af7Sopenharmony_ci}; 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_ciclass Tokenizer 84e5c31af7Sopenharmony_ci{ 85e5c31af7Sopenharmony_cipublic: 86e5c31af7Sopenharmony_ci Tokenizer (void); 87e5c31af7Sopenharmony_ci ~Tokenizer (void); 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_ci void clear (void); //!< Resets tokenizer to initial state. 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci void feed (const deUint8* bytes, int numBytes); 92e5c31af7Sopenharmony_ci void advance (void); 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_ci Token getToken (void) const { return m_curToken; } 95e5c31af7Sopenharmony_ci int getTokenLen (void) const { return m_curTokenLen; } 96e5c31af7Sopenharmony_ci deUint8 getTokenByte (int offset) const { DE_ASSERT(m_curToken != TOKEN_INCOMPLETE && m_curToken != TOKEN_END_OF_STRING); return m_buf.peekBack(offset); } 97e5c31af7Sopenharmony_ci void getTokenStr (std::string& dst) const; 98e5c31af7Sopenharmony_ci void appendTokenStr (std::string& dst) const; 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci void getString (std::string& dst) const; 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_ciprivate: 103e5c31af7Sopenharmony_ci Tokenizer (const Tokenizer& other); 104e5c31af7Sopenharmony_ci Tokenizer& operator= (const Tokenizer& other); 105e5c31af7Sopenharmony_ci 106e5c31af7Sopenharmony_ci int getChar (int offset) const; 107e5c31af7Sopenharmony_ci 108e5c31af7Sopenharmony_ci void error (const std::string& what); 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci enum State 111e5c31af7Sopenharmony_ci { 112e5c31af7Sopenharmony_ci STATE_DATA = 0, 113e5c31af7Sopenharmony_ci STATE_TAG, 114e5c31af7Sopenharmony_ci STATE_IDENTIFIER, 115e5c31af7Sopenharmony_ci STATE_VALUE, 116e5c31af7Sopenharmony_ci STATE_COMMENT, 117e5c31af7Sopenharmony_ci STATE_ENTITY, 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ci STATE_LAST 120e5c31af7Sopenharmony_ci }; 121e5c31af7Sopenharmony_ci 122e5c31af7Sopenharmony_ci enum 123e5c31af7Sopenharmony_ci { 124e5c31af7Sopenharmony_ci END_OF_STRING = 0, //!< End of string (0). 125e5c31af7Sopenharmony_ci END_OF_BUFFER = 0xffffffff //!< End of current data buffer. 126e5c31af7Sopenharmony_ci }; 127e5c31af7Sopenharmony_ci 128e5c31af7Sopenharmony_ci Token m_curToken; //!< Current token. 129e5c31af7Sopenharmony_ci int m_curTokenLen; //!< Length of current token. 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ci State m_state; //!< Tokenization state. 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_ci de::RingBuffer<deUint8> m_buf; 134e5c31af7Sopenharmony_ci}; 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_ciclass Parser 137e5c31af7Sopenharmony_ci{ 138e5c31af7Sopenharmony_cipublic: 139e5c31af7Sopenharmony_ci typedef std::map<std::string, std::string> AttributeMap; 140e5c31af7Sopenharmony_ci typedef AttributeMap::const_iterator AttributeIter; 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ci Parser (void); 143e5c31af7Sopenharmony_ci ~Parser (void); 144e5c31af7Sopenharmony_ci 145e5c31af7Sopenharmony_ci void clear (void); //!< Resets parser to initial state. 146e5c31af7Sopenharmony_ci 147e5c31af7Sopenharmony_ci void feed (const deUint8* bytes, int numBytes); 148e5c31af7Sopenharmony_ci void advance (void); 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_ci Element getElement (void) const { return m_element; } 151e5c31af7Sopenharmony_ci 152e5c31af7Sopenharmony_ci // For ELEMENT_START / ELEMENT_END. 153e5c31af7Sopenharmony_ci const char* getElementName (void) const { return m_elementName.c_str(); } 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ci // For ELEMENT_START. 156e5c31af7Sopenharmony_ci bool hasAttribute (const char* name) const { return m_attributes.find(name) != m_attributes.end(); } 157e5c31af7Sopenharmony_ci const char* getAttribute (const char* name) const { return m_attributes.find(name)->second.c_str(); } 158e5c31af7Sopenharmony_ci const AttributeMap& attributes (void) const { return m_attributes; } 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci // For ELEMENT_DATA. 161e5c31af7Sopenharmony_ci int getDataSize (void) const; 162e5c31af7Sopenharmony_ci deUint8 getDataByte (int offset) const; 163e5c31af7Sopenharmony_ci void getDataStr (std::string& dst) const; 164e5c31af7Sopenharmony_ci void appendDataStr (std::string& dst) const; 165e5c31af7Sopenharmony_ci 166e5c31af7Sopenharmony_ciprivate: 167e5c31af7Sopenharmony_ci Parser (const Parser& other); 168e5c31af7Sopenharmony_ci Parser& operator= (const Parser& other); 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_ci void parseEntityValue (void); 171e5c31af7Sopenharmony_ci 172e5c31af7Sopenharmony_ci void error (const std::string& what); 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_ci enum State 175e5c31af7Sopenharmony_ci { 176e5c31af7Sopenharmony_ci STATE_DATA = 0, //!< Initial state - assuming data or tag open. 177e5c31af7Sopenharmony_ci STATE_ENTITY, //!< Parsed entity is stored - overrides data. 178e5c31af7Sopenharmony_ci STATE_IN_PROCESSING_INSTRUCTION, //!< In processing instruction. 179e5c31af7Sopenharmony_ci STATE_START_TAG_OPEN, //!< Start tag open. 180e5c31af7Sopenharmony_ci STATE_END_TAG_OPEN, //!< End tag open. 181e5c31af7Sopenharmony_ci STATE_EXPECTING_END_TAG_CLOSE, //!< Expecting end tag close. 182e5c31af7Sopenharmony_ci STATE_ATTRIBUTE_LIST, //!< Expecting attribute list. 183e5c31af7Sopenharmony_ci STATE_EXPECTING_ATTRIBUTE_EQ, //!< Got attribute name, expecting =. 184e5c31af7Sopenharmony_ci STATE_EXPECTING_ATTRIBUTE_VALUE, //!< Expecting attribute value. 185e5c31af7Sopenharmony_ci STATE_YIELD_EMPTY_ELEMENT_END, //!< Empty element: start has been reported but not end. 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_ci STATE_LAST 188e5c31af7Sopenharmony_ci }; 189e5c31af7Sopenharmony_ci 190e5c31af7Sopenharmony_ci Tokenizer m_tokenizer; 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ci Element m_element; 193e5c31af7Sopenharmony_ci std::string m_elementName; 194e5c31af7Sopenharmony_ci AttributeMap m_attributes; 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ci State m_state; 197e5c31af7Sopenharmony_ci std::string m_attribName; 198e5c31af7Sopenharmony_ci std::string m_entityValue; //!< Data override, such as entity value. 199e5c31af7Sopenharmony_ci}; 200e5c31af7Sopenharmony_ci 201e5c31af7Sopenharmony_ci// Inline implementations 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_ciinline void Tokenizer::getTokenStr (std::string& dst) const 204e5c31af7Sopenharmony_ci{ 205e5c31af7Sopenharmony_ci DE_ASSERT(m_curToken != TOKEN_INCOMPLETE && m_curToken != TOKEN_END_OF_STRING); 206e5c31af7Sopenharmony_ci dst.resize(m_curTokenLen); 207e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < m_curTokenLen; ndx++) 208e5c31af7Sopenharmony_ci dst[ndx] = m_buf.peekBack(ndx); 209e5c31af7Sopenharmony_ci} 210e5c31af7Sopenharmony_ci 211e5c31af7Sopenharmony_ciinline void Tokenizer::appendTokenStr (std::string& dst) const 212e5c31af7Sopenharmony_ci{ 213e5c31af7Sopenharmony_ci DE_ASSERT(m_curToken != TOKEN_INCOMPLETE && m_curToken != TOKEN_END_OF_STRING); 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_ci size_t oldLen = dst.size(); 216e5c31af7Sopenharmony_ci dst.resize(oldLen+m_curTokenLen); 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < m_curTokenLen; ndx++) 219e5c31af7Sopenharmony_ci dst[oldLen+ndx] = m_buf.peekBack(ndx); 220e5c31af7Sopenharmony_ci} 221e5c31af7Sopenharmony_ci 222e5c31af7Sopenharmony_ciinline int Parser::getDataSize (void) const 223e5c31af7Sopenharmony_ci{ 224e5c31af7Sopenharmony_ci if (m_state != STATE_ENTITY) 225e5c31af7Sopenharmony_ci return m_tokenizer.getTokenLen(); 226e5c31af7Sopenharmony_ci else 227e5c31af7Sopenharmony_ci return (int)m_entityValue.size(); 228e5c31af7Sopenharmony_ci} 229e5c31af7Sopenharmony_ci 230e5c31af7Sopenharmony_ciinline deUint8 Parser::getDataByte (int offset) const 231e5c31af7Sopenharmony_ci{ 232e5c31af7Sopenharmony_ci if (m_state != STATE_ENTITY) 233e5c31af7Sopenharmony_ci return m_tokenizer.getTokenByte(offset); 234e5c31af7Sopenharmony_ci else 235e5c31af7Sopenharmony_ci return (deUint8)m_entityValue[offset]; 236e5c31af7Sopenharmony_ci} 237e5c31af7Sopenharmony_ci 238e5c31af7Sopenharmony_ciinline void Parser::getDataStr (std::string& dst) const 239e5c31af7Sopenharmony_ci{ 240e5c31af7Sopenharmony_ci if (m_state != STATE_ENTITY) 241e5c31af7Sopenharmony_ci return m_tokenizer.getTokenStr(dst); 242e5c31af7Sopenharmony_ci else 243e5c31af7Sopenharmony_ci dst = m_entityValue; 244e5c31af7Sopenharmony_ci} 245e5c31af7Sopenharmony_ci 246e5c31af7Sopenharmony_ciinline void Parser::appendDataStr (std::string& dst) const 247e5c31af7Sopenharmony_ci{ 248e5c31af7Sopenharmony_ci if (m_state != STATE_ENTITY) 249e5c31af7Sopenharmony_ci return m_tokenizer.appendTokenStr(dst); 250e5c31af7Sopenharmony_ci else 251e5c31af7Sopenharmony_ci dst += m_entityValue; 252e5c31af7Sopenharmony_ci} 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_ci} // xml 255e5c31af7Sopenharmony_ci} // xe 256e5c31af7Sopenharmony_ci 257e5c31af7Sopenharmony_ci#endif // _XEXMLPARSER_HPP 258