/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 | 954k | { |
26 | 954k | string asciiStr{_utf8}; |
27 | 19.6M | asciiStr.erase(remove_if(asciiStr.begin(), asciiStr.end(), [=](char c) -> bool { |
28 | 19.6M | return !(std::isalpha(c) || std::isdigit(c)); |
29 | 19.6M | }), asciiStr.end()); |
30 | 954k | return asciiStr.empty() ? "fuzz" : asciiStr; |
31 | 954k | } |
32 | | |
33 | | |
34 | | void ProtoConverter::visit(Misc const& _x) |
35 | 4.60k | { |
36 | 4.60k | switch (_x.misc_oneof_case()) |
37 | 4.60k | { |
38 | 1.53k | case Misc::kComment: |
39 | 1.53k | m_output << "<!--" << _x.comment() << "-->\n"; |
40 | 1.53k | break; |
41 | 1.61k | case Misc::kInst: |
42 | 1.61k | visit(_x.inst()); |
43 | 1.61k | break; |
44 | 1.45k | case Misc::MISC_ONEOF_NOT_SET: |
45 | 1.45k | break; |
46 | 4.60k | } |
47 | 4.60k | } |
48 | | |
49 | | void ProtoConverter::visit(Prolog const& _x) |
50 | 8.25k | { |
51 | 8.25k | visit(_x.decl()); |
52 | 8.25k | visit(_x.doctype()); |
53 | 8.25k | for (auto const& misc: _x.misc()) |
54 | 2.51k | visit(misc); |
55 | 8.25k | } |
56 | | |
57 | | void ProtoConverter::visit(KeyValue const& _x) |
58 | 21.5k | { |
59 | 21.5k | if (!KeyValue::XmlNamespace_IsValid(_x.type())) |
60 | 159 | return; |
61 | | |
62 | 21.4k | switch (_x.type()) |
63 | 21.4k | { |
64 | 5.74k | case KeyValue::ATTRIBUTES: |
65 | 5.74k | m_output << "xml:attributes=\"" << removeNonAscii(_x.value()) << "\" "; |
66 | 5.74k | break; |
67 | 1.49k | case KeyValue::BASE: |
68 | 1.49k | m_output << "xml:base=\"" << removeNonAscii(_x.value()) << "\" "; |
69 | 1.49k | break; |
70 | 1.28k | case KeyValue::CATALOG: |
71 | 1.28k | m_output << "xml:catalog=\"" << removeNonAscii(_x.value()) << "\" "; |
72 | 1.28k | break; |
73 | 1.97k | case KeyValue::ID: |
74 | 1.97k | m_output << "xml:id=\"" << removeNonAscii(_x.value()) << "\" "; |
75 | 1.97k | break; |
76 | 478 | case KeyValue::LANG: |
77 | 478 | m_output << "xml:lang=\"" << removeNonAscii(_x.value()) << "\" "; |
78 | 478 | break; |
79 | 674 | case KeyValue::LINK: |
80 | 674 | m_output << "xml:link=\"" << removeNonAscii(_x.value()) << "\" "; |
81 | 674 | break; |
82 | 685 | case KeyValue::SPACE: |
83 | 685 | m_output << "xml:space=\"" << removeNonAscii(_x.value()) << "\" "; |
84 | 685 | break; |
85 | 867 | case KeyValue::SPECIAL: |
86 | 867 | m_output << "xml:special=\"" << removeNonAscii(_x.value()) << "\" "; |
87 | 867 | break; |
88 | 636 | case KeyValue::TEST: |
89 | 636 | m_output << "xml:test=\"" << removeNonAscii(_x.value()) << "\" "; |
90 | 636 | break; |
91 | 7.56k | case KeyValue::FUZZ: |
92 | 7.56k | if (_x.ByteSizeLong() % 2) |
93 | 2.11k | m_output << "xmlns:" << removeNonAscii(_x.key()) << "=\"" << removeNonAscii(_x.value()) << "\" "; |
94 | 5.45k | else |
95 | 5.45k | m_output << removeNonAscii(_x.key()) << "=\"" << removeNonAscii(_x.value()) << "\" "; |
96 | 7.56k | 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 | 21.4k | } |
101 | 21.4k | } |
102 | | |
103 | | void ProtoConverter::visit(ProcessingInstruction const& _x) |
104 | 1.61k | { |
105 | 1.61k | m_output << "<?" << removeNonAscii(_x.name()) << " "; |
106 | 1.61k | for (auto const& prop: _x.kv()) |
107 | 1.68k | visit(prop); |
108 | 1.61k | m_output << "?>\n"; |
109 | 1.61k | } |
110 | | |
111 | | void ProtoConverter::visit(Content const& _x) |
112 | 185k | { |
113 | 185k | switch (_x.content_oneof_case()) |
114 | 185k | { |
115 | 2.06k | case Content::kStr: |
116 | 2.06k | m_output << _x.str() << "\n"; |
117 | 2.06k | break; |
118 | 2.84k | case Content::kE: |
119 | 2.84k | visit(_x.e()); |
120 | 2.84k | m_output << "\n"; |
121 | 2.84k | break; |
122 | 2.28k | case Content::kC: |
123 | 2.28k | visit(_x.c()); |
124 | 2.28k | m_output << "\n"; |
125 | 2.28k | break; |
126 | 178k | case Content::CONTENT_ONEOF_NOT_SET: |
127 | 178k | break; |
128 | 185k | } |
129 | 185k | } |
130 | | |
131 | | void ProtoConverter::visit(ElementDecl const& _x) |
132 | 5.83k | { |
133 | 5.83k | if (!ElementDecl::ContentSpec_IsValid(_x.spec())) |
134 | 36 | return; |
135 | | |
136 | 5.79k | m_output << "<!ELEMENT " << _x.name() << " "; |
137 | 5.79k | switch (_x.spec()) |
138 | 5.79k | { |
139 | 2.39k | case ElementDecl::EMPTY: |
140 | 2.39k | m_output << "EMPTY>"; |
141 | 2.39k | break; |
142 | 164 | case ElementDecl::ANY: |
143 | 164 | m_output << "ANY>"; |
144 | 164 | break; |
145 | 234 | case ElementDecl::FUZZ: |
146 | 234 | m_output << "FUZZ>"; |
147 | 234 | break; |
148 | 1.65k | case ElementDecl::MIXED: |
149 | 1.65k | m_output << "(#PCDATA"; |
150 | 1.65k | for (auto const& pcdata: _x.cdata()) |
151 | 2.75k | m_output << "|" << pcdata; |
152 | 1.65k | m_output << ")"; |
153 | 1.65k | if (_x.cdata_size() > 0) |
154 | 1.02k | m_output << "*"; |
155 | 1.65k | m_output << ">"; |
156 | 1.65k | break; |
157 | 1.35k | case ElementDecl::CHILDREN: |
158 | 1.35k | { |
159 | 1.35k | m_output << "("; |
160 | 1.35k | string delim = ""; |
161 | 2.34k | for (auto const& str: _x.cdata()) { |
162 | 2.34k | m_output << delim << removeNonAscii(str); |
163 | 2.34k | delim = ", "; |
164 | 2.34k | } |
165 | 1.35k | m_output << ")>"; |
166 | 1.35k | 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.79k | } |
172 | 5.79k | } |
173 | | |
174 | | void ProtoConverter::visit(AttValue const& _x) |
175 | 5.94k | { |
176 | 5.94k | if (!isValid(_x)) |
177 | 213 | return; |
178 | | |
179 | 5.72k | m_output << "\""; |
180 | 5.72k | string prefix; |
181 | 5.72k | switch (_x.type()) |
182 | 5.72k | { |
183 | 3.46k | case AttValue::ENTITY: |
184 | 3.46k | prefix = "&"; |
185 | 3.46k | break; |
186 | 1.56k | case AttValue::CHAR: |
187 | 1.56k | if (_x.ByteSizeLong() % 2) |
188 | 341 | prefix = "&#"; |
189 | 1.22k | else |
190 | | // TODO: Value that follows this must be a |
191 | | // sequence of hex digits. |
192 | 1.22k | prefix = "&#x"; |
193 | 1.56k | break; |
194 | 695 | case AttValue::FUZZ: |
195 | 695 | prefix = "fuzz"; |
196 | 695 | 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 | 5.72k | } |
201 | 5.72k | for (auto const& name: _x.value()) |
202 | 7.06k | m_output << prefix << removeNonAscii(name) << ";"; |
203 | 5.72k | m_output << "\""; |
204 | 5.72k | } |
205 | | |
206 | | void ProtoConverter::visit(DefaultDecl const& _x) |
207 | 20.6k | { |
208 | 20.6k | if (!isValid(_x)) |
209 | 98 | return; |
210 | | |
211 | 20.5k | switch (_x.type()) |
212 | 20.5k | { |
213 | 13.8k | case DefaultDecl::REQUIRED: |
214 | 13.8k | m_output << "#REQUIRED"; |
215 | 13.8k | break; |
216 | 453 | case DefaultDecl::IMPLIED: |
217 | 453 | m_output << "#IMPLIED"; |
218 | 453 | break; |
219 | 5.94k | case DefaultDecl::FIXED: |
220 | 5.94k | m_output << "#FIXED "; |
221 | 5.94k | visit(_x.att()); |
222 | 5.94k | break; |
223 | 305 | case DefaultDecl::FUZZ: |
224 | 305 | m_output << "#FUZZ"; |
225 | 305 | 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 | 20.5k | } |
230 | 20.5k | } |
231 | | |
232 | | void ProtoConverter::visit(AttDef const& _x) |
233 | 20.7k | { |
234 | 20.7k | if (!isValid(_x)) |
235 | 66 | return; |
236 | | |
237 | 20.6k | m_output << " " << removeNonAscii(_x.name()) << " "; |
238 | 20.6k | switch (_x.type()) |
239 | 20.6k | { |
240 | 11.3k | case AttDef::CDATA: |
241 | 11.3k | m_output << "CDATA "; |
242 | 11.3k | break; |
243 | 1.29k | case AttDef::ID: |
244 | 1.29k | m_output << "ID "; |
245 | 1.29k | break; |
246 | 4.37k | case AttDef::IDREF: |
247 | 4.37k | m_output << "IDREF "; |
248 | 4.37k | break; |
249 | 542 | case AttDef::IDREFS: |
250 | 542 | m_output << "IDREFS "; |
251 | 542 | break; |
252 | 825 | case AttDef::ENTITY: |
253 | 825 | m_output << "ENTITY "; |
254 | 825 | break; |
255 | 725 | case AttDef::ENTITIES: |
256 | 725 | m_output << "ENTITIES "; |
257 | 725 | break; |
258 | 948 | case AttDef::NMTOKEN: |
259 | 948 | m_output << "NMTOKEN "; |
260 | 948 | break; |
261 | 494 | case AttDef::NMTOKENS: |
262 | 494 | m_output << "NMTOKENS "; |
263 | 494 | break; |
264 | 125 | case AttDef::FUZZ: |
265 | 125 | m_output << "FUZZ "; |
266 | 125 | 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 | 20.6k | } |
271 | 20.6k | visit(_x.def()); |
272 | 20.6k | } |
273 | | |
274 | | void ProtoConverter::visit(AttListDecl const& _x) |
275 | 5.09k | { |
276 | 5.09k | m_output << "<!ATTLIST " << removeNonAscii(_x.name()); |
277 | 5.09k | for (auto const& att: _x.attdefs()) |
278 | 20.7k | visit(att); |
279 | 5.09k | m_output << ">"; |
280 | 5.09k | } |
281 | | |
282 | | void ProtoConverter::visit(NotationDecl const& _x) |
283 | 4.73k | { |
284 | 4.73k | m_output << "<!NOTATION " << removeNonAscii(_x.name()) << " "; |
285 | 4.73k | switch (_x.notation_oneof_case()) |
286 | 4.73k | { |
287 | 1.05k | case NotationDecl::kExt: |
288 | 1.05k | visit(_x.ext()); |
289 | 1.05k | break; |
290 | 2.45k | case NotationDecl::kPub: |
291 | 2.45k | m_output << "PUBLIC " << _x.pub(); |
292 | 2.45k | break; |
293 | 501 | case NotationDecl::kFuzz: |
294 | 501 | m_output << "FUZZ " << _x.fuzz(); |
295 | 501 | break; |
296 | 721 | case NotationDecl::NOTATION_ONEOF_NOT_SET: |
297 | 721 | break; |
298 | 4.73k | } |
299 | 4.73k | m_output << ">"; |
300 | 4.73k | } |
301 | | |
302 | | void ProtoConverter::visit(NDataDecl const& _x) |
303 | 1.94k | { |
304 | 1.94k | m_output << " NDATA " << _x.name(); |
305 | 1.94k | } |
306 | | |
307 | | void ProtoConverter::visit(EntityDef const& _x) |
308 | 8.45k | { |
309 | 8.45k | switch (_x.entity_oneof_case()) |
310 | 8.45k | { |
311 | 3.09k | case EntityDef::kExt: |
312 | 3.09k | visit(_x.ext()); |
313 | 3.09k | if (_x.ByteSizeLong() % 2) |
314 | 1.94k | visit(_x.ndata()); |
315 | 3.09k | break; |
316 | 3.17k | case EntityDef::kVal: |
317 | 3.17k | visit(_x.val()); |
318 | 3.17k | break; |
319 | 2.18k | case EntityDef::ENTITY_ONEOF_NOT_SET: |
320 | 2.18k | break; |
321 | 8.45k | } |
322 | 8.45k | } |
323 | | |
324 | | void ProtoConverter::visit(PEDef const& _x) |
325 | 2.45k | { |
326 | 2.45k | switch (_x.pedef_oneof_case()) |
327 | 2.45k | { |
328 | 703 | case PEDef::kVal: |
329 | 703 | visit(_x.val()); |
330 | 703 | break; |
331 | 804 | case PEDef::kId: |
332 | 804 | visit(_x.id()); |
333 | 804 | break; |
334 | 952 | case PEDef::PEDEF_ONEOF_NOT_SET: |
335 | 952 | break; |
336 | 2.45k | } |
337 | 2.45k | } |
338 | | |
339 | | void ProtoConverter::visit(EntityValue const& _x) |
340 | 3.88k | { |
341 | 3.88k | if (!isValid(_x)) |
342 | 18 | return; |
343 | | |
344 | 3.86k | m_output << "\""; |
345 | 3.86k | string prefix; |
346 | 3.86k | switch (_x.type()) |
347 | 3.86k | { |
348 | 1.66k | case EntityValue::ENTITY: |
349 | 1.66k | prefix = "&"; |
350 | 1.66k | break; |
351 | 1.23k | case EntityValue::CHAR: |
352 | 1.23k | if (_x.ByteSizeLong() % 2) |
353 | 336 | prefix = "&#"; |
354 | 900 | else |
355 | 900 | prefix = "&#x"; |
356 | 1.23k | break; |
357 | 244 | case EntityValue::PEREF: |
358 | 244 | prefix = "%"; |
359 | 244 | break; |
360 | 718 | case EntityValue::FUZZ: |
361 | 718 | prefix = "fuzz"; |
362 | 718 | 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 | 3.86k | } |
367 | 3.86k | for (auto const& ref: _x.name()) |
368 | 9.32k | m_output << prefix << ref << ";"; |
369 | 3.86k | m_output << "\""; |
370 | 3.86k | } |
371 | | |
372 | | void ProtoConverter::visit(EntityDecl const& _x) |
373 | 10.9k | { |
374 | 10.9k | if (!isValid(_x)) |
375 | 81 | return; |
376 | | |
377 | 10.9k | m_output << "<!ENTITY "; |
378 | 10.9k | switch (_x.type()) |
379 | 10.9k | { |
380 | 8.45k | case EntityDecl::GEDECL: |
381 | 8.45k | m_output << _x.name() << " "; |
382 | 8.45k | visit(_x.ent()); |
383 | 8.45k | break; |
384 | 2.45k | case EntityDecl::PEDECL: |
385 | 2.45k | m_output << "% " << _x.name() << " "; |
386 | 2.45k | visit(_x.pedef()); |
387 | 2.45k | 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 | 10.9k | } |
392 | 10.9k | m_output << ">"; |
393 | 10.9k | } |
394 | | |
395 | | void ProtoConverter::visit(ConditionalSect const& _x) |
396 | 9.07k | { |
397 | 9.07k | if (!isValid(_x)) |
398 | 70 | return; |
399 | | |
400 | 9.00k | switch (_x.type()) |
401 | 9.00k | { |
402 | 5.56k | case ConditionalSect::INCLUDE: |
403 | 5.56k | m_output << "<![ INCLUDE ["; |
404 | 5.56k | visit(_x.ext()); |
405 | 5.56k | m_output << "]]>"; |
406 | 5.56k | break; |
407 | 1.32k | case ConditionalSect::IGNORE: |
408 | 1.32k | m_output << "<![ IGNORE ["; |
409 | 1.32k | for (auto const& str: _x.ignores()) |
410 | 1.72k | m_output << "<![" << removeNonAscii(str) << "]]>"; |
411 | 1.32k | m_output << "]]>"; |
412 | 1.32k | break; |
413 | 2.11k | case ConditionalSect::FUZZ: |
414 | 2.11k | m_output << "<![ FUZZ ["; |
415 | 2.11k | visit(_x.ext()); |
416 | 2.11k | m_output << "]]>"; |
417 | 2.11k | 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 | 9.00k | } |
422 | 9.00k | } |
423 | | |
424 | | |
425 | | void ProtoConverter::visit(OneExtSubsetDecl const& _x) |
426 | 44.3k | { |
427 | 44.3k | switch (_x.extsubset_oneof_case()) |
428 | 44.3k | { |
429 | 23.7k | case OneExtSubsetDecl::kM: |
430 | 23.7k | visit(_x.m()); |
431 | 23.7k | break; |
432 | 9.07k | case OneExtSubsetDecl::kC: |
433 | 9.07k | visit(_x.c()); |
434 | 9.07k | break; |
435 | 11.5k | case OneExtSubsetDecl::EXTSUBSET_ONEOF_NOT_SET: |
436 | 11.5k | break; |
437 | 44.3k | } |
438 | 44.3k | } |
439 | | |
440 | | |
441 | | void ProtoConverter::visit(ExtSubsetDecl const& _x) |
442 | 13.9k | { |
443 | 13.9k | for (auto const& decl: _x.decls()) |
444 | 44.3k | visit(decl); |
445 | 13.9k | } |
446 | | |
447 | | void ProtoConverter::visit(CData const& _x) |
448 | 2.28k | { |
449 | 2.28k | m_output << "<![CDATA[" << removeNonAscii(_x.data()) << "]]>"; |
450 | 2.28k | } |
451 | | |
452 | | void ProtoConverter::visit(MarkupDecl const& _x) |
453 | 40.6k | { |
454 | 40.6k | switch (_x.markup_oneof_case()) |
455 | 40.6k | { |
456 | 5.83k | case MarkupDecl::kE: |
457 | 5.83k | visit(_x.e()); |
458 | 5.83k | break; |
459 | 5.09k | case MarkupDecl::kA: |
460 | 5.09k | visit(_x.a()); |
461 | 5.09k | break; |
462 | 4.73k | case MarkupDecl::kN: |
463 | 4.73k | visit(_x.n()); |
464 | 4.73k | break; |
465 | 2.09k | case MarkupDecl::kM: |
466 | 2.09k | visit(_x.m()); |
467 | 2.09k | break; |
468 | 10.9k | case MarkupDecl::kEntity: |
469 | 10.9k | visit(_x.entity()); |
470 | 10.9k | break; |
471 | 6.23k | case MarkupDecl::kExt: |
472 | 6.23k | visit(_x.ext()); |
473 | 6.23k | break; |
474 | 5.67k | case MarkupDecl::MARKUP_ONEOF_NOT_SET: |
475 | 5.67k | break; |
476 | 40.6k | } |
477 | 40.6k | } |
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 | 170k | { |
486 | 170k | string output{}; |
487 | 170k | switch (_x) |
488 | 170k | { |
489 | 158k | case Element::XIINCLUDE: |
490 | 160k | case Element::XIFALLBACK: |
491 | 163k | case Element::XIHREF: |
492 | 163k | output = "xi:include href=\"fuzz.xml\""; |
493 | 165k | case Element::XIPARSE: |
494 | 165k | output = "xi:include parse=\"xml\""; |
495 | 165k | case Element::XIXPOINTER: |
496 | 165k | output = "xi:include xpointer=\"" + removeNonAscii(_prop) + "\""; |
497 | 167k | case Element::XIENCODING: |
498 | 167k | output = "xi:include encoding=\"" + removeNonAscii(_prop) + "\""; |
499 | 169k | case Element::XIACCEPT: |
500 | 169k | output = "xi:include accept=\"" + removeNonAscii(_prop) + "\""; |
501 | 170k | case Element::XIACCEPTLANG: |
502 | 170k | output = "xi:include accept-language=\"" + removeNonAscii(_prop) + "\""; |
503 | 170k | case Element_Id_Element_Id_INT_MIN_SENTINEL_DO_NOT_USE_: |
504 | 170k | case Element_Id_Element_Id_INT_MAX_SENTINEL_DO_NOT_USE_: |
505 | 170k | output = "xi:fuzz xifuzz=\"fuzz\""; |
506 | 170k | } |
507 | 170k | return output; |
508 | 170k | } |
509 | | |
510 | | /// Returns uri string for a given Element_Id type |
511 | | string ProtoConverter::getUri(Element_Id _x) |
512 | 170k | { |
513 | 170k | if (!Element::Id_IsValid(_x)) |
514 | 237 | return s_XInclude; |
515 | | |
516 | 170k | switch (_x) |
517 | 170k | { |
518 | 158k | case Element::XIINCLUDE: |
519 | 160k | case Element::XIFALLBACK: |
520 | 163k | case Element::XIHREF: |
521 | 165k | case Element::XIPARSE: |
522 | 165k | case Element::XIXPOINTER: |
523 | 167k | case Element::XIENCODING: |
524 | 169k | case Element::XIACCEPT: |
525 | 170k | case Element::XIACCEPTLANG: |
526 | 170k | case Element_Id_Element_Id_INT_MIN_SENTINEL_DO_NOT_USE_: |
527 | 170k | case Element_Id_Element_Id_INT_MAX_SENTINEL_DO_NOT_USE_: |
528 | 170k | return s_XInclude; |
529 | 170k | } |
530 | 170k | } |
531 | | |
532 | | void ProtoConverter::visit(Element const& _x) |
533 | 185k | { |
534 | 185k | if (!isValid(_x)) |
535 | 22 | return; |
536 | | |
537 | | // Predefined child node |
538 | 185k | string child = {}; |
539 | | // Predefined uri for child node |
540 | 185k | string pUri = {}; |
541 | | // Element name |
542 | 185k | string name = removeNonAscii(_x.name()); |
543 | | |
544 | 185k | switch (_x.type()) |
545 | 185k | { |
546 | 170k | case Element::PREDEFINED: |
547 | 170k | child = getPredefined(_x.id(), _x.childprop()); |
548 | 170k | pUri = getUri(_x.id()); |
549 | 170k | break; |
550 | 14.7k | case Element::FUZZ: |
551 | 14.7k | case Element_Type_Element_Type_INT_MIN_SENTINEL_DO_NOT_USE_: |
552 | 14.7k | case Element_Type_Element_Type_INT_MAX_SENTINEL_DO_NOT_USE_: |
553 | 14.7k | break; |
554 | 185k | } |
555 | | |
556 | | // <name k1=v1 k2=v2 k3=v3> |
557 | | // <content> |
558 | | // </name> |
559 | | |
560 | | // Start name tag: Must be Ascii? |
561 | 185k | m_output << "<" << name << " "; |
562 | | |
563 | | // Add uri to name tag |
564 | 185k | if (!pUri.empty()) |
565 | 170k | m_output << pUri << " "; |
566 | 185k | for (auto const& prop: _x.kv()) |
567 | 19.8k | visit(prop); |
568 | 185k | m_output << ">\n"; |
569 | | |
570 | | // Add attribute |
571 | 185k | if (!child.empty()) |
572 | 170k | m_output << "<" << child << "/>\n"; |
573 | | |
574 | | // Add content |
575 | 185k | visit(_x.content()); |
576 | | |
577 | | // Close name tag |
578 | 185k | m_output << "</" << name << ">\n"; |
579 | 185k | } |
580 | | |
581 | | void ProtoConverter::visit(ExternalId const& _x) |
582 | 13.2k | { |
583 | 13.2k | if (!isValid(_x)) |
584 | 985 | return; |
585 | | |
586 | 12.2k | switch (_x.type()) |
587 | 12.2k | { |
588 | 10.0k | case ExternalId::SYSTEM: |
589 | 10.0k | m_output << "SYSTEM " << "\"" << removeNonAscii(_x.system()) << "\""; |
590 | 10.0k | break; |
591 | 724 | case ExternalId::PUBLIC: |
592 | 724 | m_output << "PUBLIC " << "\"" << removeNonAscii(_x.pub()) << "\"" |
593 | 724 | << " " << "\"" << removeNonAscii(_x.system()) << "\""; |
594 | 724 | break; |
595 | 1.41k | case ExternalId::FUZZ: |
596 | 1.41k | m_output << "FUZZ " << "\"" << removeNonAscii(_x.pub()) << "\""; |
597 | 1.41k | 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 | 12.2k | } |
602 | 12.2k | } |
603 | | |
604 | | void ProtoConverter::visit(DocTypeDecl const& _x) |
605 | 8.25k | { |
606 | 8.25k | m_output << "<!DOCTYPE " << removeNonAscii(_x.name()) << " "; |
607 | 8.25k | visit(_x.ext()); |
608 | 8.25k | m_output << "["; |
609 | 8.25k | for (auto const& m: _x.mdecl()) |
610 | 16.8k | visit(m); |
611 | 8.25k | m_output << "]"; |
612 | 8.25k | m_output << ">\n"; |
613 | 8.25k | } |
614 | | |
615 | | void ProtoConverter::visit(VersionNum const& _x) |
616 | 8.25k | { |
617 | 8.25k | if (!isValid(_x)) |
618 | 2 | return; |
619 | | |
620 | 8.25k | switch (_x.type()) |
621 | 8.25k | { |
622 | 8.10k | case VersionNum::STANDARD: |
623 | 8.10k | m_output << "\"1.0\""; |
624 | 8.10k | break; |
625 | 149 | case VersionNum::FUZZ: |
626 | 149 | case VersionNum_Type_VersionNum_Type_INT_MIN_SENTINEL_DO_NOT_USE_: |
627 | 149 | case VersionNum_Type_VersionNum_Type_INT_MAX_SENTINEL_DO_NOT_USE_: |
628 | 149 | m_output << "\"" << _x.major() << "." << _x.minor() << "\""; |
629 | 149 | break; |
630 | 8.25k | } |
631 | 8.25k | } |
632 | | |
633 | | void ProtoConverter::visit(Encodings const& _x) |
634 | 8.25k | { |
635 | 8.25k | if (!Encodings::Enc_IsValid(_x.name())) |
636 | 632 | return; |
637 | | |
638 | 7.62k | m_output << " encoding=\""; |
639 | 7.62k | switch (_x.name()) |
640 | 7.62k | { |
641 | 6.74k | case Encodings::BIG5: |
642 | 6.74k | m_output << "BIG5"; |
643 | 6.74k | break; |
644 | 12 | case Encodings::EUCJP: |
645 | 12 | m_output << "EUC-JP"; |
646 | 12 | break; |
647 | 39 | case Encodings::EUCKR: |
648 | 39 | m_output << "EUC-KR"; |
649 | 39 | break; |
650 | 15 | case Encodings::GB18030: |
651 | 15 | m_output << "GB18030"; |
652 | 15 | break; |
653 | 1 | case Encodings::ISO2022JP: |
654 | 1 | m_output << "ISO-2022-JP"; |
655 | 1 | break; |
656 | 125 | case Encodings::ISO2022KR: |
657 | 125 | m_output << "ISO-2022-KR"; |
658 | 125 | break; |
659 | 90 | case Encodings::ISO88591: |
660 | 90 | m_output << "ISO-8859-1"; |
661 | 90 | break; |
662 | 16 | case Encodings::ISO88592: |
663 | 16 | m_output << "ISO-8859-2"; |
664 | 16 | break; |
665 | 15 | case Encodings::ISO88593: |
666 | 15 | m_output << "ISO-8859-3"; |
667 | 15 | break; |
668 | 8 | case Encodings::ISO88594: |
669 | 8 | m_output << "ISO-8859-4"; |
670 | 8 | break; |
671 | 11 | case Encodings::ISO88595: |
672 | 11 | m_output << "ISO-8859-5"; |
673 | 11 | break; |
674 | 7 | case Encodings::ISO88596: |
675 | 7 | m_output << "ISO-8859-6"; |
676 | 7 | break; |
677 | 7 | case Encodings::ISO88597: |
678 | 7 | m_output << "ISO-8859-7"; |
679 | 7 | break; |
680 | 5 | case Encodings::ISO88598: |
681 | 5 | m_output << "ISO-8859-8"; |
682 | 5 | break; |
683 | 13 | case Encodings::ISO88599: |
684 | 13 | m_output << "ISO-8859-9"; |
685 | 13 | break; |
686 | 115 | case Encodings::SHIFTJIS: |
687 | 115 | m_output << "SHIFT_JIS"; |
688 | 115 | break; |
689 | 13 | case Encodings::TIS620: |
690 | 13 | m_output << "TIS-620"; |
691 | 13 | break; |
692 | 82 | case Encodings::USASCII: |
693 | 82 | m_output << "US-ASCII"; |
694 | 82 | break; |
695 | 56 | case Encodings::UTF8: |
696 | 56 | m_output << "UTF-8"; |
697 | 56 | break; |
698 | 40 | case Encodings::UTF16: |
699 | 40 | m_output << "UTF-16"; |
700 | 40 | break; |
701 | 14 | case Encodings::UTF16BE: |
702 | 14 | m_output << "UTF-16BE"; |
703 | 14 | break; |
704 | 15 | case Encodings::UTF16LE: |
705 | 15 | m_output << "UTF-16LE"; |
706 | 15 | break; |
707 | 28 | case Encodings::WINDOWS31J: |
708 | 28 | m_output << "WINDOWS-31J"; |
709 | 28 | break; |
710 | 5 | case Encodings::WINDOWS1255: |
711 | 5 | m_output << "WINDOWS-1255"; |
712 | 5 | break; |
713 | 6 | case Encodings::WINDOWS1256: |
714 | 6 | m_output << "WINDOWS-1256"; |
715 | 6 | break; |
716 | 142 | case Encodings::FUZZ: |
717 | 142 | m_output << removeNonAscii(_x.fuzz()); |
718 | 142 | 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.62k | } |
723 | 7.62k | m_output << "\""; |
724 | 7.62k | } |
725 | | |
726 | | void ProtoConverter::visit(XmlDeclaration const& _x) |
727 | 8.25k | { |
728 | 8.25k | m_output << R"(<?xml version=)"; |
729 | 8.25k | visit(_x.ver()); |
730 | 8.25k | visit(_x.enc()); |
731 | 8.25k | switch (_x.standalone()) |
732 | 8.25k | { |
733 | 7.91k | case XmlDeclaration::YES: |
734 | 7.91k | m_output << " standalone=\'yes\'"; |
735 | 7.91k | break; |
736 | 286 | case XmlDeclaration::NO: |
737 | 286 | m_output << " standalone=\'no\'"; |
738 | 286 | 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 | 54 | default: |
742 | 54 | break; |
743 | 8.25k | } |
744 | 8.25k | m_output << "?>\n"; |
745 | 8.25k | } |
746 | | |
747 | | void ProtoConverter::visit(XmlDocument const& _x) |
748 | 8.25k | { |
749 | 8.25k | visit(_x.p()); |
750 | 8.25k | for (auto const& element: _x.e()) |
751 | 182k | visit(element); |
752 | 8.25k | } |
753 | | |
754 | | string ProtoConverter::protoToString(XmlDocument const& _x) |
755 | 8.25k | { |
756 | 8.25k | visit(_x); |
757 | 8.25k | return m_output.str(); |
758 | 8.25k | } |