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 		default:	return DE_NULL;
     45 	}
     46 }
     47 
     48 std::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 
     83 int 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 
     95 Writer::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 
    103 Writer::~Writer (void)
    104 {
    105 }
    106 
    107 Writer& 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 
    127 Writer& 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 
    137 Writer& 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