static CborError value_to_pretty()

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;
}