1/*------------------------------------------------------------------------- 2 * drawElements Quality Program Test Executor 3 * ------------------------------------------ 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief XML Writer. 22 *//*--------------------------------------------------------------------*/ 23 24#include "xeXMLWriter.hpp" 25 26#include <cstring> 27 28namespace xe 29{ 30namespace xml 31{ 32 33const Writer::EndElementType Writer::EndElement = Writer::EndElementType(); 34 35inline const char* getEscapeEntity (char ch) 36{ 37 switch (ch) 38 { 39 case '<': return "<"; 40 case '>': return ">"; 41 case '&': return "&"; 42 case '\'': return "'"; 43 case '"': return """; 44 default: return DE_NULL; 45 } 46} 47 48std::streamsize EscapeStreambuf::xsputn (const char* s, std::streamsize count) 49{ 50 std::streamsize numWritten = 0; 51 52 for (std::streamsize inPos = 0; inPos < count; inPos++) 53 { 54 const char* entity = getEscapeEntity(s[inPos]); 55 56 if (entity) 57 { 58 // Flush data prior to entity. 59 if (inPos > numWritten) 60 { 61 m_dst.write(s + numWritten, inPos-numWritten); 62 if (m_dst.fail()) 63 return numWritten; 64 } 65 66 // Flush entity value 67 m_dst.write(entity, (std::streamsize)strlen(entity)); 68 69 numWritten = inPos+1; 70 } 71 } 72 73 if (numWritten < count) 74 { 75 m_dst.write(s + numWritten, count-numWritten); 76 if (m_dst.fail()) 77 return numWritten; 78 } 79 80 return count; 81} 82 83int EscapeStreambuf::overflow (int ch) 84{ 85 if (ch == -1) 86 return -1; 87 else 88 { 89 DE_ASSERT((ch & 0xff) == ch); 90 const char chVal = (char)(deUint8)(ch & 0xff); 91 return xsputn(&chVal, 1) == 1 ? ch : -1; 92 } 93} 94 95Writer::Writer (std::ostream& dst) 96 : m_rawDst (dst) 97 , m_dataBuf (dst) 98 , m_dataStr (&m_dataBuf) 99 , m_state (STATE_DATA) 100{ 101} 102 103Writer::~Writer (void) 104{ 105} 106 107Writer& Writer::operator<< (const BeginElement& begin) 108{ 109 if (m_state == STATE_ELEMENT) 110 m_rawDst << ">"; 111 112 if (m_state == STATE_ELEMENT || m_state == STATE_ELEMENT_END) 113 { 114 m_rawDst << "\n"; 115 for (int i = 0; i < (int)m_elementStack.size(); i++) 116 m_rawDst << " "; 117 } 118 119 m_rawDst << "<" << begin.element; 120 121 m_elementStack.push_back(begin.element); 122 m_state = STATE_ELEMENT; 123 124 return *this; 125} 126 127Writer& Writer::operator<< (const Attribute& attribute) 128{ 129 DE_ASSERT(m_state == STATE_ELEMENT); 130 131 // \todo [2012-09-05 pyry] Escape? 132 m_rawDst << " " << attribute.name << "=\"" << attribute.value << "\""; 133 134 return *this; 135} 136 137Writer& Writer::operator<< (const EndElementType&) 138{ 139 if (m_state == STATE_ELEMENT) 140 m_rawDst << "/>"; 141 else 142 { 143 if (m_state == STATE_ELEMENT_END) 144 { 145 m_rawDst << "\n"; 146 for (int i = 0; i < (int)m_elementStack.size()-1; i++) 147 m_rawDst << " "; 148 } 149 150 m_rawDst << "</" << m_elementStack.back() << ">"; 151 } 152 153 m_elementStack.pop_back(); 154 m_state = STATE_ELEMENT_END; 155 156 return *this; 157} 158 159} // xml 160} // xe 161