13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Test Executor 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ------------------------------------------ 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief XML Parser. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xeXMLParser.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace xe 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace xml 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TOKENIZER_INITIAL_BUFFER_SIZE = 1024 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool isIdentifierStartChar (int ch) 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return de::inRange<int>(ch, 'a', 'z') || de::inRange<int>(ch, 'A', 'Z'); 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool isIdentifierChar (int ch) 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return isIdentifierStartChar(ch) || de::inRange<int>(ch, '0', '9') || (ch == '-') || (ch == '_'); 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool isWhitespaceChar (int ch) 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNextBufferSize (int curSize, int minNewSize) 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return de::max(curSize*2, 1<<deLog2Ceil32(minNewSize)); 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTokenizer::Tokenizer (void) 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_curToken (TOKEN_INCOMPLETE) 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_curTokenLen (0) 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (STATE_DATA) 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_buf (TOKENIZER_INITIAL_BUFFER_SIZE) 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTokenizer::~Tokenizer (void) 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Tokenizer::clear (void) 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_INCOMPLETE; 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen = 0; 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_DATA; 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_buf.clear(); 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Tokenizer::error (const std::string& what) 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw ParseError(what); 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Tokenizer::feed (const deUint8* bytes, int numBytes) 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Grow buffer if necessary. 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_buf.getNumFree() < numBytes) 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_buf.resize(getNextBufferSize(m_buf.getSize(), m_buf.getNumElements()+numBytes)); 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Append to front. 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_buf.pushFront(bytes, numBytes); 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // If we haven't parsed complete token, re-try after data feed. 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_curToken == TOKEN_INCOMPLETE) 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry advance(); 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint Tokenizer::getChar (int offset) const 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(de::inRange(offset, 0, m_buf.getNumElements())); 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (offset < m_buf.getNumElements()) 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_buf.peekBack(offset); 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return END_OF_BUFFER; 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Tokenizer::advance (void) 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_curToken != TOKEN_INCOMPLETE) 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Parser should not try to advance beyond end of string. 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_curToken != TOKEN_END_OF_STRING); 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // If current token is tag end, change state to data. 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_curToken == TOKEN_TAG_END || 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken == TOKEN_EMPTY_ELEMENT_END || 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken == TOKEN_PROCESSING_INSTRUCTION_END || 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken == TOKEN_COMMENT || 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken == TOKEN_ENTITY) 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_DATA; 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Advance buffer by length of last token. 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_buf.popBack(m_curTokenLen); 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Reset state. 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_INCOMPLETE; 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen = 0; 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // If we hit end of string here, report it as end of string. 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (getChar(0) == END_OF_STRING) 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_END_OF_STRING; 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen = 1; 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int curChar = getChar(m_curTokenLen); 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (;;) 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state == STATE_DATA) 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Advance until we hit end of buffer or tag start and treat that as data token. 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curChar == END_OF_STRING || curChar == (int)END_OF_BUFFER || curChar == '<' || curChar == '&') 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curChar == '<') 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_TAG; 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curChar == '&') 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_ENTITY; 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_curTokenLen > 0) 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Report data token. 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_DATA; 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curChar == END_OF_STRING || curChar == (int)END_OF_BUFFER) 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Just return incomplete token, no data parsed. 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_state == STATE_TAG || m_state == STATE_ENTITY); 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Eat all whitespace if present. 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_curTokenLen == 0) 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (isWhitespaceChar(curChar)) 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_buf.popBack(); 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curChar = getChar(0); 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Handle end of string / buffer. 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curChar == END_OF_STRING) 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Unexpected end of string"); 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curChar == (int)END_OF_BUFFER) 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_curToken == TOKEN_INCOMPLETE); 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_curTokenLen == 0) 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Expect start of identifier, value or special tag token. 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curChar == '\'' || curChar == '"') 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_VALUE; 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (isIdentifierStartChar(curChar)) 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_IDENTIFIER; 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curChar == '<' || curChar == '?' || curChar == '/') 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_TAG; 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curChar == '&') 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_state == STATE_ENTITY); 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curChar == '=') 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_EQUAL; 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen = 1; 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curChar == '>') 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_TAG_END; 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen = 1; 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Unexpected character"); 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_state == STATE_IDENTIFIER) 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isIdentifierChar(curChar)) 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_IDENTIFIER; 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_state == STATE_VALUE) 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2012-06-07 pyry] Escapes. 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curChar == '\'' || curChar == '"') 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2012-10-17 pyry] Should we actually do the check against getChar(0)? 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curChar != getChar(0)) 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Mismatched quote"); 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_STRING; 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen += 1; 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_state == STATE_COMMENT) 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_curTokenLen >= 2); // 2 characters have been parsed if we are in comment state. 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_curTokenLen <= 3) 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curChar != '-') 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Invalid comment start"); 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int prev2 = m_curTokenLen > 5 ? getChar(m_curTokenLen-2) : 0; 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int prev1 = m_curTokenLen > 4 ? getChar(m_curTokenLen-1) : 0; 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (prev2 == '-' && prev1 == '-') 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curChar != '>') 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Invalid comment end"); 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_COMMENT; 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen += 1; 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_state == STATE_ENTITY) 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_curTokenLen >= 1) 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curChar == ';') 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_ENTITY; 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen += 1; 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (!de::inRange<int>(curChar, '0', '9') && 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !de::inRange<int>(curChar, 'a', 'z') && 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !de::inRange<int>(curChar, 'A', 'Z')) 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Invalid entity"); 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Special tokens are at most 2 characters. 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_state == STATE_TAG && m_curTokenLen == 1); 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int prevChar = getChar(m_curTokenLen-1); 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (prevChar == '<') 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Tag start. 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curChar == '/') 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_END_TAG_START; 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen = 2; 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curChar == '?') 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_PROCESSING_INSTRUCTION_START; 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen = 2; 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curChar == '!') 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_COMMENT; 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_TAG_START; 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen = 1; 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (prevChar == '?') 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curChar != '>') 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Invalid processing instruction end"); 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_PROCESSING_INSTRUCTION_END; 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen = 2; 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (prevChar == '/') 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curChar != '>') 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Invalid empty element end"); 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curToken = TOKEN_EMPTY_ELEMENT_END; 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen = 2; 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Could not parse special token"); 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_curTokenLen += 1; 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curChar = getChar(m_curTokenLen); 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Tokenizer::getString (std::string& dst) const 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_curToken == TOKEN_STRING); 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.resize(m_curTokenLen-2); 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_curTokenLen-2; ndx++) 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[ndx] = m_buf.peekBack(ndx+1); 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryParser::Parser (void) 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_element (ELEMENT_INCOMPLETE) 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (STATE_DATA) 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryParser::~Parser (void) 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Parser::clear (void) 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tokenizer.clear(); 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_elementName.clear(); 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_attributes.clear(); 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_attribName.clear(); 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_entityValue.clear(); 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_element = ELEMENT_INCOMPLETE; 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_DATA; 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Parser::error (const std::string& what) 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw ParseError(what); 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Parser::feed (const deUint8* bytes, int numBytes) 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tokenizer.feed(bytes, numBytes); 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_element == ELEMENT_INCOMPLETE) 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry advance(); 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Parser::advance (void) 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_element == ELEMENT_START) 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_attributes.clear(); 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note No token is advanced when element end is reported. 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state == STATE_YIELD_EMPTY_ELEMENT_END) 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_element == ELEMENT_START); 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_element = ELEMENT_END; 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_DATA; 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_element != ELEMENT_INCOMPLETE) 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tokenizer.advance(); 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_element = ELEMENT_INCOMPLETE; 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (;;) 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Token curToken = m_tokenizer.getToken(); 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Skip comments. 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (curToken == TOKEN_COMMENT) 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tokenizer.advance(); 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curToken = m_tokenizer.getToken(); 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curToken == TOKEN_INCOMPLETE) 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_element == ELEMENT_INCOMPLETE); 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (m_state) 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case STATE_ENTITY: 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_DATA; 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Fall-through to STATE_DATA processing. 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case STATE_DATA: 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (curToken) 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TOKEN_DATA: 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_element = ELEMENT_DATA; 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TOKEN_END_OF_STRING: 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_element = ELEMENT_END_OF_STRING; 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TOKEN_TAG_START: 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_START_TAG_OPEN; 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TOKEN_END_TAG_START: 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_END_TAG_OPEN; 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TOKEN_PROCESSING_INSTRUCTION_START: 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_IN_PROCESSING_INSTRUCTION; 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TOKEN_ENTITY: 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_ENTITY; 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_element = ELEMENT_DATA; 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parseEntityValue(); 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Unexpected token"); 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case STATE_IN_PROCESSING_INSTRUCTION: 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curToken == TOKEN_PROCESSING_INSTRUCTION_END) 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_DATA; 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curToken != TOKEN_IDENTIFIER && curToken != TOKEN_EQUAL && curToken != TOKEN_STRING) 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Unexpected token in processing instruction"); 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case STATE_START_TAG_OPEN: 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curToken != TOKEN_IDENTIFIER) 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Expected identifier"); 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tokenizer.getTokenStr(m_elementName); 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_ATTRIBUTE_LIST; 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case STATE_END_TAG_OPEN: 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curToken != TOKEN_IDENTIFIER) 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Expected identifier"); 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tokenizer.getTokenStr(m_elementName); 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_EXPECTING_END_TAG_CLOSE; 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case STATE_EXPECTING_END_TAG_CLOSE: 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curToken != TOKEN_TAG_END) 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Expected tag end"); 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_DATA; 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_element = ELEMENT_END; 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case STATE_ATTRIBUTE_LIST: 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curToken == TOKEN_IDENTIFIER) 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tokenizer.getTokenStr(m_attribName); 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_EXPECTING_ATTRIBUTE_EQ; 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curToken == TOKEN_EMPTY_ELEMENT_END) 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_YIELD_EMPTY_ELEMENT_END; 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_element = ELEMENT_START; 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curToken == TOKEN_TAG_END) 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_DATA; 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_element = ELEMENT_START; 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Unexpected token"); 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case STATE_EXPECTING_ATTRIBUTE_EQ: 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curToken != TOKEN_EQUAL) 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Expected '='"); 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_EXPECTING_ATTRIBUTE_VALUE; 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case STATE_EXPECTING_ATTRIBUTE_VALUE: 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curToken != TOKEN_STRING) 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Expected value"); 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hasAttribute(m_attribName.c_str())) 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Duplicate attribute"); 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tokenizer.getString(m_attributes[m_attribName]); 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = STATE_ATTRIBUTE_LIST; 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tokenizer.advance(); 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic char getEntityValue (const std::string& entity) 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const struct 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name; 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry char value; 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } s_entities[] = 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "<", '<' }, 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { ">", '>' }, 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "&", '&' }, 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "'", '\''}, 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { """, '"' }, 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_entities); ndx++) 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (entity == s_entities[ndx].name) 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return s_entities[ndx].value; 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Parser::parseEntityValue (void) 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_state == STATE_ENTITY && m_tokenizer.getToken() == TOKEN_ENTITY); 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string entity; 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tokenizer.getTokenStr(entity); 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char value = getEntityValue(entity); 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (value == 0) 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error("Invalid entity '" + entity + "'"); 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_entityValue.resize(1); 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_entityValue[0] = value; 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // xml 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // xe 574