/src/xmlProtoConverter.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2019 Google Inc. |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #include "xmlProtoConverter.h" |
18 | | |
19 | | #include <algorithm> |
20 | | |
21 | | using namespace std; |
22 | | using namespace xmlProtoFuzzer; |
23 | | |
24 | | string ProtoConverter::removeNonAscii(string const& _utf8) |
25 | 2.06M | { |
26 | 2.06M | string asciiStr{_utf8}; |
27 | 26.1M | asciiStr.erase(remove_if(asciiStr.begin(), asciiStr.end(), [=](char c) -> bool { |
28 | 26.1M | return !(std::isalpha(c) || std::isdigit(c)); |
29 | 26.1M | }), asciiStr.end()); |
30 | 2.06M | return asciiStr.empty() ? "fuzz" : asciiStr; |
31 | 2.06M | } |
32 | | |
33 | | |
34 | | void ProtoConverter::visit(Misc const& _x) |
35 | 4.61k | { |
36 | 4.61k | switch (_x.misc_oneof_case()) |
37 | 4.61k | { |
38 | 1.72k | case Misc::kComment: |
39 | 1.72k | m_output << "<!--" << _x.comment() << "-->\n"; |
40 | 1.72k | break; |
41 | 1.37k | case Misc::kInst: |
42 | 1.37k | visit(_x.inst()); |
43 | 1.37k | break; |
44 | 1.51k | case Misc::MISC_ONEOF_NOT_SET: |
45 | 1.51k | break; |
46 | 4.61k | } |
47 | 4.61k | } |
48 | | |
49 | | void ProtoConverter::visit(Prolog const& _x) |
50 | 8.51k | { |
51 | 8.51k | visit(_x.decl()); |
52 | 8.51k | visit(_x.doctype()); |
53 | 8.51k | for (auto const& misc: _x.misc()) |
54 | 2.70k | visit(misc); |
55 | 8.51k | } |
56 | | |
57 | | void ProtoConverter::visit(KeyValue const& _x) |
58 | 31.7k | { |
59 | 31.7k | if (!KeyValue::XmlNamespace_IsValid(_x.type())) |
60 | 196 | return; |
61 | | |
62 | 31.5k | switch (_x.type()) |
63 | 31.5k | { |
64 | 7.11k | case KeyValue::ATTRIBUTES: |
65 | 7.11k | m_output << "xml:attributes=\"" << removeNonAscii(_x.value()) << "\" "; |
66 | 7.11k | break; |
67 | 1.67k | case KeyValue::BASE: |
68 | 1.67k | m_output << "xml:base=\"" << removeNonAscii(_x.value()) << "\" "; |
69 | 1.67k | break; |
70 | 1.52k | case KeyValue::CATALOG: |
71 | 1.52k | m_output << "xml:catalog=\"" << removeNonAscii(_x.value()) << "\" "; |
72 | 1.52k | break; |
73 | 2.77k | case KeyValue::ID: |
74 | 2.77k | m_output << "xml:id=\"" << removeNonAscii(_x.value()) << "\" "; |
75 | 2.77k | break; |
76 | 3.44k | case KeyValue::LANG: |
77 | 3.44k | m_output << "xml:lang=\"" << removeNonAscii(_x.value()) << "\" "; |
78 | 3.44k | break; |
79 | 1.12k | case KeyValue::LINK: |
80 | 1.12k | m_output << "xml:link=\"" << removeNonAscii(_x.value()) << "\" "; |
81 | 1.12k | break; |
82 | 728 | case KeyValue::SPACE: |
83 | 728 | m_output << "xml:space=\"" << removeNonAscii(_x.value()) << "\" "; |
84 | 728 | break; |
85 | 967 | case KeyValue::SPECIAL: |
86 | 967 | m_output << "xml:special=\"" << removeNonAscii(_x.value()) << "\" "; |
87 | 967 | break; |
88 | 1.46k | case KeyValue::TEST: |
89 | 1.46k | m_output << "xml:test=\"" << removeNonAscii(_x.value()) << "\" "; |
90 | 1.46k | break; |
91 | 10.7k | case KeyValue::FUZZ: |
92 | 10.7k | if (_x.ByteSizeLong() % 2) |
93 | 2.16k | m_output << "xmlns:" << removeNonAscii(_x.key()) << "=\"" << removeNonAscii(_x.value()) << "\" "; |
94 | 8.55k | else |
95 | 8.55k | m_output << removeNonAscii(_x.key()) << "=\"" << removeNonAscii(_x.value()) << "\" "; |
96 | 10.7k | break; |
97 | 0 | case KeyValue_XmlNamespace_KeyValue_XmlNamespace_INT_MIN_SENTINEL_DO_NOT_USE_: |
98 | 0 | case KeyValue_XmlNamespace_KeyValue_XmlNamespace_INT_MAX_SENTINEL_DO_NOT_USE_: |
99 | 0 | break; |
100 | 31.5k | } |
101 | 31.5k | } |
102 | | |
103 | | void ProtoConverter::visit(ProcessingInstruction const& _x) |
104 | 1.37k | { |
105 | 1.37k | m_output << "<?" << removeNonAscii(_x.name()) << " "; |
106 | 1.37k | for (auto const& prop: _x.kv()) |
107 | 1.05k | visit(prop); |
108 | 1.37k | m_output << "?>\n"; |
109 | 1.37k | } |
110 | | |
111 | | void ProtoConverter::visit(Content const& _x) |
112 | 410k | { |
113 | 410k | switch (_x.content_oneof_case()) |
114 | 410k | { |
115 | 2.54k | case Content::kStr: |
116 | 2.54k | m_output << _x.str() << "\n"; |
117 | 2.54k | break; |
118 | 6.58k | case Content::kE: |
119 | 6.58k | visit(_x.e()); |
120 | 6.58k | m_output << "\n"; |
121 | 6.58k | break; |
122 | 3.27k | case Content::kC: |
123 | 3.27k | visit(_x.c()); |
124 | 3.27k | m_output << "\n"; |
125 | 3.27k | break; |
126 | 398k | case Content::CONTENT_ONEOF_NOT_SET: |
127 | 398k | break; |
128 | 410k | } |
129 | 410k | } |
130 | | |
131 | | void ProtoConverter::visit(ElementDecl const& _x) |
132 | 5.70k | { |
133 | 5.70k | if (!ElementDecl::ContentSpec_IsValid(_x.spec())) |
134 | 34 | return; |
135 | | |
136 | 5.66k | m_output << "<!ELEMENT " << _x.name() << " "; |
137 | 5.66k | switch (_x.spec()) |
138 | 5.66k | { |
139 | 3.43k | case ElementDecl::EMPTY: |
140 | 3.43k | m_output << "EMPTY>"; |
141 | 3.43k | break; |
142 | 329 | case ElementDecl::ANY: |
143 | 329 | m_output << "ANY>"; |
144 | 329 | break; |
145 | 105 | case ElementDecl::FUZZ: |
146 | 105 | m_output << "FUZZ>"; |
147 | 105 | break; |
148 | 1.11k | case ElementDecl::MIXED: |
149 | 1.11k | m_output << "(#PCDATA"; |
150 | 1.11k | for (auto const& pcdata: _x.cdata()) |
151 | 2.91k | m_output << "|" << pcdata; |
152 | 1.11k | m_output << ")"; |
153 | 1.11k | if (_x.cdata_size() > 0) |
154 | 759 | m_output << "*"; |
155 | 1.11k | m_output << ">"; |
156 | 1.11k | break; |
157 | 683 | case ElementDecl::CHILDREN: |
158 | 683 | { |
159 | 683 | m_output << "("; |
160 | 683 | string delim = ""; |
161 | 3.26k | for (auto const& str: _x.cdata()) { |
162 | 3.26k | m_output << delim << removeNonAscii(str); |
163 | 3.26k | delim = ", "; |
164 | 3.26k | } |
165 | 683 | m_output << ")>"; |
166 | 683 | break; |
167 | 0 | } |
168 | 0 | case ElementDecl_ContentSpec_ElementDecl_ContentSpec_INT_MIN_SENTINEL_DO_NOT_USE_: |
169 | 0 | case ElementDecl_ContentSpec_ElementDecl_ContentSpec_INT_MAX_SENTINEL_DO_NOT_USE_: |
170 | 0 | break; |
171 | 5.66k | } |
172 | 5.66k | } |
173 | | |
174 | | void ProtoConverter::visit(AttValue const& _x) |
175 | 3.16k | { |
176 | 3.16k | if (!isValid(_x)) |
177 | 331 | return; |
178 | | |
179 | 2.83k | m_output << "\""; |
180 | 2.83k | string prefix; |
181 | 2.83k | switch (_x.type()) |
182 | 2.83k | { |
183 | 1.43k | case AttValue::ENTITY: |
184 | 1.43k | prefix = "&"; |
185 | 1.43k | break; |
186 | 1.05k | case AttValue::CHAR: |
187 | 1.05k | if (_x.ByteSizeLong() % 2) |
188 | 347 | prefix = "&#"; |
189 | 703 | else |
190 | | // TODO: Value that follows this must be a |
191 | | // sequence of hex digits. |
192 | 703 | prefix = "&#x"; |
193 | 1.05k | break; |
194 | 349 | case AttValue::FUZZ: |
195 | 349 | prefix = "fuzz"; |
196 | 349 | break; |
197 | 0 | case AttValue_Type_AttValue_Type_INT_MIN_SENTINEL_DO_NOT_USE_: |
198 | 0 | case AttValue_Type_AttValue_Type_INT_MAX_SENTINEL_DO_NOT_USE_: |
199 | 0 | break; |
200 | 2.83k | } |
201 | 2.83k | for (auto const& name: _x.value()) |
202 | 3.03k | m_output << prefix << removeNonAscii(name) << ";"; |
203 | 2.83k | m_output << "\""; |
204 | 2.83k | } |
205 | | |
206 | | void ProtoConverter::visit(DefaultDecl const& _x) |
207 | 18.7k | { |
208 | 18.7k | if (!isValid(_x)) |
209 | 213 | return; |
210 | | |
211 | 18.5k | switch (_x.type()) |
212 | 18.5k | { |
213 | 14.6k | case DefaultDecl::REQUIRED: |
214 | 14.6k | m_output << "#REQUIRED"; |
215 | 14.6k | break; |
216 | 433 | case DefaultDecl::IMPLIED: |
217 | 433 | m_output << "#IMPLIED"; |
218 | 433 | break; |
219 | 3.16k | case DefaultDecl::FIXED: |
220 | 3.16k | m_output << "#FIXED "; |
221 | 3.16k | visit(_x.att()); |
222 | 3.16k | break; |
223 | 280 | case DefaultDecl::FUZZ: |
224 | 280 | m_output << "#FUZZ"; |
225 | 280 | break; |
226 | 0 | case DefaultDecl_Type_DefaultDecl_Type_INT_MIN_SENTINEL_DO_NOT_USE_: |
227 | 0 | case DefaultDecl_Type_DefaultDecl_Type_INT_MAX_SENTINEL_DO_NOT_USE_: |
228 | 0 | break; |
229 | 18.5k | } |
230 | 18.5k | } |
231 | | |
232 | | void ProtoConverter::visit(AttDef const& _x) |
233 | 18.8k | { |
234 | 18.8k | if (!isValid(_x)) |
235 | 38 | return; |
236 | | |
237 | 18.7k | m_output << " " << removeNonAscii(_x.name()) << " "; |
238 | 18.7k | switch (_x.type()) |
239 | 18.7k | { |
240 | 12.8k | case AttDef::CDATA: |
241 | 12.8k | m_output << "CDATA "; |
242 | 12.8k | break; |
243 | 2.69k | case AttDef::ID: |
244 | 2.69k | m_output << "ID "; |
245 | 2.69k | break; |
246 | 692 | case AttDef::IDREF: |
247 | 692 | m_output << "IDREF "; |
248 | 692 | break; |
249 | 894 | case AttDef::IDREFS: |
250 | 894 | m_output << "IDREFS "; |
251 | 894 | break; |
252 | 333 | case AttDef::ENTITY: |
253 | 333 | m_output << "ENTITY "; |
254 | 333 | break; |
255 | 361 | case AttDef::ENTITIES: |
256 | 361 | m_output << "ENTITIES "; |
257 | 361 | break; |
258 | 454 | case AttDef::NMTOKEN: |
259 | 454 | m_output << "NMTOKEN "; |
260 | 454 | break; |
261 | 324 | case AttDef::NMTOKENS: |
262 | 324 | m_output << "NMTOKENS "; |
263 | 324 | break; |
264 | 151 | case AttDef::FUZZ: |
265 | 151 | m_output << "FUZZ "; |
266 | 151 | break; |
267 | 0 | case AttDef_Type_AttDef_Type_INT_MIN_SENTINEL_DO_NOT_USE_: |
268 | 0 | case AttDef_Type_AttDef_Type_INT_MAX_SENTINEL_DO_NOT_USE_: |
269 | 0 | break; |
270 | 18.7k | } |
271 | 18.7k | visit(_x.def()); |
272 | 18.7k | } |
273 | | |
274 | | void ProtoConverter::visit(AttListDecl const& _x) |
275 | 3.81k | { |
276 | 3.81k | m_output << "<!ATTLIST " << removeNonAscii(_x.name()); |
277 | 3.81k | for (auto const& att: _x.attdefs()) |
278 | 18.8k | visit(att); |
279 | 3.81k | m_output << ">"; |
280 | 3.81k | } |
281 | | |
282 | | void ProtoConverter::visit(NotationDecl const& _x) |
283 | 5.15k | { |
284 | 5.15k | m_output << "<!NOTATION " << removeNonAscii(_x.name()) << " "; |
285 | 5.15k | switch (_x.notation_oneof_case()) |
286 | 5.15k | { |
287 | 1.05k | case NotationDecl::kExt: |
288 | 1.05k | visit(_x.ext()); |
289 | 1.05k | break; |
290 | 2.72k | case NotationDecl::kPub: |
291 | 2.72k | m_output << "PUBLIC " << _x.pub(); |
292 | 2.72k | break; |
293 | 661 | case NotationDecl::kFuzz: |
294 | 661 | m_output << "FUZZ " << _x.fuzz(); |
295 | 661 | break; |
296 | 717 | case NotationDecl::NOTATION_ONEOF_NOT_SET: |
297 | 717 | break; |
298 | 5.15k | } |
299 | 5.15k | m_output << ">"; |
300 | 5.15k | } |
301 | | |
302 | | void ProtoConverter::visit(NDataDecl const& _x) |
303 | 1.75k | { |
304 | 1.75k | m_output << " NDATA " << _x.name(); |
305 | 1.75k | } |
306 | | |
307 | | void ProtoConverter::visit(EntityDef const& _x) |
308 | 8.98k | { |
309 | 8.98k | switch (_x.entity_oneof_case()) |
310 | 8.98k | { |
311 | 4.11k | case EntityDef::kExt: |
312 | 4.11k | visit(_x.ext()); |
313 | 4.11k | if (_x.ByteSizeLong() % 2) |
314 | 1.75k | visit(_x.ndata()); |
315 | 4.11k | break; |
316 | 2.82k | case EntityDef::kVal: |
317 | 2.82k | visit(_x.val()); |
318 | 2.82k | break; |
319 | 2.04k | case EntityDef::ENTITY_ONEOF_NOT_SET: |
320 | 2.04k | break; |
321 | 8.98k | } |
322 | 8.98k | } |
323 | | |
324 | | void ProtoConverter::visit(PEDef const& _x) |
325 | 3.36k | { |
326 | 3.36k | switch (_x.pedef_oneof_case()) |
327 | 3.36k | { |
328 | 1.37k | case PEDef::kVal: |
329 | 1.37k | visit(_x.val()); |
330 | 1.37k | break; |
331 | 837 | case PEDef::kId: |
332 | 837 | visit(_x.id()); |
333 | 837 | break; |
334 | 1.16k | case PEDef::PEDEF_ONEOF_NOT_SET: |
335 | 1.16k | break; |
336 | 3.36k | } |
337 | 3.36k | } |
338 | | |
339 | | void ProtoConverter::visit(EntityValue const& _x) |
340 | 4.19k | { |
341 | 4.19k | if (!isValid(_x)) |
342 | 68 | return; |
343 | | |
344 | 4.12k | m_output << "\""; |
345 | 4.12k | string prefix; |
346 | 4.12k | switch (_x.type()) |
347 | 4.12k | { |
348 | 1.83k | case EntityValue::ENTITY: |
349 | 1.83k | prefix = "&"; |
350 | 1.83k | break; |
351 | 1.77k | case EntityValue::CHAR: |
352 | 1.77k | if (_x.ByteSizeLong() % 2) |
353 | 966 | prefix = "&#"; |
354 | 804 | else |
355 | 804 | prefix = "&#x"; |
356 | 1.77k | break; |
357 | 221 | case EntityValue::PEREF: |
358 | 221 | prefix = "%"; |
359 | 221 | break; |
360 | 298 | case EntityValue::FUZZ: |
361 | 298 | prefix = "fuzz"; |
362 | 298 | break; |
363 | 0 | case EntityValue_Type_EntityValue_Type_INT_MIN_SENTINEL_DO_NOT_USE_: |
364 | 0 | case EntityValue_Type_EntityValue_Type_INT_MAX_SENTINEL_DO_NOT_USE_: |
365 | 0 | break; |
366 | 4.12k | } |
367 | 4.12k | for (auto const& ref: _x.name()) |
368 | 9.01k | m_output << prefix << ref << ";"; |
369 | 4.12k | m_output << "\""; |
370 | 4.12k | } |
371 | | |
372 | | void ProtoConverter::visit(EntityDecl const& _x) |
373 | 12.4k | { |
374 | 12.4k | if (!isValid(_x)) |
375 | 100 | return; |
376 | | |
377 | 12.3k | m_output << "<!ENTITY "; |
378 | 12.3k | switch (_x.type()) |
379 | 12.3k | { |
380 | 8.98k | case EntityDecl::GEDECL: |
381 | 8.98k | m_output << _x.name() << " "; |
382 | 8.98k | visit(_x.ent()); |
383 | 8.98k | break; |
384 | 3.36k | case EntityDecl::PEDECL: |
385 | 3.36k | m_output << "% " << _x.name() << " "; |
386 | 3.36k | visit(_x.pedef()); |
387 | 3.36k | break; |
388 | 0 | case EntityDecl_Type_EntityDecl_Type_INT_MIN_SENTINEL_DO_NOT_USE_: |
389 | 0 | case EntityDecl_Type_EntityDecl_Type_INT_MAX_SENTINEL_DO_NOT_USE_: |
390 | 0 | break; |
391 | 12.3k | } |
392 | 12.3k | m_output << ">"; |
393 | 12.3k | } |
394 | | |
395 | | void ProtoConverter::visit(ConditionalSect const& _x) |
396 | 7.06k | { |
397 | 7.06k | if (!isValid(_x)) |
398 | 213 | return; |
399 | | |
400 | 6.84k | switch (_x.type()) |
401 | 6.84k | { |
402 | 4.37k | case ConditionalSect::INCLUDE: |
403 | 4.37k | m_output << "<![ INCLUDE ["; |
404 | 4.37k | visit(_x.ext()); |
405 | 4.37k | m_output << "]]>"; |
406 | 4.37k | break; |
407 | 882 | case ConditionalSect::IGNORE: |
408 | 882 | m_output << "<![ IGNORE ["; |
409 | 882 | for (auto const& str: _x.ignores()) |
410 | 855 | m_output << "<![" << removeNonAscii(str) << "]]>"; |
411 | 882 | m_output << "]]>"; |
412 | 882 | break; |
413 | 1.58k | case ConditionalSect::FUZZ: |
414 | 1.58k | m_output << "<![ FUZZ ["; |
415 | 1.58k | visit(_x.ext()); |
416 | 1.58k | m_output << "]]>"; |
417 | 1.58k | break; |
418 | 0 | case ConditionalSect_Type_ConditionalSect_Type_INT_MIN_SENTINEL_DO_NOT_USE_: |
419 | 0 | case ConditionalSect_Type_ConditionalSect_Type_INT_MAX_SENTINEL_DO_NOT_USE_: |
420 | 0 | break; |
421 | 6.84k | } |
422 | 6.84k | } |
423 | | |
424 | | |
425 | | void ProtoConverter::visit(OneExtSubsetDecl const& _x) |
426 | 33.8k | { |
427 | 33.8k | switch (_x.extsubset_oneof_case()) |
428 | 33.8k | { |
429 | 19.1k | case OneExtSubsetDecl::kM: |
430 | 19.1k | visit(_x.m()); |
431 | 19.1k | break; |
432 | 7.06k | case OneExtSubsetDecl::kC: |
433 | 7.06k | visit(_x.c()); |
434 | 7.06k | break; |
435 | 7.62k | case OneExtSubsetDecl::EXTSUBSET_ONEOF_NOT_SET: |
436 | 7.62k | break; |
437 | 33.8k | } |
438 | 33.8k | } |
439 | | |
440 | | |
441 | | void ProtoConverter::visit(ExtSubsetDecl const& _x) |
442 | 11.0k | { |
443 | 11.0k | for (auto const& decl: _x.decls()) |
444 | 33.8k | visit(decl); |
445 | 11.0k | } |
446 | | |
447 | | void ProtoConverter::visit(CData const& _x) |
448 | 3.27k | { |
449 | 3.27k | m_output << "<![CDATA[" << removeNonAscii(_x.data()) << "]]>"; |
450 | 3.27k | } |
451 | | |
452 | | void ProtoConverter::visit(MarkupDecl const& _x) |
453 | 40.3k | { |
454 | 40.3k | switch (_x.markup_oneof_case()) |
455 | 40.3k | { |
456 | 5.70k | case MarkupDecl::kE: |
457 | 5.70k | visit(_x.e()); |
458 | 5.70k | break; |
459 | 3.81k | case MarkupDecl::kA: |
460 | 3.81k | visit(_x.a()); |
461 | 3.81k | break; |
462 | 5.15k | case MarkupDecl::kN: |
463 | 5.15k | visit(_x.n()); |
464 | 5.15k | break; |
465 | 1.91k | case MarkupDecl::kM: |
466 | 1.91k | visit(_x.m()); |
467 | 1.91k | break; |
468 | 12.4k | case MarkupDecl::kEntity: |
469 | 12.4k | visit(_x.entity()); |
470 | 12.4k | break; |
471 | 5.03k | case MarkupDecl::kExt: |
472 | 5.03k | visit(_x.ext()); |
473 | 5.03k | break; |
474 | 6.31k | case MarkupDecl::MARKUP_ONEOF_NOT_SET: |
475 | 6.31k | break; |
476 | 40.3k | } |
477 | 40.3k | } |
478 | | |
479 | | /// Returns predefined element from an Element_Id enum |
480 | | /// @param _x is an enum that holds the desired type of predefined value |
481 | | /// @param _prop is a string that holds the value of the desired type |
482 | | /// @return string holding the predefined value of the form |
483 | | /// name attribute=\"value\" |
484 | | string ProtoConverter::getPredefined(Element_Id _x, string const& _prop) |
485 | 391k | { |
486 | 391k | string output{}; |
487 | 391k | switch (_x) |
488 | 391k | { |
489 | 372k | case Element::XIINCLUDE: |
490 | 374k | case Element::XIFALLBACK: |
491 | 380k | case Element::XIHREF: |
492 | 380k | output = "xi:include href=\"fuzz.xml\""; |
493 | 382k | case Element::XIPARSE: |
494 | 382k | output = "xi:include parse=\"xml\""; |
495 | 383k | case Element::XIXPOINTER: |
496 | 383k | output = "xi:include xpointer=\"" + removeNonAscii(_prop) + "\""; |
497 | 386k | case Element::XIENCODING: |
498 | 386k | output = "xi:include encoding=\"" + removeNonAscii(_prop) + "\""; |
499 | 389k | case Element::XIACCEPT: |
500 | 389k | output = "xi:include accept=\"" + removeNonAscii(_prop) + "\""; |
501 | 390k | case Element::XIACCEPTLANG: |
502 | 390k | output = "xi:include accept-language=\"" + removeNonAscii(_prop) + "\""; |
503 | 390k | case Element_Id_Element_Id_INT_MIN_SENTINEL_DO_NOT_USE_: |
504 | 390k | case Element_Id_Element_Id_INT_MAX_SENTINEL_DO_NOT_USE_: |
505 | 390k | output = "xi:fuzz xifuzz=\"fuzz\""; |
506 | 391k | } |
507 | 391k | return output; |
508 | 391k | } |
509 | | |
510 | | /// Returns uri string for a given Element_Id type |
511 | | string ProtoConverter::getUri(Element_Id _x) |
512 | 391k | { |
513 | 391k | if (!Element::Id_IsValid(_x)) |
514 | 925 | return s_XInclude; |
515 | | |
516 | 390k | switch (_x) |
517 | 390k | { |
518 | 372k | case Element::XIINCLUDE: |
519 | 374k | case Element::XIFALLBACK: |
520 | 380k | case Element::XIHREF: |
521 | 382k | case Element::XIPARSE: |
522 | 383k | case Element::XIXPOINTER: |
523 | 386k | case Element::XIENCODING: |
524 | 389k | case Element::XIACCEPT: |
525 | 390k | case Element::XIACCEPTLANG: |
526 | 390k | case Element_Id_Element_Id_INT_MIN_SENTINEL_DO_NOT_USE_: |
527 | 390k | case Element_Id_Element_Id_INT_MAX_SENTINEL_DO_NOT_USE_: |
528 | 390k | return s_XInclude; |
529 | 390k | } |
530 | 390k | } |
531 | | |
532 | | void ProtoConverter::visit(Element const& _x) |
533 | 410k | { |
534 | 410k | if (!isValid(_x)) |
535 | 77 | return; |
536 | | |
537 | | // Predefined child node |
538 | 410k | string child = {}; |
539 | | // Predefined uri for child node |
540 | 410k | string pUri = {}; |
541 | | // Element name |
542 | 410k | string name = removeNonAscii(_x.name()); |
543 | | |
544 | 410k | switch (_x.type()) |
545 | 410k | { |
546 | 391k | case Element::PREDEFINED: |
547 | 391k | child = getPredefined(_x.id(), _x.childprop()); |
548 | 391k | pUri = getUri(_x.id()); |
549 | 391k | break; |
550 | 19.4k | case Element::FUZZ: |
551 | 19.4k | case Element_Type_Element_Type_INT_MIN_SENTINEL_DO_NOT_USE_: |
552 | 19.4k | case Element_Type_Element_Type_INT_MAX_SENTINEL_DO_NOT_USE_: |
553 | 19.4k | break; |
554 | 410k | } |
555 | | |
556 | | // <name k1=v1 k2=v2 k3=v3> |
557 | | // <content> |
558 | | // </name> |
559 | | |
560 | | // Start name tag: Must be Ascii? |
561 | 410k | m_output << "<" << name << " "; |
562 | | |
563 | | // Add uri to name tag |
564 | 410k | if (!pUri.empty()) |
565 | 391k | m_output << pUri << " "; |
566 | 410k | for (auto const& prop: _x.kv()) |
567 | 30.6k | visit(prop); |
568 | 410k | m_output << ">\n"; |
569 | | |
570 | | // Add attribute |
571 | 410k | if (!child.empty()) |
572 | 390k | m_output << "<" << child << "/>\n"; |
573 | | |
574 | | // Add content |
575 | 410k | visit(_x.content()); |
576 | | |
577 | | // Close name tag |
578 | 410k | m_output << "</" << name << ">\n"; |
579 | 410k | } |
580 | | |
581 | | void ProtoConverter::visit(ExternalId const& _x) |
582 | 14.5k | { |
583 | 14.5k | if (!isValid(_x)) |
584 | 1.16k | return; |
585 | | |
586 | 13.3k | switch (_x.type()) |
587 | 13.3k | { |
588 | 11.4k | case ExternalId::SYSTEM: |
589 | 11.4k | m_output << "SYSTEM " << "\"" << removeNonAscii(_x.system()) << "\""; |
590 | 11.4k | break; |
591 | 1.13k | case ExternalId::PUBLIC: |
592 | 1.13k | m_output << "PUBLIC " << "\"" << removeNonAscii(_x.pub()) << "\"" |
593 | 1.13k | << " " << "\"" << removeNonAscii(_x.system()) << "\""; |
594 | 1.13k | break; |
595 | 749 | case ExternalId::FUZZ: |
596 | 749 | m_output << "FUZZ " << "\"" << removeNonAscii(_x.pub()) << "\""; |
597 | 749 | break; |
598 | 0 | case ExternalId_Type_ExternalId_Type_INT_MIN_SENTINEL_DO_NOT_USE_: |
599 | 0 | case ExternalId_Type_ExternalId_Type_INT_MAX_SENTINEL_DO_NOT_USE_: |
600 | 0 | break; |
601 | 13.3k | } |
602 | 13.3k | } |
603 | | |
604 | | void ProtoConverter::visit(DocTypeDecl const& _x) |
605 | 8.51k | { |
606 | 8.51k | m_output << "<!DOCTYPE " << removeNonAscii(_x.name()) << " "; |
607 | 8.51k | visit(_x.ext()); |
608 | 8.51k | m_output << "["; |
609 | 8.51k | for (auto const& m: _x.mdecl()) |
610 | 21.2k | visit(m); |
611 | 8.51k | m_output << "]"; |
612 | 8.51k | m_output << ">\n"; |
613 | 8.51k | } |
614 | | |
615 | | void ProtoConverter::visit(VersionNum const& _x) |
616 | 8.51k | { |
617 | 8.51k | if (!isValid(_x)) |
618 | 3 | return; |
619 | | |
620 | 8.51k | switch (_x.type()) |
621 | 8.51k | { |
622 | 8.36k | case VersionNum::STANDARD: |
623 | 8.36k | m_output << "\"1.0\""; |
624 | 8.36k | break; |
625 | 144 | case VersionNum::FUZZ: |
626 | 144 | case VersionNum_Type_VersionNum_Type_INT_MIN_SENTINEL_DO_NOT_USE_: |
627 | 144 | case VersionNum_Type_VersionNum_Type_INT_MAX_SENTINEL_DO_NOT_USE_: |
628 | 144 | m_output << "\"" << _x.major() << "." << _x.minor() << "\""; |
629 | 144 | break; |
630 | 8.51k | } |
631 | 8.51k | } |
632 | | |
633 | | void ProtoConverter::visit(Encodings const& _x) |
634 | 8.51k | { |
635 | 8.51k | if (!Encodings::Enc_IsValid(_x.name())) |
636 | 855 | return; |
637 | | |
638 | 7.66k | m_output << " encoding=\""; |
639 | 7.66k | switch (_x.name()) |
640 | 7.66k | { |
641 | 6.79k | case Encodings::BIG5: |
642 | 6.79k | m_output << "BIG5"; |
643 | 6.79k | break; |
644 | 12 | case Encodings::EUCJP: |
645 | 12 | m_output << "EUC-JP"; |
646 | 12 | break; |
647 | 53 | case Encodings::EUCKR: |
648 | 53 | m_output << "EUC-KR"; |
649 | 53 | break; |
650 | 12 | case Encodings::GB18030: |
651 | 12 | m_output << "GB18030"; |
652 | 12 | break; |
653 | 1 | case Encodings::ISO2022JP: |
654 | 1 | m_output << "ISO-2022-JP"; |
655 | 1 | break; |
656 | 123 | case Encodings::ISO2022KR: |
657 | 123 | m_output << "ISO-2022-KR"; |
658 | 123 | break; |
659 | 67 | case Encodings::ISO88591: |
660 | 67 | m_output << "ISO-8859-1"; |
661 | 67 | break; |
662 | 10 | case Encodings::ISO88592: |
663 | 10 | m_output << "ISO-8859-2"; |
664 | 10 | break; |
665 | 12 | case Encodings::ISO88593: |
666 | 12 | m_output << "ISO-8859-3"; |
667 | 12 | break; |
668 | 10 | case Encodings::ISO88594: |
669 | 10 | m_output << "ISO-8859-4"; |
670 | 10 | break; |
671 | 8 | case Encodings::ISO88595: |
672 | 8 | m_output << "ISO-8859-5"; |
673 | 8 | break; |
674 | 4 | case Encodings::ISO88596: |
675 | 4 | m_output << "ISO-8859-6"; |
676 | 4 | break; |
677 | 4 | case Encodings::ISO88597: |
678 | 4 | m_output << "ISO-8859-7"; |
679 | 4 | break; |
680 | 3 | case Encodings::ISO88598: |
681 | 3 | m_output << "ISO-8859-8"; |
682 | 3 | break; |
683 | 14 | case Encodings::ISO88599: |
684 | 14 | m_output << "ISO-8859-9"; |
685 | 14 | break; |
686 | 113 | case Encodings::SHIFTJIS: |
687 | 113 | m_output << "SHIFT_JIS"; |
688 | 113 | break; |
689 | 12 | case Encodings::TIS620: |
690 | 12 | m_output << "TIS-620"; |
691 | 12 | break; |
692 | 74 | case Encodings::USASCII: |
693 | 74 | m_output << "US-ASCII"; |
694 | 74 | break; |
695 | 82 | case Encodings::UTF8: |
696 | 82 | m_output << "UTF-8"; |
697 | 82 | break; |
698 | 23 | case Encodings::UTF16: |
699 | 23 | m_output << "UTF-16"; |
700 | 23 | break; |
701 | 14 | case Encodings::UTF16BE: |
702 | 14 | m_output << "UTF-16BE"; |
703 | 14 | break; |
704 | 11 | case Encodings::UTF16LE: |
705 | 11 | m_output << "UTF-16LE"; |
706 | 11 | break; |
707 | 63 | case Encodings::WINDOWS31J: |
708 | 63 | m_output << "WINDOWS-31J"; |
709 | 63 | break; |
710 | 6 | case Encodings::WINDOWS1255: |
711 | 6 | m_output << "WINDOWS-1255"; |
712 | 6 | break; |
713 | 4 | case Encodings::WINDOWS1256: |
714 | 4 | m_output << "WINDOWS-1256"; |
715 | 4 | break; |
716 | 134 | case Encodings::FUZZ: |
717 | 134 | m_output << removeNonAscii(_x.fuzz()); |
718 | 134 | break; |
719 | 0 | case Encodings_Enc_Encodings_Enc_INT_MIN_SENTINEL_DO_NOT_USE_: |
720 | 0 | case Encodings_Enc_Encodings_Enc_INT_MAX_SENTINEL_DO_NOT_USE_: |
721 | 0 | break; |
722 | 7.66k | } |
723 | 7.66k | m_output << "\""; |
724 | 7.66k | } |
725 | | |
726 | | void ProtoConverter::visit(XmlDeclaration const& _x) |
727 | 8.51k | { |
728 | 8.51k | m_output << R"(<?xml version=)"; |
729 | 8.51k | visit(_x.ver()); |
730 | 8.51k | visit(_x.enc()); |
731 | 8.51k | switch (_x.standalone()) |
732 | 8.51k | { |
733 | 8.20k | case XmlDeclaration::YES: |
734 | 8.20k | m_output << " standalone=\'yes\'"; |
735 | 8.20k | break; |
736 | 288 | case XmlDeclaration::NO: |
737 | 288 | m_output << " standalone=\'no\'"; |
738 | 288 | break; |
739 | 0 | case XmlDeclaration_Standalone_XmlDeclaration_Standalone_INT_MIN_SENTINEL_DO_NOT_USE_: |
740 | 0 | case XmlDeclaration_Standalone_XmlDeclaration_Standalone_INT_MAX_SENTINEL_DO_NOT_USE_: |
741 | 27 | default: |
742 | 27 | break; |
743 | 8.51k | } |
744 | 8.51k | m_output << "?>\n"; |
745 | 8.51k | } |
746 | | |
747 | | void ProtoConverter::visit(XmlDocument const& _x) |
748 | 8.51k | { |
749 | 8.51k | visit(_x.p()); |
750 | 8.51k | for (auto const& element: _x.e()) |
751 | 404k | visit(element); |
752 | 8.51k | } |
753 | | |
754 | | string ProtoConverter::protoToString(XmlDocument const& _x) |
755 | 8.51k | { |
756 | 8.51k | visit(_x); |
757 | 8.51k | return m_output.str(); |
758 | 8.51k | } |