diff --git a/README.md b/README.md index 713ad357..895d82f6 100644 --- a/README.md +++ b/README.md @@ -527,8 +527,8 @@ options: -b {32,64}, --default-bit-size {32,64} Default bit size of integers in code. When integers have no explicit bounds, assume they have this bit - width. Should follow the bit width of the architecture - the code will be running on. + width. Recommended to follow the bit width of the + architecture the code will be running on. --include-prefix INCLUDE_PREFIX When #include'ing generated files, add this path prefix to the filename. diff --git a/include/zcbor_decode.h b/include/zcbor_decode.h index 90319d21..1d21b456 100644 --- a/include/zcbor_decode.h +++ b/include/zcbor_decode.h @@ -63,8 +63,12 @@ do { \ * fit in the result variable. * Use zcbor_peek_error() to see the error code. */ +bool zcbor_int8_decode(zcbor_state_t *state, int8_t *result); +bool zcbor_int16_decode(zcbor_state_t *state, int16_t *result); bool zcbor_int32_decode(zcbor_state_t *state, int32_t *result); /* pint/nint */ bool zcbor_int64_decode(zcbor_state_t *state, int64_t *result); /* pint/nint */ +bool zcbor_uint8_decode(zcbor_state_t *state, uint8_t *result); +bool zcbor_uint16_decode(zcbor_state_t *state, uint16_t *result); bool zcbor_uint32_decode(zcbor_state_t *state, uint32_t *result); /* pint */ bool zcbor_uint64_decode(zcbor_state_t *state, uint64_t *result); /* pint */ bool zcbor_size_decode(zcbor_state_t *state, size_t *result); /* pint */ @@ -92,8 +96,12 @@ bool zcbor_float_decode(zcbor_state_t *state, double *result); /* IEEE754 float1 * expected value. * Use zcbor_peek_error() to see the error code. */ +bool zcbor_int8_expect(zcbor_state_t *state, int8_t expected); /* pint/nint */ +bool zcbor_int16_expect(zcbor_state_t *state, int16_t expected); /* pint/nint */ bool zcbor_int32_expect(zcbor_state_t *state, int32_t expected); /* pint/nint */ bool zcbor_int64_expect(zcbor_state_t *state, int64_t expected); /* pint/nint */ +bool zcbor_uint8_expect(zcbor_state_t *state, uint8_t expected); /* pint */ +bool zcbor_uint16_expect(zcbor_state_t *state, uint16_t expected); /* pint */ bool zcbor_uint32_expect(zcbor_state_t *state, uint32_t expected); /* pint */ bool zcbor_uint64_expect(zcbor_state_t *state, uint64_t expected); /* pint */ bool zcbor_size_expect(zcbor_state_t *state, size_t expected); /* pint */ @@ -113,8 +121,12 @@ bool zcbor_float_expect(zcbor_state_t *state, double expected); /* IEEE754 float /** Like the _expect() functions but the value is passed through a pointer. * (for use as a zcbor_decoder_t function) */ +bool zcbor_int8_pexpect(zcbor_state_t *state, int8_t *expected); /* pint/nint */ +bool zcbor_int16_pexpect(zcbor_state_t *state, int16_t *expected); /* pint/nint */ bool zcbor_int32_pexpect(zcbor_state_t *state, int32_t *expected); /* pint/nint */ bool zcbor_int64_pexpect(zcbor_state_t *state, int64_t *expected); /* pint/nint */ +bool zcbor_uint8_pexpect(zcbor_state_t *state, uint8_t *expected); /* pint */ +bool zcbor_uint16_pexpect(zcbor_state_t *state, uint16_t *expected); /* pint */ bool zcbor_uint32_pexpect(zcbor_state_t *state, uint32_t *expected); /* pint */ bool zcbor_uint64_pexpect(zcbor_state_t *state, uint64_t *expected); /* pint */ bool zcbor_size_pexpect(zcbor_state_t *state, size_t *expected); /* pint */ @@ -132,8 +144,12 @@ bool zcbor_float_pexpect(zcbor_state_t *state, double *expected); /* IEEE754 flo * * Calls @ref zcbor_union_elem_code then @ref zcbor_[u]int[32|64]_expect. */ +bool zcbor_int8_expect_union(zcbor_state_t *state, int8_t expected); +bool zcbor_int16_expect_union(zcbor_state_t *state, int16_t expected); bool zcbor_int32_expect_union(zcbor_state_t *state, int32_t expected); bool zcbor_int64_expect_union(zcbor_state_t *state, int64_t expected); +bool zcbor_uint8_expect_union(zcbor_state_t *state, uint8_t expected); +bool zcbor_uint16_expect_union(zcbor_state_t *state, uint16_t expected); bool zcbor_uint32_expect_union(zcbor_state_t *state, uint32_t expected); bool zcbor_uint64_expect_union(zcbor_state_t *state, uint64_t expected); diff --git a/include/zcbor_encode.h b/include/zcbor_encode.h index 9bd9383c..9387c4a9 100644 --- a/include/zcbor_encode.h +++ b/include/zcbor_encode.h @@ -59,8 +59,12 @@ do { \ * @retval false If the payload is exhausted. Or an unexpected error happened. * Use zcbor_peek_error() to see the error code. */ +bool zcbor_int8_put(zcbor_state_t *state, int8_t input); +bool zcbor_int16_put(zcbor_state_t *state, int16_t input); bool zcbor_int32_put(zcbor_state_t *state, int32_t input); /* pint/nint */ bool zcbor_int64_put(zcbor_state_t *state, int64_t input); /* pint/nint */ +bool zcbor_uint8_put(zcbor_state_t *state, uint8_t input); +bool zcbor_uint16_put(zcbor_state_t *state, uint16_t input); bool zcbor_uint32_put(zcbor_state_t *state, uint32_t input); /* pint */ bool zcbor_uint64_put(zcbor_state_t *state, uint64_t input); /* pint */ bool zcbor_size_put(zcbor_state_t *state, size_t input); /* pint */ @@ -73,8 +77,12 @@ bool zcbor_float16_bytes_put(zcbor_state_t *state, uint16_t input); /* IEEE754 f bool zcbor_float32_put(zcbor_state_t *state, float input); /* IEEE754 float32 */ bool zcbor_float64_put(zcbor_state_t *state, double input); /* IEEE754 float64 */ +bool zcbor_int8_encode(zcbor_state_t *state, const int8_t *input); +bool zcbor_int16_encode(zcbor_state_t *state, const int16_t *input); bool zcbor_int32_encode(zcbor_state_t *state, const int32_t *input); /* pint/nint */ bool zcbor_int64_encode(zcbor_state_t *state, const int64_t *input); /* pint/nint */ +bool zcbor_uint8_encode(zcbor_state_t *state, const uint8_t *input); +bool zcbor_uint16_encode(zcbor_state_t *state, const uint16_t *input); bool zcbor_uint32_encode(zcbor_state_t *state, const uint32_t *input); /* pint */ bool zcbor_uint64_encode(zcbor_state_t *state, const uint64_t *input); /* pint */ bool zcbor_size_encode(zcbor_state_t *state, const size_t *input); /* pint */ diff --git a/samples/pet/src/pet_encode.c b/samples/pet/src/pet_encode.c index 4f390c29..cd718d97 100644 --- a/samples/pet/src/pet_encode.c +++ b/samples/pet/src/pet_encode.c @@ -40,9 +40,9 @@ static bool encode_Pet( bool res = (((zcbor_list_start_encode(state, 3) && ((((zcbor_list_start_encode(state, 3) && ((zcbor_multi_encode_minmax(1, 3, &(*input).names_count, (zcbor_encoder_t *)zcbor_tstr_encode, state, (*&(*input).names), sizeof(struct zcbor_string))) || (zcbor_list_map_end_force_encode(state), false)) && zcbor_list_end_encode(state, 3))) && (((((((*input).birthday.len == 8)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false))) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)) && (zcbor_bstr_encode(state, (&(*input).birthday)))) - && ((((*input).species_choice == Pet_species_cat_c) ? ((zcbor_uint32_put(state, (1)))) - : (((*input).species_choice == Pet_species_dog_c) ? ((zcbor_uint32_put(state, (2)))) - : (((*input).species_choice == Pet_species_other_c) ? ((zcbor_uint32_put(state, (3)))) + && ((((*input).species_choice == Pet_species_cat_c) ? ((zcbor_uint8_put(state, (1)))) + : (((*input).species_choice == Pet_species_dog_c) ? ((zcbor_uint8_put(state, (2)))) + : (((*input).species_choice == Pet_species_other_c) ? ((zcbor_uint8_put(state, (3)))) : false))))) || (zcbor_list_map_end_force_encode(state), false)) && zcbor_list_end_encode(state, 3)))); log_result(state, res, __func__); diff --git a/src/zcbor_decode.c b/src/zcbor_decode.c index 1ced3e0b..d369b08c 100644 --- a/src/zcbor_decode.c +++ b/src/zcbor_decode.c @@ -239,6 +239,20 @@ bool zcbor_int_decode(zcbor_state_t *state, void *result, size_t result_size) } +bool zcbor_int8_decode(zcbor_state_t *state, int8_t *result) +{ + PRINT_FUNC(); + return zcbor_int_decode(state, result, sizeof(*result)); +} + + +bool zcbor_int16_decode(zcbor_state_t *state, int16_t *result) +{ + PRINT_FUNC(); + return zcbor_int_decode(state, result, sizeof(*result)); +} + + bool zcbor_int32_decode(zcbor_state_t *state, int32_t *result) { PRINT_FUNC(); @@ -266,6 +280,20 @@ bool zcbor_uint_decode(zcbor_state_t *state, void *result, size_t result_size) } +bool zcbor_uint8_decode(zcbor_state_t *state, uint8_t *result) +{ + PRINT_FUNC(); + return zcbor_uint_decode(state, result, sizeof(*result)); +} + + +bool zcbor_uint16_decode(zcbor_state_t *state, uint16_t *result) +{ + PRINT_FUNC(); + return zcbor_uint_decode(state, result, sizeof(*result)); +} + + bool zcbor_uint32_decode(zcbor_state_t *state, uint32_t *result) { PRINT_FUNC(); @@ -273,6 +301,33 @@ bool zcbor_uint32_decode(zcbor_state_t *state, uint32_t *result) } +bool zcbor_uint64_decode(zcbor_state_t *state, uint64_t *result) +{ + PRINT_FUNC(); + return zcbor_uint_decode(state, result, sizeof(*result)); +} + + +bool zcbor_int8_expect_union(zcbor_state_t *state, int8_t result) +{ + PRINT_FUNC(); + if (!zcbor_union_elem_code(state)) { + ZCBOR_FAIL(); + } + return zcbor_int8_expect(state, result); +} + + +bool zcbor_int16_expect_union(zcbor_state_t *state, int16_t result) +{ + PRINT_FUNC(); + if (!zcbor_union_elem_code(state)) { + ZCBOR_FAIL(); + } + return zcbor_int16_expect(state, result); +} + + bool zcbor_int32_expect_union(zcbor_state_t *state, int32_t result) { PRINT_FUNC(); @@ -293,6 +348,26 @@ bool zcbor_int64_expect_union(zcbor_state_t *state, int64_t result) } +bool zcbor_uint8_expect_union(zcbor_state_t *state, uint8_t result) +{ + PRINT_FUNC(); + if (!zcbor_union_elem_code(state)) { + ZCBOR_FAIL(); + } + return zcbor_uint8_expect(state, result); +} + + +bool zcbor_uint16_expect_union(zcbor_state_t *state, uint16_t result) +{ + PRINT_FUNC(); + if (!zcbor_union_elem_code(state)) { + ZCBOR_FAIL(); + } + return zcbor_uint16_expect(state, result); +} + + bool zcbor_uint32_expect_union(zcbor_state_t *state, uint32_t result) { PRINT_FUNC(); @@ -313,6 +388,20 @@ bool zcbor_uint64_expect_union(zcbor_state_t *state, uint64_t result) } +bool zcbor_int8_expect(zcbor_state_t *state, int8_t expected) +{ + PRINT_FUNC(); + return zcbor_int64_expect(state, expected); +} + + +bool zcbor_int16_expect(zcbor_state_t *state, int16_t expected) +{ + PRINT_FUNC(); + return zcbor_int64_expect(state, expected); +} + + bool zcbor_int32_expect(zcbor_state_t *state, int32_t expected) { PRINT_FUNC(); @@ -351,20 +440,38 @@ bool zcbor_int64_pexpect(zcbor_state_t *state, int64_t *expected) } -bool zcbor_uint64_decode(zcbor_state_t *state, uint64_t *result) +#ifdef ZCBOR_SUPPORTS_SIZE_T +bool zcbor_size_decode(zcbor_state_t *state, size_t *result) { PRINT_FUNC(); return zcbor_uint_decode(state, result, sizeof(*result)); } +#endif -#ifdef ZCBOR_SUPPORTS_SIZE_T -bool zcbor_size_decode(zcbor_state_t *state, size_t *result) +bool zcbor_uint8_expect(zcbor_state_t *state, uint8_t expected) { PRINT_FUNC(); - return zcbor_uint_decode(state, result, sizeof(*result)); + return zcbor_uint64_expect(state, expected); +} + +bool zcbor_uint8_pexpect(zcbor_state_t *state, uint8_t *expected) +{ + PRINT_FUNC(); + return zcbor_uint64_expect(state, *expected); +} + +bool zcbor_uint16_expect(zcbor_state_t *state, uint16_t expected) +{ + PRINT_FUNC(); + return zcbor_uint64_expect(state, expected); +} + +bool zcbor_uint16_pexpect(zcbor_state_t *state, uint16_t *expected) +{ + PRINT_FUNC(); + return zcbor_uint64_expect(state, *expected); } -#endif bool zcbor_uint32_expect(zcbor_state_t *state, uint32_t expected) @@ -377,7 +484,7 @@ bool zcbor_uint32_expect(zcbor_state_t *state, uint32_t expected) bool zcbor_uint32_pexpect(zcbor_state_t *state, uint32_t *expected) { PRINT_FUNC(); - return zcbor_uint32_expect(state, *expected); + return zcbor_uint64_expect(state, *expected); } @@ -415,7 +522,7 @@ bool zcbor_size_expect(zcbor_state_t *state, size_t expected) bool zcbor_size_pexpect(zcbor_state_t *state, size_t *expected) { PRINT_FUNC(); - return zcbor_size_expect(state, *expected); + return zcbor_uint64_expect(state, *expected); } #endif diff --git a/src/zcbor_encode.c b/src/zcbor_encode.c index 1240fd9b..6887d2e1 100644 --- a/src/zcbor_encode.c +++ b/src/zcbor_encode.c @@ -146,55 +146,86 @@ bool zcbor_uint_encode(zcbor_state_t *state, const void *input_uint, size_t uint return true; } +bool zcbor_int8_encode(zcbor_state_t *state, const int8_t *input) +{ + return zcbor_int_encode(state, input, sizeof(*input)); +} -bool zcbor_int32_encode(zcbor_state_t *state, const int32_t *input) +bool zcbor_int16_encode(zcbor_state_t *state, const int16_t *input) { return zcbor_int_encode(state, input, sizeof(*input)); } +bool zcbor_int32_encode(zcbor_state_t *state, const int32_t *input) +{ + return zcbor_int_encode(state, input, sizeof(*input)); +} bool zcbor_int64_encode(zcbor_state_t *state, const int64_t *input) { return zcbor_int_encode(state, input, sizeof(*input)); } +bool zcbor_uint8_encode(zcbor_state_t *state, const uint8_t *input) +{ + return zcbor_uint_encode(state, input, sizeof(*input)); +} -bool zcbor_uint32_encode(zcbor_state_t *state, const uint32_t *input) +bool zcbor_uint16_encode(zcbor_state_t *state, const uint16_t *input) { return zcbor_uint_encode(state, input, sizeof(*input)); } +bool zcbor_uint32_encode(zcbor_state_t *state, const uint32_t *input) +{ + return zcbor_uint_encode(state, input, sizeof(*input)); +} bool zcbor_uint64_encode(zcbor_state_t *state, const uint64_t *input) { return zcbor_uint_encode(state, input, sizeof(*input)); } +bool zcbor_int8_put(zcbor_state_t *state, int8_t input) +{ + return zcbor_int_encode(state, &input, sizeof(input)); +} -bool zcbor_int32_put(zcbor_state_t *state, int32_t input) +bool zcbor_int16_put(zcbor_state_t *state, int16_t input) { return zcbor_int_encode(state, &input, sizeof(input)); } +bool zcbor_int32_put(zcbor_state_t *state, int32_t input) +{ + return zcbor_int_encode(state, &input, sizeof(input)); +} bool zcbor_int64_put(zcbor_state_t *state, int64_t input) { return zcbor_int_encode(state, &input, sizeof(input)); } +bool zcbor_uint8_put(zcbor_state_t *state, uint8_t input) +{ + return zcbor_uint_encode(state, &input, sizeof(input)); +} + +bool zcbor_uint16_put(zcbor_state_t *state, uint16_t input) +{ + return zcbor_uint_encode(state, &input, sizeof(input)); +} bool zcbor_uint32_put(zcbor_state_t *state, uint32_t input) { return zcbor_uint_encode(state, &input, sizeof(input)); } - bool zcbor_uint64_put(zcbor_state_t *state, uint64_t input) { return zcbor_uint_encode(state, &input, sizeof(input)); } - #ifdef ZCBOR_SUPPORTS_SIZE_T bool zcbor_size_put(zcbor_state_t *state, size_t input) { diff --git a/tests/cmake/test_template.cmake b/tests/cmake/test_template.cmake index 9fe349c3..58b95583 100644 --- a/tests/cmake/test_template.cmake +++ b/tests/cmake/test_template.cmake @@ -28,5 +28,5 @@ endif() zephyr_compile_options(-Werror) if (CONFIG_64BIT) - set(bit_arg -b 64) + set(bit_arg --default-bit-size 64) endif() diff --git a/tests/decode/test5_corner_cases/src/main.c b/tests/decode/test5_corner_cases/src/main.c index bb930cc8..4dea523b 100644 --- a/tests/decode/test5_corner_cases/src/main.c +++ b/tests/decode/test5_corner_cases/src/main.c @@ -341,7 +341,7 @@ ZTEST(cbor_decode_test5, test_number_map) zassert_equal(0x12, number_map.opt_short.opt_short, NULL); zassert_false(number_map.opt_cbor_present, NULL); - zassert_equal(ZCBOR_ERR_WRONG_RANGE, cbor_decode_NumberMap(payload_number_map4_inv, + zassert_equal(ZCBOR_ERR_INT_SIZE, cbor_decode_NumberMap(payload_number_map4_inv, sizeof(payload_number_map4_inv), &number_map, &decode_len), NULL); int res = cbor_decode_NumberMap(payload_number_map5_inv, @@ -1286,7 +1286,7 @@ ZTEST(cbor_decode_test5, test_single) uint8_t payload_single3[] = {9}; uint8_t payload_single4_inv[] = {10}; struct zcbor_string result_bstr; - size_t result_int; + uint8_t result_int; size_t out_len; zassert_equal(ZCBOR_SUCCESS, cbor_decode_SingleBstr(payload_single0, sizeof(payload_single0), &result_bstr, &out_len), NULL); @@ -1670,8 +1670,8 @@ ZTEST(cbor_decode_test5, test_prelude) uint8_t prelude_payload1[] = { LIST3(25), 0x40 /* empty bstr */, 0x60 /* empty tstr */, 0xC0, 0x6A, '2', '0', '2', '2', '-', '0', '2', '-', '2', '2' /* tdate */, - 0xC1, 0x1A, 0x62, 0x15, 0x5d, 0x6c /* 1645567340 */, - 0xFA, 0x40, 0x49, 0xe, 0x56 /* 3.1415 */, + 0xC1, 0x1A, 0x62, 0x15, 0x5d, 0x6c /* time: 1645567340 */, + 0xFA, 0x40, 0x49, 0xe, 0x56 /* number: 3.1415 */, 0xC2, 0x4A, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /* 0x0102030405060708090A */, 0xC3, 0x4A, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9 /* -0x0102030405060708090A */, 0xC3, 0x4A, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9 /* -0x0102030405060708090A */, diff --git a/tests/encode/test3_corner_cases/src/main.c b/tests/encode/test3_corner_cases/src/main.c index 61cf5a0c..5fec9365 100644 --- a/tests/encode/test3_corner_cases/src/main.c +++ b/tests/encode/test3_corner_cases/src/main.c @@ -1039,8 +1039,8 @@ ZTEST(cbor_encode_test3, test_single) }; size_t input_single1 = 52; size_t input_single2_ign = 53; - size_t input_single3 = 9; - size_t input_single4_inv = 10; + uint8_t input_single3 = 9; + uint8_t input_single4_inv = 10; zassert_equal(ZCBOR_SUCCESS, cbor_encode_SingleBstr(output, sizeof(output), &input_single0, &out_len), NULL); zassert_equal(sizeof(exp_payload_single0), out_len, NULL); diff --git a/zcbor/zcbor.py b/zcbor/zcbor.py index ea649a01..cca870ca 100755 --- a/zcbor/zcbor.py +++ b/zcbor/zcbor.py @@ -56,6 +56,10 @@ INT32_MIN = -0x80000000 INT64_MIN = -0x8000000000000000 +UINT_MAX = {8: UINT8_MAX, 16: UINT16_MAX, 32: UINT32_MAX, 64: UINT64_MAX} +INT_MIN = {8: INT8_MIN, 16: INT16_MIN, 32: INT32_MIN, 64: INT64_MIN} +INT_MAX = {8: INT8_MAX, 16: INT16_MAX, 32: INT32_MAX, 64: INT64_MAX} + def getrp(pattern, flags=0): """Get a compiled regex pattern from the cache. Add it to the cache if not present.""" @@ -1953,25 +1957,42 @@ def enum_type_name(self): def bit_size(self): """The bit width of the integers as represented in code.""" - bit_size = None if self.type in ["UINT", "INT", "NINT"]: assert self.default_bit_size in [32, 64], "The default_bit_size must be 32 or 64." - if self.default_bit_size == 64: - bit_size = 64 - else: - bit_size = 32 - - for v in [self.value or 0, self.max_value or 0, self.min_value or 0]: - if (type(v) is str): - if "64" in v: - bit_size = 64 - elif self.type == "UINT": - if (v > UINT32_MAX): - bit_size = 64 + default_max = INT_MAX[self.default_bit_size] + default_min = 0 if self.type == "UINT" else INT_MIN[self.default_bit_size] + + candidates = [] + + for v in [ + self.value or 0, + self.max_value or default_max, + self.min_value or default_min]: + if (type(v) is str): + bit_size = max([x for x in (8, 16, 32, 64) if x in v], default=bit_size) + elif self.type == "UINT": + if (v > UINT32_MAX): + bit_size = 64 + elif (v > UINT16_MAX): + bit_size = 32 + elif (v > UINT8_MAX): + bit_size = 16 + else: + bit_size = 8 + else: + if (v > INT32_MAX) or (v < INT32_MIN): + bit_size = 64 + elif (v > INT16_MAX) or (v < INT16_MIN): + bit_size = 32 + elif (v > INT8_MAX) or (v < INT8_MIN): + bit_size = 16 else: - if (v > INT32_MAX) or (v < INT32_MIN): - bit_size = 64 - return bit_size + bit_size = 8 + candidates.append(bit_size) + + return max(candidates) + else: + return None def float_type(self): """If this is a floating point number, return the C type to use for it.""" @@ -3095,7 +3116,7 @@ def parse_args(): code_parser.add_argument( "-b", "--default-bit-size", required=False, type=int, default=32, choices=[32, 64], help="""Default bit size of integers in code. When integers have no explicit bounds, -assume they have this bit width. Should follow the bit width of the architecture +assume they have this bit width. Recommended to follow the bit width of the architecture the code will be running on.""") code_parser.add_argument( "--include-prefix", default="",