xref: /aosp_15_r20/external/deqp/executor/xeXMLWriter.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program Test Executor
3*35238bceSAndroid Build Coastguard Worker  * ------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief XML Writer.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "xeXMLWriter.hpp"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include <cstring>
27*35238bceSAndroid Build Coastguard Worker 
28*35238bceSAndroid Build Coastguard Worker namespace xe
29*35238bceSAndroid Build Coastguard Worker {
30*35238bceSAndroid Build Coastguard Worker namespace xml
31*35238bceSAndroid Build Coastguard Worker {
32*35238bceSAndroid Build Coastguard Worker 
33*35238bceSAndroid Build Coastguard Worker const Writer::EndElementType Writer::EndElement = Writer::EndElementType();
34*35238bceSAndroid Build Coastguard Worker 
getEscapeEntity(char ch)35*35238bceSAndroid Build Coastguard Worker inline const char *getEscapeEntity(char ch)
36*35238bceSAndroid Build Coastguard Worker {
37*35238bceSAndroid Build Coastguard Worker     switch (ch)
38*35238bceSAndroid Build Coastguard Worker     {
39*35238bceSAndroid Build Coastguard Worker     case '<':
40*35238bceSAndroid Build Coastguard Worker         return "&lt;";
41*35238bceSAndroid Build Coastguard Worker     case '>':
42*35238bceSAndroid Build Coastguard Worker         return "&gt;";
43*35238bceSAndroid Build Coastguard Worker     case '&':
44*35238bceSAndroid Build Coastguard Worker         return "&amp;";
45*35238bceSAndroid Build Coastguard Worker     case '\'':
46*35238bceSAndroid Build Coastguard Worker         return "&apos;";
47*35238bceSAndroid Build Coastguard Worker     case '"':
48*35238bceSAndroid Build Coastguard Worker         return "&quot;";
49*35238bceSAndroid Build Coastguard Worker 
50*35238bceSAndroid Build Coastguard Worker     // Non-printable characters.
51*35238bceSAndroid Build Coastguard Worker     case 0:
52*35238bceSAndroid Build Coastguard Worker         return "&lt;NUL&gt;";
53*35238bceSAndroid Build Coastguard Worker     case 1:
54*35238bceSAndroid Build Coastguard Worker         return "&lt;SOH&gt;";
55*35238bceSAndroid Build Coastguard Worker     case 2:
56*35238bceSAndroid Build Coastguard Worker         return "&lt;STX&gt;";
57*35238bceSAndroid Build Coastguard Worker     case 3:
58*35238bceSAndroid Build Coastguard Worker         return "&lt;ETX&gt;";
59*35238bceSAndroid Build Coastguard Worker     case 4:
60*35238bceSAndroid Build Coastguard Worker         return "&lt;EOT&gt;";
61*35238bceSAndroid Build Coastguard Worker     case 5:
62*35238bceSAndroid Build Coastguard Worker         return "&lt;ENQ&gt;";
63*35238bceSAndroid Build Coastguard Worker     case 6:
64*35238bceSAndroid Build Coastguard Worker         return "&lt;ACK&gt;";
65*35238bceSAndroid Build Coastguard Worker     case 7:
66*35238bceSAndroid Build Coastguard Worker         return "&lt;BEL&gt;";
67*35238bceSAndroid Build Coastguard Worker     case 8:
68*35238bceSAndroid Build Coastguard Worker         return "&lt;BS&gt;";
69*35238bceSAndroid Build Coastguard Worker     case 11:
70*35238bceSAndroid Build Coastguard Worker         return "&lt;VT&gt;";
71*35238bceSAndroid Build Coastguard Worker     case 12:
72*35238bceSAndroid Build Coastguard Worker         return "&lt;FF&gt;";
73*35238bceSAndroid Build Coastguard Worker     case 14:
74*35238bceSAndroid Build Coastguard Worker         return "&lt;SO&gt;";
75*35238bceSAndroid Build Coastguard Worker     case 15:
76*35238bceSAndroid Build Coastguard Worker         return "&lt;SI&gt;";
77*35238bceSAndroid Build Coastguard Worker     case 16:
78*35238bceSAndroid Build Coastguard Worker         return "&lt;DLE&gt;";
79*35238bceSAndroid Build Coastguard Worker     case 17:
80*35238bceSAndroid Build Coastguard Worker         return "&lt;DC1&gt;";
81*35238bceSAndroid Build Coastguard Worker     case 18:
82*35238bceSAndroid Build Coastguard Worker         return "&lt;DC2&gt;";
83*35238bceSAndroid Build Coastguard Worker     case 19:
84*35238bceSAndroid Build Coastguard Worker         return "&lt;DC3&gt;";
85*35238bceSAndroid Build Coastguard Worker     case 20:
86*35238bceSAndroid Build Coastguard Worker         return "&lt;DC4&gt;";
87*35238bceSAndroid Build Coastguard Worker     case 21:
88*35238bceSAndroid Build Coastguard Worker         return "&lt;NAK&gt;";
89*35238bceSAndroid Build Coastguard Worker     case 22:
90*35238bceSAndroid Build Coastguard Worker         return "&lt;SYN&gt;";
91*35238bceSAndroid Build Coastguard Worker     case 23:
92*35238bceSAndroid Build Coastguard Worker         return "&lt;ETB&gt;";
93*35238bceSAndroid Build Coastguard Worker     case 24:
94*35238bceSAndroid Build Coastguard Worker         return "&lt;CAN&gt;";
95*35238bceSAndroid Build Coastguard Worker     case 25:
96*35238bceSAndroid Build Coastguard Worker         return "&lt;EM&gt;";
97*35238bceSAndroid Build Coastguard Worker     case 26:
98*35238bceSAndroid Build Coastguard Worker         return "&lt;SUB&gt;";
99*35238bceSAndroid Build Coastguard Worker     case 27:
100*35238bceSAndroid Build Coastguard Worker         return "&lt;ESC&gt;";
101*35238bceSAndroid Build Coastguard Worker     case 28:
102*35238bceSAndroid Build Coastguard Worker         return "&lt;FS&gt;";
103*35238bceSAndroid Build Coastguard Worker     case 29:
104*35238bceSAndroid Build Coastguard Worker         return "&lt;GS&gt;";
105*35238bceSAndroid Build Coastguard Worker     case 30:
106*35238bceSAndroid Build Coastguard Worker         return "&lt;RS&gt;";
107*35238bceSAndroid Build Coastguard Worker     case 31:
108*35238bceSAndroid Build Coastguard Worker         return "&lt;US&gt;";
109*35238bceSAndroid Build Coastguard Worker 
110*35238bceSAndroid Build Coastguard Worker     default:
111*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
112*35238bceSAndroid Build Coastguard Worker     }
113*35238bceSAndroid Build Coastguard Worker }
114*35238bceSAndroid Build Coastguard Worker 
xsputn(const char * s,std::streamsize count)115*35238bceSAndroid Build Coastguard Worker std::streamsize EscapeStreambuf::xsputn(const char *s, std::streamsize count)
116*35238bceSAndroid Build Coastguard Worker {
117*35238bceSAndroid Build Coastguard Worker     std::streamsize numWritten = 0;
118*35238bceSAndroid Build Coastguard Worker 
119*35238bceSAndroid Build Coastguard Worker     for (std::streamsize inPos = 0; inPos < count; inPos++)
120*35238bceSAndroid Build Coastguard Worker     {
121*35238bceSAndroid Build Coastguard Worker         const char *entity = getEscapeEntity(s[inPos]);
122*35238bceSAndroid Build Coastguard Worker 
123*35238bceSAndroid Build Coastguard Worker         if (entity)
124*35238bceSAndroid Build Coastguard Worker         {
125*35238bceSAndroid Build Coastguard Worker             // Flush data prior to entity.
126*35238bceSAndroid Build Coastguard Worker             if (inPos > numWritten)
127*35238bceSAndroid Build Coastguard Worker             {
128*35238bceSAndroid Build Coastguard Worker                 m_dst.write(s + numWritten, inPos - numWritten);
129*35238bceSAndroid Build Coastguard Worker                 if (m_dst.fail())
130*35238bceSAndroid Build Coastguard Worker                     return numWritten;
131*35238bceSAndroid Build Coastguard Worker             }
132*35238bceSAndroid Build Coastguard Worker 
133*35238bceSAndroid Build Coastguard Worker             // Flush entity value
134*35238bceSAndroid Build Coastguard Worker             m_dst.write(entity, (std::streamsize)strlen(entity));
135*35238bceSAndroid Build Coastguard Worker 
136*35238bceSAndroid Build Coastguard Worker             numWritten = inPos + 1;
137*35238bceSAndroid Build Coastguard Worker         }
138*35238bceSAndroid Build Coastguard Worker     }
139*35238bceSAndroid Build Coastguard Worker 
140*35238bceSAndroid Build Coastguard Worker     if (numWritten < count)
141*35238bceSAndroid Build Coastguard Worker     {
142*35238bceSAndroid Build Coastguard Worker         m_dst.write(s + numWritten, count - numWritten);
143*35238bceSAndroid Build Coastguard Worker         if (m_dst.fail())
144*35238bceSAndroid Build Coastguard Worker             return numWritten;
145*35238bceSAndroid Build Coastguard Worker     }
146*35238bceSAndroid Build Coastguard Worker 
147*35238bceSAndroid Build Coastguard Worker     return count;
148*35238bceSAndroid Build Coastguard Worker }
149*35238bceSAndroid Build Coastguard Worker 
overflow(int ch)150*35238bceSAndroid Build Coastguard Worker int EscapeStreambuf::overflow(int ch)
151*35238bceSAndroid Build Coastguard Worker {
152*35238bceSAndroid Build Coastguard Worker     if (ch == -1)
153*35238bceSAndroid Build Coastguard Worker         return -1;
154*35238bceSAndroid Build Coastguard Worker     else
155*35238bceSAndroid Build Coastguard Worker     {
156*35238bceSAndroid Build Coastguard Worker         DE_ASSERT((ch & 0xff) == ch);
157*35238bceSAndroid Build Coastguard Worker         const char chVal = (char)(uint8_t)(ch & 0xff);
158*35238bceSAndroid Build Coastguard Worker         return xsputn(&chVal, 1) == 1 ? ch : -1;
159*35238bceSAndroid Build Coastguard Worker     }
160*35238bceSAndroid Build Coastguard Worker }
161*35238bceSAndroid Build Coastguard Worker 
Writer(std::ostream & dst)162*35238bceSAndroid Build Coastguard Worker Writer::Writer(std::ostream &dst) : m_rawDst(dst), m_dataBuf(dst), m_dataStr(&m_dataBuf), m_state(STATE_DATA)
163*35238bceSAndroid Build Coastguard Worker {
164*35238bceSAndroid Build Coastguard Worker }
165*35238bceSAndroid Build Coastguard Worker 
~Writer(void)166*35238bceSAndroid Build Coastguard Worker Writer::~Writer(void)
167*35238bceSAndroid Build Coastguard Worker {
168*35238bceSAndroid Build Coastguard Worker }
169*35238bceSAndroid Build Coastguard Worker 
operator <<(const BeginElement & begin)170*35238bceSAndroid Build Coastguard Worker Writer &Writer::operator<<(const BeginElement &begin)
171*35238bceSAndroid Build Coastguard Worker {
172*35238bceSAndroid Build Coastguard Worker     if (m_state == STATE_ELEMENT)
173*35238bceSAndroid Build Coastguard Worker         m_rawDst << ">";
174*35238bceSAndroid Build Coastguard Worker 
175*35238bceSAndroid Build Coastguard Worker     if (m_state == STATE_ELEMENT || m_state == STATE_ELEMENT_END)
176*35238bceSAndroid Build Coastguard Worker     {
177*35238bceSAndroid Build Coastguard Worker         m_rawDst << "\n";
178*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < (int)m_elementStack.size(); i++)
179*35238bceSAndroid Build Coastguard Worker             m_rawDst << "  ";
180*35238bceSAndroid Build Coastguard Worker     }
181*35238bceSAndroid Build Coastguard Worker 
182*35238bceSAndroid Build Coastguard Worker     m_rawDst << "<" << begin.element;
183*35238bceSAndroid Build Coastguard Worker 
184*35238bceSAndroid Build Coastguard Worker     m_elementStack.push_back(begin.element);
185*35238bceSAndroid Build Coastguard Worker     m_state = STATE_ELEMENT;
186*35238bceSAndroid Build Coastguard Worker 
187*35238bceSAndroid Build Coastguard Worker     return *this;
188*35238bceSAndroid Build Coastguard Worker }
189*35238bceSAndroid Build Coastguard Worker 
operator <<(const Attribute & attribute)190*35238bceSAndroid Build Coastguard Worker Writer &Writer::operator<<(const Attribute &attribute)
191*35238bceSAndroid Build Coastguard Worker {
192*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_state == STATE_ELEMENT);
193*35238bceSAndroid Build Coastguard Worker 
194*35238bceSAndroid Build Coastguard Worker     // \todo [2012-09-05 pyry] Escape?
195*35238bceSAndroid Build Coastguard Worker     m_rawDst << " " << attribute.name << "=\"" << attribute.value << "\"";
196*35238bceSAndroid Build Coastguard Worker 
197*35238bceSAndroid Build Coastguard Worker     return *this;
198*35238bceSAndroid Build Coastguard Worker }
199*35238bceSAndroid Build Coastguard Worker 
operator <<(const EndElementType &)200*35238bceSAndroid Build Coastguard Worker Writer &Writer::operator<<(const EndElementType &)
201*35238bceSAndroid Build Coastguard Worker {
202*35238bceSAndroid Build Coastguard Worker     if (m_state == STATE_ELEMENT)
203*35238bceSAndroid Build Coastguard Worker         m_rawDst << "/>";
204*35238bceSAndroid Build Coastguard Worker     else
205*35238bceSAndroid Build Coastguard Worker     {
206*35238bceSAndroid Build Coastguard Worker         if (m_state == STATE_ELEMENT_END)
207*35238bceSAndroid Build Coastguard Worker         {
208*35238bceSAndroid Build Coastguard Worker             m_rawDst << "\n";
209*35238bceSAndroid Build Coastguard Worker             for (int i = 0; i < (int)m_elementStack.size() - 1; i++)
210*35238bceSAndroid Build Coastguard Worker                 m_rawDst << "  ";
211*35238bceSAndroid Build Coastguard Worker         }
212*35238bceSAndroid Build Coastguard Worker 
213*35238bceSAndroid Build Coastguard Worker         m_rawDst << "</" << m_elementStack.back() << ">";
214*35238bceSAndroid Build Coastguard Worker     }
215*35238bceSAndroid Build Coastguard Worker 
216*35238bceSAndroid Build Coastguard Worker     m_elementStack.pop_back();
217*35238bceSAndroid Build Coastguard Worker     m_state = STATE_ELEMENT_END;
218*35238bceSAndroid Build Coastguard Worker 
219*35238bceSAndroid Build Coastguard Worker     return *this;
220*35238bceSAndroid Build Coastguard Worker }
221*35238bceSAndroid Build Coastguard Worker 
222*35238bceSAndroid Build Coastguard Worker } // namespace xml
223*35238bceSAndroid Build Coastguard Worker } // namespace xe
224