Coverage Report

Created: 2026-10-01 06:55

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