in encoding/tinycbor/src/cborpretty.c [266:443]
static CborError value_to_pretty(FILE *out, CborValue *it)
{
CborError err;
CborType type = cbor_value_get_type(it);
switch (type) {
case CborArrayType:
case CborMapType: {
/* recursive type */
CborValue recursed;
if (fprintf(out, type == CborArrayType ? "[" : "{") < 0)
return CborErrorIO;
if (!cbor_value_is_length_known(it)) {
if (fprintf(out, "_ ") < 0)
return CborErrorIO;
}
err = cbor_value_enter_container(it, &recursed);
if (err) {
it->offset = recursed.offset;
return err; /* parse error */
}
err = container_to_pretty(out, &recursed, type);
if (err) {
it->offset = recursed.offset;
return err; /* parse error */
}
err = cbor_value_leave_container(it, &recursed);
if (err)
return err; /* parse error */
if (fprintf(out, type == CborArrayType ? "]" : "}") < 0)
return CborErrorIO;
return CborNoError;
}
case CborIntegerType: {
uint64_t val;
cbor_value_get_raw_integer(it, &val); /* can't fail */
if (cbor_value_is_unsigned_integer(it)) {
if (fprintf(out, "%" PRIu64, val) < 0)
return CborErrorIO;
} else {
/* CBOR stores the negative number X as -1 - X
* (that is, -1 is stored as 0, -2 as 1 and so forth) */
if (++val) { /* unsigned overflow may happen */
if (fprintf(out, "-%" PRIu64, val) < 0)
return CborErrorIO;
} else {
/* overflown
* 0xffff`ffff`ffff`ffff + 1 =
* 0x1`0000`0000`0000`0000 = 18446744073709551616 (2^64) */
if (fprintf(out, "-18446744073709551616") < 0)
return CborErrorIO;
}
}
break;
}
case CborByteStringType:{
size_t n = 0;
uint8_t *buffer;
err = cbor_value_dup_byte_string(it, &buffer, &n, it);
if (err)
return err;
bool failed = fprintf(out, "h'") < 0 || hexDump(out, buffer, n) < 0 || fprintf(out, "'") < 0;
free(buffer);
return failed ? CborErrorIO : CborNoError;
}
case CborTextStringType: {
size_t n = 0;
char *buffer;
err = cbor_value_dup_text_string(it, &buffer, &n, it);
if (err)
return err;
err = CborNoError;
bool failed = fprintf(out, "\"") < 0
|| (err = utf8EscapedDump(out, buffer, n)) != CborNoError
|| fprintf(out, "\"") < 0;
free(buffer);
return err != CborNoError ? err :
failed ? CborErrorIO : CborNoError;
}
case CborTagType: {
CborTag tag;
cbor_value_get_tag(it, &tag); /* can't fail */
if (fprintf(out, "%" PRIu64 "(", tag) < 0)
return CborErrorIO;
err = cbor_value_advance_fixed(it);
if (err)
return err;
err = value_to_pretty(out, it);
if (err)
return err;
if (fprintf(out, ")") < 0)
return CborErrorIO;
return CborNoError;
}
case CborSimpleType: {
uint8_t simple_type;
cbor_value_get_simple_type(it, &simple_type); /* can't fail */
if (fprintf(out, "simple(%" PRIu8 ")", simple_type) < 0)
return CborErrorIO;
break;
}
case CborNullType:
if (fprintf(out, "null") < 0)
return CborErrorIO;
break;
case CborUndefinedType:
if (fprintf(out, "undefined") < 0)
return CborErrorIO;
break;
case CborBooleanType: {
bool val;
cbor_value_get_boolean(it, &val); /* can't fail */
if (fprintf(out, val ? "true" : "false") < 0)
return CborErrorIO;
break;
}
#if FLOAT_SUPPORT
case CborDoubleType: {
const char *suffix;
double val;
if (false) {
float f;
case CborFloatType:
cbor_value_get_float(it, &f);
val = f;
suffix = "f";
} else if (false) {
uint16_t f16;
case CborHalfFloatType:
cbor_value_get_half_float(it, &f16);
val = decode_half(f16);
suffix = "f16";
} else {
cbor_value_get_double(it, &val);
suffix = "";
}
int r = fpclassify(val);
if (r == FP_NAN || r == FP_INFINITE)
suffix = "";
uint64_t ival = (uint64_t)fabs(val);
if (ival == fabs(val)) {
/* this double value fits in a 64-bit integer, so show it as such
* (followed by a floating point suffix, to disambiguate) */
r = fprintf(out, "%s%" PRIu64 ".%s", val < 0 ? "-" : "", ival, suffix);
} else {
/* this number is definitely not a 64-bit integer */
r = fprintf(out, "%." DBL_DECIMAL_DIG_STR "g%s", val, suffix);
}
if (r < 0)
return CborErrorIO;
break;
}
#endif
case CborInvalidType:
default:
if (fprintf(out, "invalid") < 0)
return CborErrorIO;
return CborErrorUnknownType;
}
err = cbor_value_advance_fixed(it);
return err;
}