Home | History | Annotate | Download | only in executor
      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 
     28 namespace xe
     29 {
     30 namespace xml
     31 {
     32 
     33 const Writer::EndElementType Writer::EndElement = Writer::EndElementType();
     34 
     35 inline const char* getEscapeEntity (char ch)
     36 {
     37 	switch (ch)
     38 	{
     39 		case '<':	return "&lt;";
     40 		case '>':	return "&gt;";
     41 		case '&':	return "&amp;";
     42 		case '\'':	return "&apos;";
     43 		case '"':	return "&quot;";
     44 
     45 		// Non-printable characters.
     46 		case 0:		return "&lt;NUL&gt;";
     47 		case 1:		return "&lt;SOH&gt;";
     48 		case 2:		return "&lt;STX&gt;";
     49 		case 3:		return "&lt;ETX&gt;";
     50 		case 4:		return "&lt;EOT&gt;";
     51 		case 5:		return "&lt;ENQ&gt;";
     52 		case 6:		return "&lt;ACK&gt;";
     53 		case 7:		return "&lt;BEL&gt;";
     54 		case 8:		return "&lt;BS&gt;";
     55 		case 11:	return "&lt;VT&gt;";
     56 		case 12:	return "&lt;FF&gt;";
     57 		case 14:	return "&lt;SO&gt;";
     58 		case 15:	return "&lt;SI&gt;";
     59 		case 16:	return "&lt;DLE&gt;";
     60 		case 17:	return "&lt;DC1&gt;";
     61 		case 18:	return "&lt;DC2&gt;";
     62 		case 19:	return "&lt;DC3&gt;";
     63 		case 20:	return "&lt;DC4&gt;";
     64 		case 21:	return "&lt;NAK&gt;";
     65 		case 22:	return "&lt;SYN&gt;";
     66 		case 23:	return "&lt;ETB&gt;";
     67 		case 24:	return "&lt;CAN&gt;";
     68 		case 25:	return "&lt;EM&gt;";
     69 		case 26:	return "&lt;SUB&gt;";
     70 		case 27:	return "&lt;ESC&gt;";
     71 		case 28:	return "&lt;FS&gt;";
     72 		case 29:	return "&lt;GS&gt;";
     73 		case 30:	return "&lt;RS&gt;";
     74 		case 31:	return "&lt;US&gt;";
     75 
     76 		default:	return DE_NULL;
     77 	}
     78 }
     79 
     80 std::streamsize EscapeStreambuf::xsputn (const char* s, std::streamsize count)
     81 {
     82 	std::streamsize	numWritten = 0;
     83 
     84 	for (std::streamsize inPos = 0; inPos < count; inPos++)
     85 	{
     86 		const char* entity = getEscapeEntity(s[inPos]);
     87 
     88 		if (entity)
     89 		{
     90 			// Flush data prior to entity.
     91 			if (inPos > numWritten)
     92 			{
     93 				m_dst.write(s + numWritten, inPos-numWritten);
     94 				if (m_dst.fail())
     95 					return numWritten;
     96 			}
     97 
     98 			// Flush entity value
     99 			m_dst.write(entity, (std::streamsize)strlen(entity));
    100 
    101 			numWritten = inPos+1;
    102 		}
    103 	}
    104 
    105 	if (numWritten < count)
    106 	{
    107 		m_dst.write(s + numWritten, count-numWritten);
    108 		if (m_dst.fail())
    109 			return numWritten;
    110 	}
    111 
    112 	return count;
    113 }
    114 
    115 int EscapeStreambuf::overflow (int ch)
    116 {
    117 	if (ch == -1)
    118 		return -1;
    119 	else
    120 	{
    121 		DE_ASSERT((ch & 0xff) == ch);
    122 		const char chVal = (char)(deUint8)(ch & 0xff);
    123 		return xsputn(&chVal, 1) == 1 ? ch : -1;
    124 	}
    125 }
    126 
    127 Writer::Writer (std::ostream& dst)
    128 	: m_rawDst	(dst)
    129 	, m_dataBuf	(dst)
    130 	, m_dataStr	(&m_dataBuf)
    131 	, m_state	(STATE_DATA)
    132 {
    133 }
    134 
    135 Writer::~Writer (void)
    136 {
    137 }
    138 
    139 Writer& Writer::operator<< (const BeginElement& begin)
    140 {
    141 	if (m_state == STATE_ELEMENT)
    142 		m_rawDst << ">";
    143 
    144 	if (m_state == STATE_ELEMENT || m_state == STATE_ELEMENT_END)
    145 	{
    146 		m_rawDst << "\n";
    147 		for (int i = 0; i < (int)m_elementStack.size(); i++)
    148 			m_rawDst << "  ";
    149 	}
    150 
    151 	m_rawDst << "<" << begin.element;
    152 
    153 	m_elementStack.push_back(begin.element);
    154 	m_state = STATE_ELEMENT;
    155 
    156 	return *this;
    157 }
    158 
    159 Writer& Writer::operator<< (const Attribute& attribute)
    160 {
    161 	DE_ASSERT(m_state == STATE_ELEMENT);
    162 
    163 	// \todo [2012-09-05 pyry] Escape?
    164 	m_rawDst << " " << attribute.name << "=\"" << attribute.value << "\"";
    165 
    166 	return *this;
    167 }
    168 
    169 Writer& Writer::operator<< (const EndElementType&)
    170 {
    171 	if (m_state == STATE_ELEMENT)
    172 		m_rawDst << "/>";
    173 	else
    174 	{
    175 		if (m_state == STATE_ELEMENT_END)
    176 		{
    177 			m_rawDst << "\n";
    178 			for (int i = 0; i < (int)m_elementStack.size()-1; i++)
    179 				m_rawDst << "  ";
    180 		}
    181 
    182 		m_rawDst << "</" << m_elementStack.back() << ">";
    183 	}
    184 
    185 	m_elementStack.pop_back();
    186 	m_state = STATE_ELEMENT_END;
    187 
    188 	return *this;
    189 }
    190 
    191 } // xml
    192 } // xe
    193