xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
libxrpl
json
json_writer.cpp
1
#include <xrpl/json/json_writer.h>
2
3
#include <xrpl/beast/utility/instrumentation.h>
4
#include <xrpl/json/json_forwards.h>
5
#include <xrpl/json/json_value.h>
6
7
#include <
charconv
>
8
#include <
cstring
>
9
#include <
iomanip
>
10
#include <
ios
>
11
#include <
ostream
>
12
#include <
sstream
>
13
#include <
string
>
14
#include <
system_error
>
15
#include <
utility
>
16
17
namespace
json
{
18
19
static
bool
20
isControlCharacter
(
char
ch)
21
{
22
return
ch > 0 && ch <= 0x1F;
23
}
24
25
static
bool
26
containsControlCharacter
(
char
const
* str)
27
{
28
while
(*str != 0)
29
{
30
if
(
isControlCharacter
(*(str++)))
31
return
true
;
32
}
33
34
return
false
;
35
}
36
static
void
37
uintToString
(
unsigned
int
value,
char
*& current)
38
{
39
*--current = 0;
40
41
do
42
{
43
*--current = (value % 10) +
'0'
;
44
value /= 10;
45
}
while
(value != 0);
46
}
47
48
std::string
49
valueToString
(
Int
value)
50
{
51
char
buffer[32];
52
char
* current = buffer +
sizeof
(buffer);
// NOLINT(misc-const-correctness)
53
bool
const
isNegative = value < 0;
54
55
if
(isNegative)
56
value = -value;
57
58
uintToString
(
UInt
(value), current);
59
60
if
(isNegative)
61
*--current =
'-'
;
62
63
XRPL_ASSERT(current >= buffer,
"json::valueToString(Int) : buffer check"
);
64
return
current;
65
}
66
67
std::string
68
valueToString
(
UInt
value)
69
{
70
char
buffer[32];
71
char
* current = buffer +
sizeof
(buffer);
// NOLINT(misc-const-correctness)
72
uintToString
(value, current);
73
XRPL_ASSERT(current >= buffer,
"json::valueToString(UInt) : buffer check"
);
74
return
current;
75
}
76
77
std::string
78
valueToString
(
double
value)
79
{
80
// Format with 16 significant digits.
81
// We need not request the alternative representation that always has a
82
// decimal point because JSON doesn't distinguish the concepts of reals and integers.
83
// A double never needs more than 32 characters in this form,
84
// so to_chars cannot actually run out of room here.
85
char
buffer[32];
86
auto
const
[ptr, ec] =
87
std::to_chars
(buffer, buffer +
sizeof
(buffer), value, std::chars_format::general, 16);
88
XRPL_ASSERT(ec ==
std::errc
{},
"json::valueToString(double) : conversion fits buffer"
);
89
if
(ec !=
std::errc
{})
90
return
{};
91
return
std::string
(buffer, ptr);
92
}
93
94
std::string
95
valueToString
(
bool
value)
96
{
97
return
value ?
"true"
:
"false"
;
98
}
99
100
std::string
101
valueToQuotedString
(
char
const
* value)
102
{
103
// Not sure how to handle unicode...
104
if
(strpbrk(value,
"\"\\\b\f\n\r\t"
) ==
nullptr
&& !
containsControlCharacter
(value))
105
return
std::string
(
"\""
) + value +
"\""
;
106
107
// We have to walk value and escape any special characters.
108
// Appending to std::string is not efficient, but this should be rare.
109
// (Note: forward slashes are *not* rare, but I am not escaping them.)
110
unsigned
const
maxsize = (strlen(value) * 2) + 3;
// all-escaped+quotes+NULL
111
std::string
result;
112
result.
reserve
(maxsize);
// to avoid lots of mallocs
113
result +=
"\""
;
114
115
for
(
char
const
* c = value; *c != 0; ++c)
116
{
117
switch
(*c)
118
{
119
case
'\"'
:
120
result +=
"\\\""
;
121
break
;
122
123
case
'\\'
:
124
result +=
"\\\\"
;
125
break
;
126
127
case
'\b'
:
128
result +=
"\\b"
;
129
break
;
130
131
case
'\f'
:
132
result +=
"\\f"
;
133
break
;
134
135
case
'\n'
:
136
result +=
"\\n"
;
137
break
;
138
139
case
'\r'
:
140
result +=
"\\r"
;
141
break
;
142
143
case
'\t'
:
144
result +=
"\\t"
;
145
break
;
146
147
// case '/':
148
// Even though \/ is considered a legal escape in JSON, a bare
149
// slash is also legal, so I see no reason to escape it.
150
// (I hope I am not misunderstanding something.
151
// blep notes: actually escaping \/ may be useful in javascript
152
// to avoid </ sequence. Should add a flag to allow this
153
// compatibility mode and prevent this sequence from occurring.
154
default
:
155
if
(
isControlCharacter
(*c))
156
{
157
std::ostringstream
oss;
158
oss <<
"\\u"
<<
std::hex
<<
std::uppercase
<<
std::setfill
(
'0'
) <<
std::setw
(4)
159
<<
static_cast<
int
>
(*c);
160
result += oss.
str
();
161
}
162
else
163
{
164
result += *c;
165
}
166
167
break
;
168
}
169
}
170
171
result +=
"\""
;
172
return
result;
173
}
174
175
// Class FastWriter
176
// //////////////////////////////////////////////////////////////////
177
178
std::string
179
FastWriter::write
(
Value
const
& root)
180
{
181
document_
=
""
;
182
writeValue
(root);
183
return
std::move(
document_
);
184
}
185
186
void
187
FastWriter::writeValue
(
Value
const
& value)
188
{
189
switch
(value.type())
190
{
191
case
ValueType::Null
:
192
document_
+=
"null"
;
193
break
;
194
195
case
ValueType::Int
:
196
document_
+=
valueToString
(value.asInt());
197
break
;
198
199
case
ValueType::UInt
:
200
document_
+=
valueToString
(value.asUInt());
201
break
;
202
203
case
ValueType::Real
:
204
document_
+=
valueToString
(value.asDouble());
205
break
;
206
207
case
ValueType::String
:
208
document_
+=
valueToQuotedString
(value.asCString());
209
break
;
210
211
case
ValueType::Boolean
:
212
document_
+=
valueToString
(value.asBool());
213
break
;
214
215
case
ValueType::Array
: {
216
document_
+=
"["
;
217
int
const
size = value.size();
218
219
for
(
int
index = 0; index < size; ++index)
220
{
221
if
(index > 0)
222
document_
+=
","
;
223
224
writeValue
(value[index]);
225
}
226
227
document_
+=
"]"
;
228
}
229
break
;
230
231
case
ValueType::Object
: {
232
Value::Members
members(value.getMemberNames());
233
document_
+=
"{"
;
234
235
for
(
auto
it = members.
begin
(); it != members.
end
(); ++it)
236
{
237
std::string
const
& name = *it;
238
239
if
(it != members.
begin
())
240
document_
+=
","
;
241
242
document_
+=
valueToQuotedString
(name.
c_str
());
243
document_
+=
":"
;
244
writeValue
(value[name]);
245
}
246
247
document_
+=
"}"
;
248
}
249
break
;
250
}
251
}
252
253
// Class StyledWriter
254
// //////////////////////////////////////////////////////////////////
255
256
StyledWriter::StyledWriter
() =
default
;
257
258
std::string
259
StyledWriter::write
(
Value
const
& root)
260
{
261
document_
=
""
;
262
addChildValues_
=
false
;
263
indentString_
=
""
;
264
writeValue
(root);
265
document_
+=
"\n"
;
266
return
document_
;
267
}
268
269
void
270
StyledWriter::writeValue
(
Value
const
& value)
271
{
272
switch
(value.type())
273
{
274
case
ValueType::Null
:
275
pushValue
(
"null"
);
276
break
;
277
278
case
ValueType::Int
:
279
pushValue
(
valueToString
(value.asInt()));
280
break
;
281
282
case
ValueType::UInt
:
283
pushValue
(
valueToString
(value.asUInt()));
284
break
;
285
286
case
ValueType::Real
:
287
pushValue
(
valueToString
(value.asDouble()));
288
break
;
289
290
case
ValueType::String
:
291
pushValue
(
valueToQuotedString
(value.asCString()));
292
break
;
293
294
case
ValueType::Boolean
:
295
pushValue
(
valueToString
(value.asBool()));
296
break
;
297
298
case
ValueType::Array
:
299
writeArrayValue
(value);
300
break
;
301
302
case
ValueType::Object
: {
303
Value::Members
members(value.getMemberNames());
304
305
if
(members.
empty
())
306
{
307
pushValue
(
"{}"
);
308
}
309
else
310
{
311
writeWithIndent
(
"{"
);
312
indent
();
313
auto
it = members.
begin
();
314
315
while
(
true
)
316
{
317
std::string
const
& name = *it;
318
Value
const
& childValue = value[name];
319
writeWithIndent
(
valueToQuotedString
(name.
c_str
()));
320
document_
+=
" : "
;
321
writeValue
(childValue);
322
323
if
(++it; it == members.
end
())
324
break
;
325
326
document_
+=
","
;
327
}
328
329
unindent
();
330
writeWithIndent
(
"}"
);
331
}
332
}
333
break
;
334
}
335
}
336
337
void
338
StyledWriter::writeArrayValue
(
Value
const
& value)
339
{
340
unsigned
const
size = value.size();
341
342
if
(size == 0)
343
{
344
pushValue
(
"[]"
);
345
}
346
else
347
{
348
bool
const
isArrayMultiLine =
isMultilineArray
(value);
349
350
if
(isArrayMultiLine)
351
{
352
writeWithIndent
(
"["
);
353
indent
();
354
bool
const
hasChildValue = !
childValues_
.empty();
355
unsigned
index = 0;
356
357
while
(
true
)
358
{
359
Value
const
& childValue = value[index];
360
361
if
(hasChildValue)
362
{
363
writeWithIndent
(
childValues_
[index]);
364
}
365
else
366
{
367
writeIndent
();
368
writeValue
(childValue);
369
}
370
371
if
(++index == size)
372
break
;
373
374
document_
+=
","
;
375
}
376
377
unindent
();
378
writeWithIndent
(
"]"
);
379
}
380
else
// output on a single line
381
{
382
XRPL_ASSERT(
383
childValues_
.size() == size,
384
"json::StyledWriter::writeArrayValue : child size match"
);
385
document_
+=
"[ "
;
386
387
for
(
unsigned
index = 0; index < size; ++index)
388
{
389
if
(index > 0)
390
document_
+=
", "
;
391
392
document_
+=
childValues_
[index];
393
}
394
395
document_
+=
" ]"
;
396
}
397
}
398
}
399
400
bool
401
StyledWriter::isMultilineArray
(
Value
const
& value)
402
{
403
int
const
size = value.size();
404
bool
isMultiLine = size * 3 >=
rightMargin_
;
405
childValues_
.clear();
406
407
for
(
int
index = 0; index < size && !isMultiLine; ++index)
408
{
409
Value
const
& childValue = value[index];
410
isMultiLine = isMultiLine ||
411
((childValue.
isArray
() || childValue.
isObject
()) && childValue.
size
() > 0);
412
}
413
414
if
(!isMultiLine)
// check if line length > max line length
415
{
416
childValues_
.reserve(size);
417
addChildValues_
=
true
;
418
int
lineLength = 4 + ((size - 1) * 2);
// '[ ' + ', '*n + ' ]'
419
420
for
(
int
index = 0; index < size; ++index)
421
{
422
writeValue
(value[index]);
423
lineLength += int(
childValues_
[index].length());
424
}
425
426
addChildValues_
=
false
;
427
isMultiLine = isMultiLine || lineLength >=
rightMargin_
;
428
}
429
430
return
isMultiLine;
431
}
432
433
void
434
StyledWriter::pushValue
(
std::string
const
& value)
435
{
436
if
(
addChildValues_
)
437
{
438
childValues_
.push_back(value);
439
}
440
else
441
{
442
document_
+= value;
443
}
444
}
445
446
void
447
StyledWriter::writeIndent
()
448
{
449
if
(!
document_
.empty())
450
{
451
char
const
last =
document_
[
document_
.length() - 1];
452
453
if
(last ==
' '
)
// already indented
454
return
;
455
456
if
(last !=
'\n'
)
// Comments may add new-line
457
document_
+=
'\n'
;
458
}
459
460
document_
+=
indentString_
;
461
}
462
463
void
464
StyledWriter::writeWithIndent
(
std::string
const
& value)
465
{
466
writeIndent
();
467
document_
+= value;
468
}
469
470
void
471
StyledWriter::indent
()
472
{
473
indentString_
+=
std::string
(
indentSize_
,
' '
);
474
}
475
476
void
477
StyledWriter::unindent
()
478
{
479
XRPL_ASSERT(
480
int
(
indentString_
.size()) >=
indentSize_
,
481
"json::StyledWriter::unindent : maximum indent size"
);
482
indentString_
.resize(
indentString_
.size() -
indentSize_
);
483
}
484
485
// Class StyledStreamWriter
486
// //////////////////////////////////////////////////////////////////
487
488
StyledStreamWriter::StyledStreamWriter
(
std::string
indentation)
489
:
indentation_
(
std
::move(indentation))
490
{
491
}
492
493
void
494
StyledStreamWriter::write
(
std::ostream
& out,
Value
const
& root)
495
{
496
document_
= &out;
497
addChildValues_
=
false
;
498
indentString_
=
""
;
499
writeValue
(root);
500
*
document_
<<
"\n"
;
501
document_
=
nullptr
;
// Forget the stream, for safety.
502
}
503
504
void
505
StyledStreamWriter::writeValue
(
Value
const
& value)
506
{
507
switch
(value.type())
508
{
509
case
ValueType::Null
:
510
pushValue
(
"null"
);
511
break
;
512
513
case
ValueType::Int
:
514
pushValue
(
valueToString
(value.asInt()));
515
break
;
516
517
case
ValueType::UInt
:
518
pushValue
(
valueToString
(value.asUInt()));
519
break
;
520
521
case
ValueType::Real
:
522
pushValue
(
valueToString
(value.asDouble()));
523
break
;
524
525
case
ValueType::String
:
526
pushValue
(
valueToQuotedString
(value.asCString()));
527
break
;
528
529
case
ValueType::Boolean
:
530
pushValue
(
valueToString
(value.asBool()));
531
break
;
532
533
case
ValueType::Array
:
534
writeArrayValue
(value);
535
break
;
536
537
case
ValueType::Object
: {
538
Value::Members
members(value.getMemberNames());
539
540
if
(members.
empty
())
541
{
542
pushValue
(
"{}"
);
543
}
544
else
545
{
546
writeWithIndent
(
"{"
);
547
indent
();
548
auto
it = members.
begin
();
549
550
while
(
true
)
551
{
552
std::string
const
& name = *it;
553
Value
const
& childValue = value[name];
554
writeWithIndent
(
valueToQuotedString
(name.
c_str
()));
555
*
document_
<<
" : "
;
556
writeValue
(childValue);
557
558
if
(++it == members.
end
())
559
break
;
560
561
*
document_
<<
","
;
562
}
563
564
unindent
();
565
writeWithIndent
(
"}"
);
566
}
567
}
568
break
;
569
}
570
}
571
572
void
573
StyledStreamWriter::writeArrayValue
(
Value
const
& value)
574
{
575
unsigned
const
size = value.size();
576
577
if
(size == 0)
578
{
579
pushValue
(
"[]"
);
580
}
581
else
582
{
583
bool
const
isArrayMultiLine =
isMultilineArray
(value);
584
585
if
(isArrayMultiLine)
586
{
587
writeWithIndent
(
"["
);
588
indent
();
589
bool
const
hasChildValue = !
childValues_
.empty();
590
unsigned
index = 0;
591
592
while
(
true
)
593
{
594
Value
const
& childValue = value[index];
595
596
if
(hasChildValue)
597
{
598
writeWithIndent
(
childValues_
[index]);
599
}
600
else
601
{
602
writeIndent
();
603
writeValue
(childValue);
604
}
605
606
if
(++index == size)
607
break
;
608
609
*
document_
<<
","
;
610
}
611
612
unindent
();
613
writeWithIndent
(
"]"
);
614
}
615
else
// output on a single line
616
{
617
XRPL_ASSERT(
618
childValues_
.size() == size,
619
"json::StyledStreamWriter::writeArrayValue : child size match"
);
620
*
document_
<<
"[ "
;
621
622
for
(
unsigned
index = 0; index < size; ++index)
623
{
624
if
(index > 0)
625
*
document_
<<
", "
;
626
627
*
document_
<<
childValues_
[index];
628
}
629
630
*
document_
<<
" ]"
;
631
}
632
}
633
}
634
635
bool
636
StyledStreamWriter::isMultilineArray
(
Value
const
& value)
637
{
638
int
const
size = value.size();
639
bool
isMultiLine = size * 3 >=
rightMargin_
;
640
childValues_
.clear();
641
642
for
(
int
index = 0; index < size && !isMultiLine; ++index)
643
{
644
Value
const
& childValue = value[index];
645
isMultiLine = isMultiLine ||
646
((childValue.
isArray
() || childValue.
isObject
()) && childValue.
size
() > 0);
647
}
648
649
if
(!isMultiLine)
// check if line length > max line length
650
{
651
childValues_
.reserve(size);
652
addChildValues_
=
true
;
653
int
lineLength = 4 + ((size - 1) * 2);
// '[ ' + ', '*n + ' ]'
654
655
for
(
int
index = 0; index < size; ++index)
656
{
657
writeValue
(value[index]);
658
lineLength += int(
childValues_
[index].length());
659
}
660
661
addChildValues_
=
false
;
662
isMultiLine = isMultiLine || lineLength >=
rightMargin_
;
663
}
664
665
return
isMultiLine;
666
}
667
668
void
669
StyledStreamWriter::pushValue
(
std::string
const
& value)
670
{
671
if
(
addChildValues_
)
672
{
673
childValues_
.push_back(value);
674
}
675
else
676
{
677
*
document_
<< value;
678
}
679
}
680
681
void
682
StyledStreamWriter::writeIndent
()
683
{
684
/*
685
Some comments in this method would have been nice. ;-)
686
687
if ( !document_.empty() )
688
{
689
char last = document_[document_.length()-1];
690
if ( last == ' ' ) // already indented
691
return;
692
if ( last != '\n' ) // Comments may add new-line
693
*document_ << '\n';
694
}
695
*/
696
*
document_
<<
'\n'
<<
indentString_
;
697
}
698
699
void
700
StyledStreamWriter::writeWithIndent
(
std::string
const
& value)
701
{
702
writeIndent
();
703
*
document_
<< value;
704
}
705
706
void
707
StyledStreamWriter::indent
()
708
{
709
indentString_
+=
indentation_
;
710
}
711
712
void
713
StyledStreamWriter::unindent
()
714
{
715
XRPL_ASSERT(
716
indentString_
.size() >=
indentation_
.size(),
717
"json::StyledStreamWriter::unindent : maximum indent size"
);
718
indentString_
.resize(
indentString_
.size() -
indentation_
.size());
719
}
720
721
std::ostream
&
722
operator<<
(
std::ostream
& sout,
Value
const
& root)
723
{
724
json::StyledStreamWriter
writer;
725
writer.
write
(sout, root);
726
return
sout;
727
}
728
729
}
// namespace json
std::ostream
std::ostringstream
std::string
std::vector::begin
T begin(T... args)
std::string::c_str
T c_str(T... args)
charconv
json::FastWriter::writeValue
void writeValue(Value const &value)
Definition
json_writer.cpp:187
json::FastWriter::write
std::string write(Value const &root) override
Definition
json_writer.cpp:179
json::FastWriter::document_
std::string document_
Definition
json_writer.h:50
json::StyledStreamWriter
Writes a Value in JSON format in a human friendly way, to a stream rather than to a string.
Definition
json_writer.h:138
json::StyledStreamWriter::writeIndent
void writeIndent()
Definition
json_writer.cpp:682
json::StyledStreamWriter::indentation_
std::string indentation_
Definition
json_writer.h:178
json::StyledStreamWriter::pushValue
void pushValue(std::string const &value)
Definition
json_writer.cpp:669
json::StyledStreamWriter::unindent
void unindent()
Definition
json_writer.cpp:713
json::StyledStreamWriter::writeArrayValue
void writeArrayValue(Value const &value)
Definition
json_writer.cpp:573
json::StyledStreamWriter::addChildValues_
bool addChildValues_
Definition
json_writer.h:179
json::StyledStreamWriter::document_
std::ostream * document_
Definition
json_writer.h:175
json::StyledStreamWriter::write
void write(std::ostream &out, Value const &root)
Serialize a Value in JSON format.
Definition
json_writer.cpp:494
json::StyledStreamWriter::writeValue
void writeValue(Value const &value)
Definition
json_writer.cpp:505
json::StyledStreamWriter::isMultilineArray
bool isMultilineArray(Value const &value)
Definition
json_writer.cpp:636
json::StyledStreamWriter::rightMargin_
int rightMargin_
Definition
json_writer.h:177
json::StyledStreamWriter::StyledStreamWriter
StyledStreamWriter(std::string indentation="\t")
Definition
json_writer.cpp:488
json::StyledStreamWriter::indent
void indent()
Definition
json_writer.cpp:707
json::StyledStreamWriter::writeWithIndent
void writeWithIndent(std::string const &value)
Definition
json_writer.cpp:700
json::StyledStreamWriter::childValues_
ChildValues childValues_
Definition
json_writer.h:174
json::StyledStreamWriter::indentString_
std::string indentString_
Definition
json_writer.h:176
json::StyledWriter::pushValue
void pushValue(std::string const &value)
Definition
json_writer.cpp:434
json::StyledWriter::indentSize_
int indentSize_
Definition
json_writer.h:111
json::StyledWriter::childValues_
ChildValues childValues_
Definition
json_writer.h:107
json::StyledWriter::isMultilineArray
bool isMultilineArray(Value const &value)
Definition
json_writer.cpp:401
json::StyledWriter::write
std::string write(Value const &root) override
Serialize a Value in JSON format.
Definition
json_writer.cpp:259
json::StyledWriter::indentString_
std::string indentString_
Definition
json_writer.h:109
json::StyledWriter::writeValue
void writeValue(Value const &value)
Definition
json_writer.cpp:270
json::StyledWriter::addChildValues_
bool addChildValues_
Definition
json_writer.h:112
json::StyledWriter::writeWithIndent
void writeWithIndent(std::string const &value)
Definition
json_writer.cpp:464
json::StyledWriter::unindent
void unindent()
Definition
json_writer.cpp:477
json::StyledWriter::indent
void indent()
Definition
json_writer.cpp:471
json::StyledWriter::StyledWriter
StyledWriter()
json::StyledWriter::rightMargin_
int rightMargin_
Definition
json_writer.h:110
json::StyledWriter::writeIndent
void writeIndent()
Definition
json_writer.cpp:447
json::StyledWriter::writeArrayValue
void writeArrayValue(Value const &value)
Definition
json_writer.cpp:338
json::StyledWriter::document_
std::string document_
Definition
json_writer.h:108
json::Value
Represents a JSON value.
Definition
json_value.h:117
json::Value::isObject
bool isObject() const
Definition
json_value.cpp:1152
json::Value::Members
std::vector< std::string > Members
Definition
json_value.h:121
json::Value::isArray
bool isArray() const
Definition
json_value.cpp:1140
json::Value::size
UInt size() const
Number of values in array or object.
Definition
json_value.cpp:801
cstring
std::vector::empty
T empty(T... args)
std::vector::end
T end(T... args)
std::errc
std::hex
T hex(T... args)
iomanip
ios
json
JSON (JavaScript Object Notation).
Definition
json_errors.h:5
json::Int
int Int
Definition
json_forwards.h:6
json::valueToQuotedString
std::string valueToQuotedString(char const *value)
Definition
json_writer.cpp:101
json::containsControlCharacter
static bool containsControlCharacter(char const *str)
Definition
json_writer.cpp:26
json::UInt
unsigned int UInt
Definition
json_forwards.h:7
json::isControlCharacter
static bool isControlCharacter(char ch)
Definition
json_writer.cpp:20
json::ValueType::UInt
@ UInt
unsigned integer value
Definition
json_value.h:24
json::ValueType::Int
@ Int
signed integer value
Definition
json_value.h:23
json::ValueType::String
@ String
UTF-8 string value.
Definition
json_value.h:26
json::ValueType::Boolean
@ Boolean
bool value
Definition
json_value.h:27
json::ValueType::Array
@ Array
array value (ordered list)
Definition
json_value.h:28
json::ValueType::Object
@ Object
object value (collection of name/value pairs).
Definition
json_value.h:29
json::ValueType::Real
@ Real
double value
Definition
json_value.h:25
json::ValueType::Null
@ Null
'null' value
Definition
json_value.h:22
json::uintToString
static void uintToString(unsigned int value, char *¤t)
Definition
json_writer.cpp:37
json::operator<<
std::ostream & operator<<(std::ostream &, Value const &root)
Output using the StyledStreamWriter.
Definition
json_writer.cpp:722
json::valueToString
std::string valueToString(Int value)
Definition
json_writer.cpp:49
std
STL namespace.
ostream
std::string::reserve
T reserve(T... args)
std::setfill
T setfill(T... args)
std::setw
T setw(T... args)
sstream
std::ostringstream::str
T str(T... args)
string
system_error
std::to_chars
T to_chars(T... args)
std::uppercase
T uppercase(T... args)
utility
Generated by
1.17.0