• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

arangodb / velocypack / 3998645281

pending completion
3998645281

Pull #148

github

GitHub
Merge b1e3c924b into 5a28b6413
Pull Request #148: use separate namespace for xxh functions

0 of 5107 relevant lines covered (0.0%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Dumper.cpp
1
////////////////////////////////////////////////////////////////////////////////
2
/// DISCLAIMER
3
///
4
/// Copyright 2014-2020 ArangoDB GmbH, Cologne, Germany
5
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
6
///
7
/// Licensed under the Apache License, Version 2.0 (the "License");
8
/// you may not use this file except in compliance with the License.
9
/// You may obtain a copy of the License at
10
///
11
///     http://www.apache.org/licenses/LICENSE-2.0
12
///
13
/// Unless required by applicable law or agreed to in writing, software
14
/// distributed under the License is distributed on an "AS IS" BASIS,
15
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
/// See the License for the specific language governing permissions and
17
/// limitations under the License.
18
///
19
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
20
///
21
/// @author Max Neunhoeffer
22
/// @author Jan Steemann
23
////////////////////////////////////////////////////////////////////////////////
24

25
#include <cmath>
26

27
#include "velocypack/velocypack-common.h"
28
#include "velocypack/Dumper.h"
29
#include "velocypack/Exception.h"
30
#include "velocypack/Iterator.h"
31
#include "velocypack/Sink.h"
32
#include "velocypack/ValueType.h"
33

34
using namespace arangodb::velocypack;
35

36
// forward for fpconv function declared elsewhere
37
namespace arangodb::velocypack {
38
int fpconv_dtoa(double fp, char dest[24]);
39
}  // namespace arangodb::velocypack
40

41
Dumper::Dumper(Sink* sink, Options const* options)
×
42
    : options(options), _sink(sink), _indentation(0) {
×
43
  if (VELOCYPACK_UNLIKELY(sink == nullptr)) {
×
44
    throw Exception(Exception::InternalError, "Sink cannot be a nullptr");
×
45
  }
46
  if (VELOCYPACK_UNLIKELY(options == nullptr)) {
×
47
    throw Exception(Exception::InternalError, "Options cannot be a nullptr");
×
48
  }
49
}
×
50

51
void Dumper::dump(Slice slice) {
×
52
  _indentation = 0;
×
53
  _sink->reserve(slice.byteSize());
×
54
  dumpValue(slice);
×
55
}
×
56

57
/*static*/ void Dumper::dump(Slice slice, Sink* sink,
×
58
                             Options const* options) {
59
  Dumper dumper(sink, options);
×
60
  dumper.dump(slice);
×
61
}
×
62

63
/*static*/ void Dumper::dump(Slice const* slice, Sink* sink,
×
64
                             Options const* options) {
65
  dump(*slice, sink, options);
×
66
}
×
67

68
/*static*/ std::string Dumper::toString(Slice slice,
×
69
                                        Options const* options) {
70
  std::string buffer;
×
71
  StringSink sink(&buffer);
×
72
  dump(slice, &sink, options);
×
73
  return buffer;
×
74
}
75

76
/*static*/ std::string Dumper::toString(Slice const* slice,
×
77
                                        Options const* options) {
78
  return toString(*slice, options);
×
79
}
80

81
void Dumper::appendString(char const* src, ValueLength len) {
×
82
  _sink->reserve(2 + len);
×
83
  _sink->push_back('"');
×
84
  dumpString(src, len);
×
85
  _sink->push_back('"');
×
86
}
×
87

88
void Dumper::appendInt(int64_t v) {
×
89
  if (v == INT64_MIN) {
×
90
    _sink->append("-9223372036854775808", 20);
×
91
    return;
×
92
  }
93
  if (v < 0) {
×
94
    _sink->push_back('-');
×
95
    v = -v;
×
96
  }
97

98
  if (1000000000000000000LL <= v) {
×
99
    _sink->push_back('0' + (v / 1000000000000000000LL) % 10);
×
100
  }
101
  if (100000000000000000LL <= v) {
×
102
    _sink->push_back('0' + (v / 100000000000000000LL) % 10);
×
103
  }
104
  if (10000000000000000LL <= v) {
×
105
    _sink->push_back('0' + (v / 10000000000000000LL) % 10);
×
106
  }
107
  if (1000000000000000LL <= v) {
×
108
    _sink->push_back('0' + (v / 1000000000000000LL) % 10);
×
109
  }
110
  if (100000000000000LL <= v) {
×
111
    _sink->push_back('0' + (v / 100000000000000LL) % 10);
×
112
  }
113
  if (10000000000000LL <= v) {
×
114
    _sink->push_back('0' + (v / 10000000000000LL) % 10);
×
115
  }
116
  if (1000000000000LL <= v) {
×
117
    _sink->push_back('0' + (v / 1000000000000LL) % 10);
×
118
  }
119
  if (100000000000LL <= v) {
×
120
    _sink->push_back('0' + (v / 100000000000LL) % 10);
×
121
  }
122
  if (10000000000LL <= v) {
×
123
    _sink->push_back('0' + (v / 10000000000LL) % 10);
×
124
  }
125
  if (1000000000LL <= v) {
×
126
    _sink->push_back('0' + (v / 1000000000LL) % 10);
×
127
  }
128
  if (100000000LL <= v) {
×
129
    _sink->push_back('0' + (v / 100000000LL) % 10);
×
130
  }
131
  if (10000000LL <= v) {
×
132
    _sink->push_back('0' + (v / 10000000LL) % 10);
×
133
  }
134
  if (1000000LL <= v) {
×
135
    _sink->push_back('0' + (v / 1000000LL) % 10);
×
136
  }
137
  if (100000LL <= v) {
×
138
    _sink->push_back('0' + (v / 100000LL) % 10);
×
139
  }
140
  if (10000LL <= v) {
×
141
    _sink->push_back('0' + (v / 10000LL) % 10);
×
142
  }
143
  if (1000LL <= v) {
×
144
    _sink->push_back('0' + (v / 1000LL) % 10);
×
145
  }
146
  if (100LL <= v) {
×
147
    _sink->push_back('0' + (v / 100LL) % 10);
×
148
  }
149
  if (10LL <= v) {
×
150
    _sink->push_back('0' + (v / 10LL) % 10);
×
151
  }
152

153
  _sink->push_back('0' + (v % 10));
×
154
}
155

156
void Dumper::appendUInt(uint64_t v) {
×
157
  if (10000000000000000000ULL <= v) {
×
158
    _sink->push_back('0' + (v / 10000000000000000000ULL) % 10);
×
159
  }
160
  if (1000000000000000000ULL <= v) {
×
161
    _sink->push_back('0' + (v / 1000000000000000000ULL) % 10);
×
162
  }
163
  if (100000000000000000ULL <= v) {
×
164
    _sink->push_back('0' + (v / 100000000000000000ULL) % 10);
×
165
  }
166
  if (10000000000000000ULL <= v) {
×
167
    _sink->push_back('0' + (v / 10000000000000000ULL) % 10);
×
168
  }
169
  if (1000000000000000ULL <= v) {
×
170
    _sink->push_back('0' + (v / 1000000000000000ULL) % 10);
×
171
  }
172
  if (100000000000000ULL <= v) {
×
173
    _sink->push_back('0' + (v / 100000000000000ULL) % 10);
×
174
  }
175
  if (10000000000000ULL <= v) {
×
176
    _sink->push_back('0' + (v / 10000000000000ULL) % 10);
×
177
  }
178
  if (1000000000000ULL <= v) {
×
179
    _sink->push_back('0' + (v / 1000000000000ULL) % 10);
×
180
  }
181
  if (100000000000ULL <= v) {
×
182
    _sink->push_back('0' + (v / 100000000000ULL) % 10);
×
183
  }
184
  if (10000000000ULL <= v) {
×
185
    _sink->push_back('0' + (v / 10000000000ULL) % 10);
×
186
  }
187
  if (1000000000ULL <= v) {
×
188
    _sink->push_back('0' + (v / 1000000000ULL) % 10);
×
189
  }
190
  if (100000000ULL <= v) {
×
191
    _sink->push_back('0' + (v / 100000000ULL) % 10);
×
192
  }
193
  if (10000000ULL <= v) {
×
194
    _sink->push_back('0' + (v / 10000000ULL) % 10);
×
195
  }
196
  if (1000000ULL <= v) {
×
197
    _sink->push_back('0' + (v / 1000000ULL) % 10);
×
198
  }
199
  if (100000ULL <= v) {
×
200
    _sink->push_back('0' + (v / 100000ULL) % 10);
×
201
  }
202
  if (10000ULL <= v) {
×
203
    _sink->push_back('0' + (v / 10000ULL) % 10);
×
204
  }
205
  if (1000ULL <= v) {
×
206
    _sink->push_back('0' + (v / 1000ULL) % 10);
×
207
  }
208
  if (100ULL <= v) {
×
209
    _sink->push_back('0' + (v / 100ULL) % 10);
×
210
  }
211
  if (10ULL <= v) {
×
212
    _sink->push_back('0' + (v / 10ULL) % 10);
×
213
  }
214

215
  _sink->push_back('0' + (v % 10));
×
216
}
×
217

218
void Dumper::appendDouble(double v) {
×
219
  char temp[24];
220
  int len = fpconv_dtoa(v, &temp[0]);
×
221
  _sink->append(&temp[0], static_cast<ValueLength>(len));
×
222
}
×
223

224
void Dumper::dumpUnicodeCharacter(uint16_t value) {
×
225
  _sink->append("\\u", 2);
×
226

227
  uint16_t p;
228
  p = (value & 0xf000U) >> 12;
×
229
  _sink->push_back((p < 10) ? ('0' + p) : ('A' + p - 10));
×
230

231
  p = (value & 0x0f00U) >> 8;
×
232
  _sink->push_back((p < 10) ? ('0' + p) : ('A' + p - 10));
×
233

234
  p = (value & 0x00f0U) >> 4;
×
235
  _sink->push_back((p < 10) ? ('0' + p) : ('A' + p - 10));
×
236

237
  p = (value & 0x000fU);
×
238
  _sink->push_back((p < 10) ? ('0' + p) : ('A' + p - 10));
×
239
}
×
240

241
void Dumper::dumpInteger(Slice slice) {
×
242
  VELOCYPACK_ASSERT(slice.isInteger());
×
243

244
  if (slice.isType(ValueType::UInt)) {
×
245
    uint64_t v = slice.getUIntUnchecked();
×
246

247
    appendUInt(v);
×
248
  } else if (slice.isType(ValueType::Int)) {
×
249
    int64_t v = slice.getIntUnchecked();
×
250

251
    appendInt(v);
×
252
  } else if (slice.isType(ValueType::SmallInt)) {
×
253
    int64_t v = slice.getSmallIntUnchecked();
×
254
    if (v < 0) {
×
255
      _sink->push_back('-');
×
256
      v = -v;
×
257
    }
258
    _sink->push_back('0' + static_cast<char>(v));
×
259
  }
260
}
×
261

262
void Dumper::dumpString(char const* src, ValueLength len) {
×
263
  static char const EscapeTable[256] = {
264
      // 0    1    2    3    4    5    6    7    8    9    A    B    C    D    E
265
      // F
266
      'u',  'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r',
267
      'u',
268
      'u',  // 00
269
      'u',  'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
270
      'u',
271
      'u',  // 10
272
      0,    0,   '"', 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
273
      0,
274
      '/',  // 20
275
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
276
      0,
277
      0,  // 30~4F
278
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
279
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
280
      '\\', 0,   0,   0,  // 50
281
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
282
      0,
283
      0,  // 60~FF
284
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
285
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
286
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
287
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
288
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
289
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
290
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
291
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
292
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
293
      0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
294
      0,    0,   0,   0};
295

296
  _sink->reserve(len);
×
297

298
  uint8_t const* p = reinterpret_cast<uint8_t const*>(src);
×
299
  uint8_t const* e = p + len;
×
300
  while (p < e) {
×
301
    uint8_t c = *p;
×
302

303
    if ((c & 0x80U) == 0) {
×
304
      // check for control characters
305
      char esc = EscapeTable[c];
×
306

307
      if (esc) {
×
308
        if (options->escapeControl) {
×
309
          if (c != '/' || options->escapeForwardSlashes) {
×
310
            // escape forward slashes only when requested
311
            _sink->push_back('\\');
×
312
          }
313
          _sink->push_back(static_cast<char>(esc));
×
314
          if (esc == 'u') {
×
315
            uint16_t i1 = (((uint16_t)c) & 0xf0U) >> 4;
×
316
            uint16_t i2 = (((uint16_t)c) & 0x0fU);
×
317

318
            _sink->append("00", 2);
×
319
            _sink->push_back(
×
320
                static_cast<char>((i1 < 10) ? ('0' + i1) : ('A' + i1 - 10)));
×
321
            _sink->push_back(
×
322
                static_cast<char>((i2 < 10) ? ('0' + i2) : ('A' + i2 - 10)));
×
323
          }
324
        } else {
325
          if (esc == '"' || esc == '/' || esc == '\\') {
×
326
            _sink->push_back('\\');
×
327
            _sink->push_back(static_cast<char>(esc));
×
328
          } else {
329
            _sink->push_back(' ');
×
330
          }
331
        }
332
      } else {
333
        _sink->push_back(static_cast<char>(c));
×
334
      }
335
    } else if ((c & 0xe0U) == 0xc0U) {
×
336
      // two-byte sequence
337
      if (p + 1 >= e) {
×
338
        throw Exception(Exception::InvalidUtf8Sequence);
×
339
      }
340

341
      if (options->escapeUnicode) {
×
342
        uint16_t value =
×
343
            ((((uint16_t)*p & 0x1fU) << 6) | ((uint16_t) * (p + 1) & 0x3fU));
×
344
        dumpUnicodeCharacter(value);
×
345
      } else {
346
        _sink->append(reinterpret_cast<char const*>(p), 2);
×
347
      }
348
      ++p;
×
349
    } else if ((c & 0xf0U) == 0xe0U) {
×
350
      // three-byte sequence
351
      if (p + 2 >= e) {
×
352
        throw Exception(Exception::InvalidUtf8Sequence);
×
353
      }
354

355
      if (options->escapeUnicode) {
×
356
        uint16_t value = ((((uint16_t)*p & 0x0fU) << 12) |
×
357
                          (((uint16_t) * (p + 1) & 0x3fU) << 6) |
×
358
                          ((uint16_t) * (p + 2) & 0x3fU));
×
359
        dumpUnicodeCharacter(value);
×
360
      } else {
361
        _sink->append(reinterpret_cast<char const*>(p), 3);
×
362
      }
363
      p += 2;
×
364
    } else if ((c & 0xf8U) == 0xf0U) {
×
365
      // four-byte sequence
366
      if (p + 3 >= e) {
×
367
        throw Exception(Exception::InvalidUtf8Sequence);
×
368
      }
369

370
      if (options->escapeUnicode) {
×
371
        uint32_t value = ((((uint32_t)*p & 0x0fU) << 18) |
×
372
                          (((uint32_t) * (p + 1) & 0x3fU) << 12) |
×
373
                          (((uint32_t) * (p + 2) & 0x3fU) << 6) |
×
374
                          ((uint32_t) * (p + 3) & 0x3fU));
×
375
        // construct the surrogate pairs
376
        value -= 0x10000U;
×
377
        uint16_t high = (uint16_t)(((value & 0xffc00U) >> 10) + 0xd800);
×
378
        dumpUnicodeCharacter(high);
×
379
        uint16_t low = (value & 0x3ffU) + 0xdc00U;
×
380
        dumpUnicodeCharacter(low);
×
381
      } else {
382
        _sink->append(reinterpret_cast<char const*>(p), 4);
×
383
      }
384
      p += 3;
×
385
    }
386

387
    ++p;
×
388
  }
389
}
×
390

391
void Dumper::dumpValue(Slice slice, Slice const* base) {
×
392
  if (options->debugTags && slice.isTagged()) {
×
393
    appendUInt(slice.getFirstTag());
×
394
    _sink->push_back(':');
×
395
  }
396

397
  switch (slice.type()) {
×
398
    case ValueType::Null: {
×
399
      _sink->append("null", 4);
×
400
      break;
×
401
    }
402

403
    case ValueType::Bool: {
×
404
      if (slice.getBool()) {
×
405
        _sink->append("true", 4);
×
406
      } else {
407
        _sink->append("false", 5);
×
408
      }
409
      break;
×
410
    }
411

412
    case ValueType::Array: {
×
413
      ArrayIterator it(slice);
×
414
      _sink->push_back('[');
×
415
      if (options->prettyPrint) {
×
416
        _sink->push_back('\n');
×
417
        ++_indentation;
×
418
        while (it.valid()) {
×
419
          indent();
×
420
          dumpValue(it.value(), &slice);
×
421
          if (it.index() + 1 != it.size()) {
×
422
            _sink->push_back(',');
×
423
          }
424
          _sink->push_back('\n');
×
425
          it.next();
×
426
        }
427
        --_indentation;
×
428
        indent();
×
429
      } else if (options->singleLinePrettyPrint) {
×
430
        while (it.valid()) {
×
431
          if (it.index() != 0) {
×
432
            _sink->push_back(',');
×
433
            _sink->push_back(' ');
×
434
          }
435
          dumpValue(it.value(), &slice);
×
436
          it.next();
×
437
        }
438
      } else {
439
        while (it.valid()) {
×
440
          if (it.index() != 0) {
×
441
            _sink->push_back(',');
×
442
          }
443
          dumpValue(it.value(), &slice);
×
444
          it.next();
×
445
        }
446
      }
447
      _sink->push_back(']');
×
448
      break;
×
449
    }
450

451
    case ValueType::Object: {
×
452
      ObjectIterator it(slice, !options->dumpAttributesInIndexOrder);
×
453
      _sink->push_back('{');
×
454
      if (options->prettyPrint) {
×
455
        _sink->push_back('\n');
×
456
        ++_indentation;
×
457
        while (it.valid()) {
×
458
          auto current = (*it);
×
459
          indent();
×
460
          dumpValue(current.key, &slice);
×
461
          _sink->append(" : ", 3);
×
462
          dumpValue(current.value, &slice);
×
463
          if (it.index() + 1 != it.size()) {
×
464
            _sink->push_back(',');
×
465
          }
466
          _sink->push_back('\n');
×
467
          it.next();
×
468
        }
469
        --_indentation;
×
470
        indent();
×
471
      } else if (options->singleLinePrettyPrint) {
×
472
        while (it.valid()) {
×
473
          if (it.index() != 0) {
×
474
            _sink->push_back(',');
×
475
            _sink->push_back(' ');
×
476
          }
477
          auto current = (*it);
×
478
          dumpValue(current.key, &slice);
×
479
          _sink->push_back(':');
×
480
          _sink->push_back(' ');
×
481
          dumpValue(current.value, &slice);
×
482
          it.next();
×
483
        }
484
      } else {
485
        while (it.valid()) {
×
486
          if (it.index() != 0) {
×
487
            _sink->push_back(',');
×
488
          }
489
          auto current = (*it);
×
490
          dumpValue(current.key, &slice);
×
491
          _sink->push_back(':');
×
492
          dumpValue(current.value, &slice);
×
493
          it.next();
×
494
        }
495
      }
496
      _sink->push_back('}');
×
497
      break;
×
498
    }
499

500
    case ValueType::Double: {
×
501
      double const v = slice.getDouble();
×
502

503
      if (!std::isnan(v) && !std::isinf(v)) {
×
504
        appendDouble(v);
×
505
        break;
×
506
      }
507

508
      if (options->unsupportedDoublesAsString) {
×
509
        if (std::isnan(v)) {
×
510
          _sink->append("\"NaN\"", 5);
×
511
          break;
×
512
        } else if (std::isinf(v)) {
×
513
          _sink->push_back('"');
×
514
          if (v == -INFINITY) {
×
515
            _sink->push_back('-');
×
516
          }
517
          _sink->append("Infinity\"", 9);
×
518
          break;
×
519
        }
520
      }
521

522
      handleUnsupportedType(slice);
×
523
      break;
×
524
    }
525

526
    case ValueType::Int:
×
527
    case ValueType::UInt:
528
    case ValueType::SmallInt: {
529
      dumpInteger(slice);
×
530
      break;
×
531
    }
532

533
    case ValueType::String: {
×
534
      ValueLength len;
535
      char const* p = slice.getString(len);
×
536
      _sink->reserve(2 + len);
×
537
      _sink->push_back('"');
×
538
      dumpString(p, len);
×
539
      _sink->push_back('"');
×
540
      break;
×
541
    }
542

543
    case ValueType::External: {
×
544
      if (base == nullptr) {
×
545
        base = &slice;
×
546
      }
547

548
      Slice external(
549
          reinterpret_cast<uint8_t const*>(slice.getExternal()));
×
550
      dumpValue(external, base);
×
551
      break;
×
552
    }
553

554
    case ValueType::Tagged: {
×
555
      dump(slice.value());
×
556
      break;
×
557
    }
558

559
    case ValueType::Binary: {
×
560
      if (options->binaryAsHex) {
×
561
        _sink->push_back('"');
×
562
        ValueLength len;
563
        uint8_t const* bin = slice.getBinary(len);
×
564
        for (ValueLength i = 0; i < len; ++i) {
×
565
          uint8_t value = bin[i];
×
566
          uint8_t x = value / 16;
×
567
          _sink->push_back((x < 10 ? ('0' + x) : ('a' + x - 10)));
×
568
          x = value % 16;
×
569
          _sink->push_back((x < 10 ? ('0' + x) : ('a' + x - 10)));
×
570
        }
571
        _sink->push_back('"');
×
572
      } else {
573
        handleUnsupportedType(slice);
×
574
      }
575
      break;
×
576
    }
577

578
    case ValueType::UTCDate: {
×
579
      if (options->datesAsIntegers) {
×
580
        appendInt(slice.getUTCDate());
×
581
      } else {
582
        handleUnsupportedType(slice);
×
583
      }
584
      break;
×
585
    }
586

587
    case ValueType::None:
×
588
    case ValueType::Illegal:
589
    case ValueType::MinKey:
590
    case ValueType::MaxKey: {
591
      handleUnsupportedType(slice);
×
592
      break;
×
593
    }
594

595
    case ValueType::BCD: {
×
596
      // TODO
597
      throw Exception(Exception::NotImplemented);
×
598
    }
599

600
    case ValueType::Custom: {
×
601
      if (options->customTypeHandler == nullptr) {
×
602
        throw Exception(Exception::NeedCustomTypeHandler);
×
603
      }
604
      if (base == nullptr) {
×
605
        base = &slice;
×
606
      }
607
      options->customTypeHandler->dump(slice, this, *base);
×
608
      break;
×
609
    }
610
  }
611
}
×
612

613
void Dumper::indent() {
×
614
  std::size_t n = _indentation;
×
615
  _sink->reserve(2 * n);
×
616
  for (std::size_t i = 0; i < n; ++i) {
×
617
    _sink->append("  ", 2);
×
618
  }
619
}
×
620

621
void Dumper::handleUnsupportedType(Slice slice) {
×
622
  if (options->unsupportedTypeBehavior == Options::NullifyUnsupportedType) {
×
623
    _sink->append("null", 4);
×
624
    return;
×
625
  } else if (options->unsupportedTypeBehavior ==
×
626
             Options::ConvertUnsupportedType) {
627
    _sink->append(std::string("\"(non-representable type ") +
×
628
                  slice.typeName() + ")\"");
×
629
    return;
×
630
  }
631

632
  throw Exception(Exception::NoJsonEquivalent);
×
633
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc