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