• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getEscapeEntity(char ch)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 
xsputn(const char * s,std::streamsize count)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 
overflow(int ch)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 
Writer(std::ostream & dst)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 
~Writer(void)103 Writer::~Writer (void)
104 {
105 }
106 
operator <<(const BeginElement & begin)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 
operator <<(const Attribute & attribute)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 
operator <<(const EndElementType &)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