From b751dd25ce53e7c18e25c8cc614834caeb48cc46 Mon Sep 17 00:00:00 2001 From: Siebren Weertman Date: Wed, 17 Jan 2024 12:22:55 +0000 Subject: [PATCH 1/4] Use big int for integer type without max value Signed-off-by: Siebren Weertman Signed-off-by: Siebren Weertman --- src/cbexigen/decoder_classes.py | 19 ++++++++++ src/cbexigen/encoder_classes.py | 11 ++++++ src/cbexigen/tools.py | 3 +- .../c/decoder/DecodeTypeSigned.jinja | 9 +++++ .../c/encoder/EncodeTypeSigned.jinja | 14 ++++++++ .../c/static_code/exi_basetypes.c.jinja | 36 +++++++++++++++++++ .../c/static_code/exi_basetypes.h.jinja | 14 +++++++- .../static_code/exi_basetypes_decoder.c.jinja | 21 +++++++++++ .../static_code/exi_basetypes_decoder.h.jinja | 2 ++ .../static_code/exi_basetypes_encoder.c.jinja | 22 ++++++++++-- .../static_code/exi_basetypes_encoder.h.jinja | 2 ++ 11 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 src/input/code_templates/c/decoder/DecodeTypeSigned.jinja create mode 100644 src/input/code_templates/c/encoder/EncodeTypeSigned.jinja diff --git a/src/cbexigen/decoder_classes.py b/src/cbexigen/decoder_classes.py index cfaf1f2..ea07f8d 100644 --- a/src/cbexigen/decoder_classes.py +++ b/src/cbexigen/decoder_classes.py @@ -365,6 +365,23 @@ def __get_content_decode_long_int(self, element_typename, detail: ElementGrammar return decode_content + def __get_content_decode_signed(self, element_typename, detail: ElementGrammarDetail, level): + type_value = f'{element_typename}->{detail.particle.name}' + next_grammar_id = detail.next_grammar + + template_file = 'DecodeTypeSigned.jinja' + decode_comment = '// decode: signed' + if detail.particle.is_attribute: + decode_comment += ' (Attribute)' + temp = self.generator.get_template(template_file) + decode_content = temp.render(decode_comment=decode_comment, + type_value=type_value, + type_option=detail.particle.is_optional, + next_grammar_id=next_grammar_id, + indent=self.indent, level=level) + + return decode_content + def __get_content_decode_string(self, element_typename, detail: ElementGrammarDetail, level): decode_comment = '// decode: string (len, characters)' if detail.particle.is_attribute: @@ -550,6 +567,8 @@ def __get_type_content(self, grammar: ElementGrammar, detail: ElementGrammarDeta type_content = self.__get_content_decode_int(grammar.element_typename, detail, level) elif detail.particle.integer_base_type == 'uint64': type_content = self.__get_content_decode_long_int(grammar.element_typename, detail, level) + elif detail.particle.integer_base_type == 'signed': + type_content = self.__get_content_decode_signed(grammar.element_typename, detail, level) else: log_write_error(f"Unhandled numeric type: '{detail.particle.name}': " f"'{detail.particle.type_short}', " + diff --git a/src/cbexigen/encoder_classes.py b/src/cbexigen/encoder_classes.py index ec09067..0ca423a 100644 --- a/src/cbexigen/encoder_classes.py +++ b/src/cbexigen/encoder_classes.py @@ -282,6 +282,15 @@ def __get_content_encode_long_int(self, element_typename, detail: ElementGrammar return content + def __get_content_encode_signed(self, element_typename, detail, level): + value_parameter = f'{element_typename}->{detail.particle.name}' + + temp = self.generator.get_template('EncodeTypeSigned.jinja') + content = temp.render(value_parameter=value_parameter, + next_grammar=detail.next_grammar, + indent=self.indent, level=level) + return content + def __get_content_encode_string(self, element_typename, detail: ElementGrammarDetail, level): length_parameter = f'{element_typename}->{detail.particle.name}.{detail.particle.length_parameter_name}' value_parameter = f'{element_typename}->{detail.particle.name}.{detail.particle.value_parameter_name}' @@ -420,6 +429,8 @@ def __get_type_content(self, grammar: ElementGrammar, detail: ElementGrammarDeta type_content = self.__get_content_encode_int(grammar.element_typename, detail, level) elif detail.particle.integer_base_type == 'uint64': type_content = self.__get_content_encode_long_int(grammar.element_typename, detail, level) + elif detail.particle.integer_base_type == 'signed': + type_content = self.__get_content_encode_signed(grammar.element_typename, detail, level) else: log_write_error(f"Unhandled numeric type: '{detail.particle.name}': " f"'{detail.particle.type_short}', " + diff --git a/src/cbexigen/tools.py b/src/cbexigen/tools.py index b26f5ae..f82a9e5 100644 --- a/src/cbexigen/tools.py +++ b/src/cbexigen/tools.py @@ -21,6 +21,7 @@ 'uint16': 'uint16_t', 'uint32': 'uint32_t', 'uint64': 'uint64_t', + 'signed': 'exi_signed_t', } TYPE_TRANSLATION = { @@ -29,7 +30,7 @@ 'byte': 'int8', 'short': 'int16', 'int': 'int32', - 'integer': 'int32', + 'integer': 'signed', 'long': 'int64', 'decimal': 'integer', # FIXME special type 'unsignedByte': 'uint8', diff --git a/src/input/code_templates/c/decoder/DecodeTypeSigned.jinja b/src/input/code_templates/c/decoder/DecodeTypeSigned.jinja new file mode 100644 index 0000000..fa6d4a1 --- /dev/null +++ b/src/input/code_templates/c/decoder/DecodeTypeSigned.jinja @@ -0,0 +1,9 @@ +{{ indent * level }}{{ decode_comment }} +{{ indent * level }}error = exi_basetypes_decoder_signed(stream, &{{ type_value }}); +{{ indent * level }}if (error == 0) +{{ indent * level }}{ +{%- if type_option == 1 %} +{{ indent * (level + 1) }}{{ type_value }}_isUsed = 1u; +{%- endif %} +{{ indent * (level + 1) }}grammar_id = {{ next_grammar_id }}; +{{ indent * level }}} diff --git a/src/input/code_templates/c/encoder/EncodeTypeSigned.jinja b/src/input/code_templates/c/encoder/EncodeTypeSigned.jinja new file mode 100644 index 0000000..d1fc767 --- /dev/null +++ b/src/input/code_templates/c/encoder/EncodeTypeSigned.jinja @@ -0,0 +1,14 @@ +{{ indent * level }}error = exi_basetypes_encoder_nbit_uint(stream, 1, 0); +{{ indent * level }}if (error == EXI_ERROR__NO_ERROR) +{{ indent * level }}{ +{{ indent * (level + 1) }}error = exi_basetypes_encoder_signed(stream, &{{ value_parameter }}); +{{ indent * (level + 1) }}if (error == EXI_ERROR__NO_ERROR) +{{ indent * (level + 1) }}{ +{{ indent * (level + 2) }}// encode END Element +{{ indent * (level + 2) }}error = exi_basetypes_encoder_nbit_uint(stream, 1, 0); +{{ indent * (level + 2) }}if (error == EXI_ERROR__NO_ERROR) +{{ indent * (level + 2) }}{ +{{ indent * (level + 3) }}grammar_id = {{ next_grammar }}; +{{ indent * (level + 2) }}} +{{ indent * (level + 1) }}} +{{ indent * level }}} diff --git a/src/input/code_templates/c/static_code/exi_basetypes.c.jinja b/src/input/code_templates/c/static_code/exi_basetypes.c.jinja index 45d5c8f..088e559 100644 --- a/src/input/code_templates/c/static_code/exi_basetypes.c.jinja +++ b/src/input/code_templates/c/static_code/exi_basetypes.c.jinja @@ -58,6 +58,26 @@ int exi_basetypes_convert_64_to_unsigned(exi_unsigned_t* exi_unsigned, uint64_t return (exi_unsigned->octets_count <= EXI_BASETYPES_UINT64_MAX_OCTETS) ? EXI_ERROR__NO_ERROR : EXI_ERROR__OCTET_COUNT_LARGER_THAN_TYPE_SUPPORTS; } +int exi_basetypes_convert_to_signed(exi_signed_t* exi_signed, int32_t value, size_t max_octets) +{ + if (value < 0) { + exi_signed->is_negative = 1; + return exi_basetypes_convert_to_unsigned(&exi_signed->data, -value, max_octets); + } + exi_signed->is_negative = 0; + return exi_basetypes_convert_to_unsigned(&exi_signed->data, value, max_octets); +} + +int exi_basetypes_convert_64_to_signed(exi_signed_t* exi_signed, int64_t value) +{ + if (value < 0) { + exi_signed->is_negative = 1; + return exi_basetypes_convert_64_to_unsigned(&exi_signed->data, -value); + } + exi_signed->is_negative = 0; + return exi_basetypes_convert_64_to_unsigned(&exi_signed->data, value); +} + int exi_basetypes_convert_from_unsigned(exi_unsigned_t* exi_unsigned, uint32_t* value, size_t max_octets) { if (exi_unsigned->octets_count > max_octets) @@ -97,4 +117,20 @@ int exi_basetypes_convert_64_from_unsigned(exi_unsigned_t* exi_unsigned, uint64_ return EXI_ERROR__NO_ERROR; } + +int exi_basetypes_convert_from_signed(exi_signed_t* exi_signed, int32_t* value, size_t max_octets) +{ + uint32_t uValue = 0; + int res = exi_basetypes_convert_from_unsigned(&exi_signed->data, &uValue, max_octets); + *value = (exi_signed->is_negative == 0) ? uValue : -uValue; + return res; +} + +int exi_basetypes_convert_64_from_signed(exi_signed_t* exi_signed, int64_t* value) +{ + uint64_t uValue = 0; + int res = exi_basetypes_convert_64_from_unsigned(&exi_signed->data, &uValue); + *value = (exi_signed->is_negative == 0) ? uValue : -uValue; + return res; +} {% endblock %} diff --git a/src/input/code_templates/c/static_code/exi_basetypes.h.jinja b/src/input/code_templates/c/static_code/exi_basetypes.h.jinja index bba1dde..20d59c4 100644 --- a/src/input/code_templates/c/static_code/exi_basetypes.h.jinja +++ b/src/input/code_templates/c/static_code/exi_basetypes.h.jinja @@ -16,7 +16,7 @@ #define EXI_STRING_MAX_LEN 64 #define EXI_BYTE_ARRAY_MAX_LEN 350 -#define EXI_BASETYPES_MAX_OCTETS_SUPPORTED 10 +#define EXI_BASETYPES_MAX_OCTETS_SUPPORTED 20 #define EXI_BASETYPES_OCTET_SEQ_FLAG_MASK 0x80 #define EXI_BASETYPES_OCTET_SEQ_VALUE_MASK 0x7F @@ -40,6 +40,12 @@ typedef struct size_t octets_count; } exi_unsigned_t; +typedef struct exi_signed_t +{ + exi_unsigned_t data; + uint8_t is_negative : 1; +} exi_signed_t; + typedef char exi_character_t; int exi_basetypes_convert_to_unsigned(exi_unsigned_t* exi_unsigned, uint32_t value, size_t max_octets); @@ -47,4 +53,10 @@ int exi_basetypes_convert_64_to_unsigned(exi_unsigned_t* exi_unsigned, uint64_t int exi_basetypes_convert_from_unsigned(exi_unsigned_t* exi_unsigned, uint32_t* value, size_t max_octets); int exi_basetypes_convert_64_from_unsigned(exi_unsigned_t* exi_unsigned, uint64_t* value); + +int exi_basetypes_convert_to_signed(exi_signed_t* exi_signed, int32_t value, size_t max_octets); +int exi_basetypes_convert_64_to_signed(exi_signed_t* exi_signed, int64_t value); + +int exi_basetypes_convert_from_signed(exi_signed_t* exi_unsigned, int32_t* value, size_t max_octets); +int exi_basetypes_convert_64_from_signed(exi_signed_t* exi_unsigned, int64_t* value); {% endblock %} diff --git a/src/input/code_templates/c/static_code/exi_basetypes_decoder.c.jinja b/src/input/code_templates/c/static_code/exi_basetypes_decoder.c.jinja index a8da681..719720e 100644 --- a/src/input/code_templates/c/static_code/exi_basetypes_decoder.c.jinja +++ b/src/input/code_templates/c/static_code/exi_basetypes_decoder.c.jinja @@ -224,6 +224,11 @@ int exi_basetypes_decoder_uint_64(exi_bitstream_t* stream, uint64_t* value) return EXI_ERROR__NO_ERROR; } +int exi_basetypes_decoder_unsigned(exi_bitstream_t* stream, exi_unsigned_t* value) +{ + return exi_basetypes_decoder_read_unsigned(stream, value); +} + /***************************************************************************** * interface functions - integer *****************************************************************************/ @@ -341,6 +346,22 @@ int exi_basetypes_decoder_integer_64(exi_bitstream_t* stream, int64_t* value) return error; } +int exi_basetypes_decoder_signed(exi_bitstream_t* stream, exi_signed_t* value) +{ + int sign; + int error; + + error = exi_basetypes_decoder_bool(stream, &sign); + if (error != EXI_ERROR__NO_ERROR) + { + return error; + } + value->is_negative = (sign == 0) ? 0 : 1; + + error = exi_basetypes_decoder_unsigned(stream, &value->data); + return error; +} + /***************************************************************************** * interface functions - characters, string *****************************************************************************/ diff --git a/src/input/code_templates/c/static_code/exi_basetypes_decoder.h.jinja b/src/input/code_templates/c/static_code/exi_basetypes_decoder.h.jinja index 374c80e..5bcb808 100644 --- a/src/input/code_templates/c/static_code/exi_basetypes_decoder.h.jinja +++ b/src/input/code_templates/c/static_code/exi_basetypes_decoder.h.jinja @@ -62,6 +62,7 @@ int exi_basetypes_decoder_uint_8(exi_bitstream_t* stream, uint8_t* value); int exi_basetypes_decoder_uint_16(exi_bitstream_t* stream, uint16_t* value); int exi_basetypes_decoder_uint_32(exi_bitstream_t* stream, uint32_t* value); int exi_basetypes_decoder_uint_64(exi_bitstream_t* stream, uint64_t* value); +int exi_basetypes_decoder_unsigned(exi_bitstream_t* stream, exi_unsigned_t* value); /** * \brief decoder for type integer @@ -79,6 +80,7 @@ int exi_basetypes_decoder_integer_8(exi_bitstream_t* stream, int8_t* value); int exi_basetypes_decoder_integer_16(exi_bitstream_t* stream, int16_t* value); int exi_basetypes_decoder_integer_32(exi_bitstream_t* stream, int32_t* value); int exi_basetypes_decoder_integer_64(exi_bitstream_t* stream, int64_t* value); +int exi_basetypes_decoder_signed(exi_bitstream_t* stream, exi_signed_t* value); /** * \brief decoder for type character array diff --git a/src/input/code_templates/c/static_code/exi_basetypes_encoder.c.jinja b/src/input/code_templates/c/static_code/exi_basetypes_encoder.c.jinja index dad98b8..3378e67 100644 --- a/src/input/code_templates/c/static_code/exi_basetypes_encoder.c.jinja +++ b/src/input/code_templates/c/static_code/exi_basetypes_encoder.c.jinja @@ -11,7 +11,7 @@ /***************************************************************************** * local functions *****************************************************************************/ -static int exi_basetypes_encoder_write_unsigned(exi_bitstream_t* stream, exi_unsigned_t* exi_unsigned) +static int exi_basetypes_encoder_write_unsigned(exi_bitstream_t* stream, const exi_unsigned_t* exi_unsigned) { {%- if add_debug_code == 1 %} if (stream->status_callback) @@ -19,7 +19,7 @@ static int exi_basetypes_encoder_write_unsigned(exi_bitstream_t* stream, exi_uns stream->status_callback(EXI_DEBUG__BASETYPES_ENCODE_UNSIGNED, 0, exi_unsigned->octets_count, 0); } {% endif %} - uint8_t* current_octet = exi_unsigned->octets; + const uint8_t* current_octet = exi_unsigned->octets; for (size_t n = 0; n < exi_unsigned->octets_count; n++) { @@ -173,6 +173,11 @@ int exi_basetypes_encoder_uint_64(exi_bitstream_t* stream, uint64_t value) return exi_basetypes_encoder_write_unsigned(stream, &exi_unsigned); } +int exi_basetypes_encoder_unsigned(exi_bitstream_t* stream, const exi_unsigned_t* value) +{ + return exi_basetypes_encoder_write_unsigned(stream, value); +} + /***************************************************************************** * interface functions - integer *****************************************************************************/ @@ -278,6 +283,19 @@ int exi_basetypes_encoder_integer_64(exi_bitstream_t* stream, int64_t value) return exi_basetypes_encoder_uint_64(stream, result); } +int exi_basetypes_encoder_signed(exi_bitstream_t* stream, const exi_signed_t* value) +{ + int error; + + error = exi_basetypes_encoder_bool(stream, value->is_negative); + if (error != EXI_ERROR__NO_ERROR) + { + return error; + } + + return exi_basetypes_encoder_unsigned(stream, &value->data); +} + /***************************************************************************** * interface functions - characters, string *****************************************************************************/ diff --git a/src/input/code_templates/c/static_code/exi_basetypes_encoder.h.jinja b/src/input/code_templates/c/static_code/exi_basetypes_encoder.h.jinja index e81f52c..cbf7d04 100644 --- a/src/input/code_templates/c/static_code/exi_basetypes_encoder.h.jinja +++ b/src/input/code_templates/c/static_code/exi_basetypes_encoder.h.jinja @@ -62,6 +62,7 @@ int exi_basetypes_encoder_uint_8(exi_bitstream_t* stream, uint8_t value); int exi_basetypes_encoder_uint_16(exi_bitstream_t* stream, uint16_t value); int exi_basetypes_encoder_uint_32(exi_bitstream_t* stream, uint32_t value); int exi_basetypes_encoder_uint_64(exi_bitstream_t* stream, uint64_t value); +int exi_basetypes_encoder_unsigned(exi_bitstream_t* stream, const exi_unsigned_t* value); /** * \brief encoder for type integer @@ -79,6 +80,7 @@ int exi_basetypes_encoder_integer_8(exi_bitstream_t* stream, int8_t value); int exi_basetypes_encoder_integer_16(exi_bitstream_t* stream, int16_t value); int exi_basetypes_encoder_integer_32(exi_bitstream_t* stream, int32_t value); int exi_basetypes_encoder_integer_64(exi_bitstream_t* stream, int64_t value); +int exi_basetypes_encoder_signed(exi_bitstream_t* stream, const exi_signed_t* value); /** * \brief encoder for type exi_character array From 243ad56741069c545fcaf22d4c79ecdff55cc650 Mon Sep 17 00:00:00 2001 From: Siebren Weertman Date: Thu, 18 Jan 2024 10:09:17 +0000 Subject: [PATCH 2/4] fix decoder for signed datatype with non-strict exi padding Signed-off-by: Siebren Weertman Signed-off-by: Siebren Weertman --- .../code_templates/c/decoder/DecodeTypeSigned.jinja | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/input/code_templates/c/decoder/DecodeTypeSigned.jinja b/src/input/code_templates/c/decoder/DecodeTypeSigned.jinja index fa6d4a1..ddde9cb 100644 --- a/src/input/code_templates/c/decoder/DecodeTypeSigned.jinja +++ b/src/input/code_templates/c/decoder/DecodeTypeSigned.jinja @@ -1,9 +1,14 @@ {{ indent * level }}{{ decode_comment }} -{{ indent * level }}error = exi_basetypes_decoder_signed(stream, &{{ type_value }}); +{{ indent * level }}error = exi_basetypes_decoder_nbit_uint(stream, 1, &eventCode); {{ indent * level }}if (error == 0) {{ indent * level }}{ +{{ indent * (level + 1) }}error = exi_basetypes_decoder_signed(stream, &{{ type_value }}); +{{ indent * (level + 1) }}if (error == 0) +{{ indent * (level + 1) }}{ {%- if type_option == 1 %} -{{ indent * (level + 1) }}{{ type_value }}_isUsed = 1u; +{{ indent * (level + 2) }}{{ type_value }}_isUsed = 1u; {%- endif %} -{{ indent * (level + 1) }}grammar_id = {{ next_grammar_id }}; +{{ indent * (level + 2) }}grammar_id = {{ next_grammar_id }}; +{{ indent * (level + 1) }}} +{{ indent * (level + 1) }}error = exi_basetypes_decoder_nbit_uint(stream, 1, &eventCode); {{ indent * level }}} From b76f8186dfe2306fe489f21ed444c8a82ece6c93 Mon Sep 17 00:00:00 2001 From: Siebren Weertman Date: Wed, 31 Jan 2024 09:14:44 +0000 Subject: [PATCH 3/4] add conversion for byte to/from unsigned (bigint) datatype Signed-off-by: Siebren Weertman const correctness and remove log Signed-off-by: Siebren Weertman init dummy Signed-off-by: Siebren Weertman --- .../c/static_code/exi_basetypes.c.jinja | 72 +++++++++++++++++-- .../c/static_code/exi_basetypes.h.jinja | 11 +-- 2 files changed, 73 insertions(+), 10 deletions(-) diff --git a/src/input/code_templates/c/static_code/exi_basetypes.c.jinja b/src/input/code_templates/c/static_code/exi_basetypes.c.jinja index 088e559..47951f7 100644 --- a/src/input/code_templates/c/static_code/exi_basetypes.c.jinja +++ b/src/input/code_templates/c/static_code/exi_basetypes.c.jinja @@ -78,14 +78,14 @@ int exi_basetypes_convert_64_to_signed(exi_signed_t* exi_signed, int64_t value) return exi_basetypes_convert_64_to_unsigned(&exi_signed->data, value); } -int exi_basetypes_convert_from_unsigned(exi_unsigned_t* exi_unsigned, uint32_t* value, size_t max_octets) +int exi_basetypes_convert_from_unsigned(const exi_unsigned_t* exi_unsigned, uint32_t* value, size_t max_octets) { if (exi_unsigned->octets_count > max_octets) { return EXI_ERROR__OCTET_COUNT_LARGER_THAN_TYPE_SUPPORTS; } - uint8_t* current_octet = exi_unsigned->octets; + const uint8_t* current_octet = exi_unsigned->octets; *value = 0; for (size_t n = 0; n < exi_unsigned->octets_count; n++) @@ -98,14 +98,14 @@ int exi_basetypes_convert_from_unsigned(exi_unsigned_t* exi_unsigned, uint32_t* return EXI_ERROR__NO_ERROR; } -int exi_basetypes_convert_64_from_unsigned(exi_unsigned_t* exi_unsigned, uint64_t* value) +int exi_basetypes_convert_64_from_unsigned(const exi_unsigned_t* exi_unsigned, uint64_t* value) { if (exi_unsigned->octets_count > EXI_BASETYPES_UINT64_MAX_OCTETS) { return EXI_ERROR__OCTET_COUNT_LARGER_THAN_TYPE_SUPPORTS; } - uint8_t* current_octet = exi_unsigned->octets; + const uint8_t* current_octet = exi_unsigned->octets; *value = 0; for (size_t n = 0; n < exi_unsigned->octets_count; n++) @@ -118,7 +118,7 @@ int exi_basetypes_convert_64_from_unsigned(exi_unsigned_t* exi_unsigned, uint64_ return EXI_ERROR__NO_ERROR; } -int exi_basetypes_convert_from_signed(exi_signed_t* exi_signed, int32_t* value, size_t max_octets) +int exi_basetypes_convert_from_signed(const exi_signed_t* exi_signed, int32_t* value, size_t max_octets) { uint32_t uValue = 0; int res = exi_basetypes_convert_from_unsigned(&exi_signed->data, &uValue, max_octets); @@ -126,11 +126,71 @@ int exi_basetypes_convert_from_signed(exi_signed_t* exi_signed, int32_t* value, return res; } -int exi_basetypes_convert_64_from_signed(exi_signed_t* exi_signed, int64_t* value) +int exi_basetypes_convert_64_from_signed(const exi_signed_t* exi_signed, int64_t* value) { uint64_t uValue = 0; int res = exi_basetypes_convert_64_from_unsigned(&exi_signed->data, &uValue); *value = (exi_signed->is_negative == 0) ? uValue : -uValue; return res; } + +int exi_basetypes_convert_bytes_from_unsigned(const exi_unsigned_t* exi_unsigned, uint8_t* data, size_t* data_len, size_t data_size) +{ + const uint8_t* current_octet = exi_unsigned->octets; + uint16_t temp = 0; + *data_len = 0; + size_t total_offset = 0; + + for (size_t n = 0; n < exi_unsigned->octets_count; n++) { + temp = temp + ((uint16_t)(*current_octet & EXI_BASETYPES_OCTET_SEQ_VALUE_MASK) << (total_offset)); + total_offset += 7; + if (total_offset >= 8) { + if (data_size == *data_len) { + return -1; + } + total_offset -= 8; + data[(*data_len)++] = temp & 0xFF; + temp >>= 8; + } + current_octet++; + } + if (total_offset != 0) { + if (data_size == *data_len) { + return -1; + } + data[(*data_len)++] = temp & 0xFF; + } + return 0; +} + +int exi_basetypes_convert_bytes_to_unsigned(exi_unsigned_t* exi_unsigned, const uint8_t* data, size_t data_len) +{ + uint8_t *current_octet = &exi_unsigned->octets[0]; + uint16_t dummy = 0; + uint8_t dummy_count = 0; + + for (size_t n = 0; n != data_len; n++, current_octet++) { + if (dummy_count <= 8) { + dummy = dummy | ((data[n]) << dummy_count); + dummy_count += 8; + } + exi_unsigned->octets_count++; + *current_octet = (uint8_t)(dummy & EXI_BASETYPES_OCTET_SEQ_VALUE_MASK); + + dummy = dummy >> 7u; + dummy_count -= 7; + if (n == data_len) { + break; + } + + *current_octet |= EXI_BASETYPES_OCTET_SEQ_FLAG_MASK; + } + if (dummy_count > 0) { + *(current_octet-1) |= EXI_BASETYPES_OCTET_SEQ_FLAG_MASK; + exi_unsigned->octets_count++; + *current_octet = (uint8_t)(dummy & EXI_BASETYPES_OCTET_SEQ_VALUE_MASK); + } + return 0; +} + {% endblock %} diff --git a/src/input/code_templates/c/static_code/exi_basetypes.h.jinja b/src/input/code_templates/c/static_code/exi_basetypes.h.jinja index 20d59c4..cb377a0 100644 --- a/src/input/code_templates/c/static_code/exi_basetypes.h.jinja +++ b/src/input/code_templates/c/static_code/exi_basetypes.h.jinja @@ -51,12 +51,15 @@ typedef char exi_character_t; int exi_basetypes_convert_to_unsigned(exi_unsigned_t* exi_unsigned, uint32_t value, size_t max_octets); int exi_basetypes_convert_64_to_unsigned(exi_unsigned_t* exi_unsigned, uint64_t value); -int exi_basetypes_convert_from_unsigned(exi_unsigned_t* exi_unsigned, uint32_t* value, size_t max_octets); -int exi_basetypes_convert_64_from_unsigned(exi_unsigned_t* exi_unsigned, uint64_t* value); +int exi_basetypes_convert_from_unsigned(const exi_unsigned_t* exi_unsigned, uint32_t* value, size_t max_octets); +int exi_basetypes_convert_64_from_unsigned(const exi_unsigned_t* exi_unsigned, uint64_t* value); int exi_basetypes_convert_to_signed(exi_signed_t* exi_signed, int32_t value, size_t max_octets); int exi_basetypes_convert_64_to_signed(exi_signed_t* exi_signed, int64_t value); -int exi_basetypes_convert_from_signed(exi_signed_t* exi_unsigned, int32_t* value, size_t max_octets); -int exi_basetypes_convert_64_from_signed(exi_signed_t* exi_unsigned, int64_t* value); +int exi_basetypes_convert_from_signed(const exi_signed_t* exi_unsigned, int32_t* value, size_t max_octets); +int exi_basetypes_convert_64_from_signed(const exi_signed_t* exi_unsigned, int64_t* value); + +int exi_basetypes_convert_bytes_from_unsigned(const exi_unsigned_t* exi_unsigned, uint8_t* data, size_t* data_len, size_t data_size); +int exi_basetypes_convert_bytes_to_unsigned(exi_unsigned_t* exi_unsigned, const uint8_t* data, size_t data_len); {% endblock %} From de691166c8f0a55ac30a7b69361ec4258d2b562b Mon Sep 17 00:00:00 2001 From: Siebren Date: Fri, 18 Oct 2024 21:28:35 +0200 Subject: [PATCH 4/4] increase int buffer and code cleanup Signed-off-by: Siebren --- .../c/static_code/exi_basetypes.c.jinja | 28 +++++++++---------- .../c/static_code/exi_basetypes.h.jinja | 2 +- .../static_code/exi_basetypes_decoder.c.jinja | 5 ++-- .../static_code/exi_basetypes_encoder.c.jinja | 4 +-- .../c/static_code/exi_error_codes.h.jinja | 1 + 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/input/code_templates/c/static_code/exi_basetypes.c.jinja b/src/input/code_templates/c/static_code/exi_basetypes.c.jinja index 47951f7..6e4eb10 100644 --- a/src/input/code_templates/c/static_code/exi_basetypes.c.jinja +++ b/src/input/code_templates/c/static_code/exi_basetypes.c.jinja @@ -120,33 +120,33 @@ int exi_basetypes_convert_64_from_unsigned(const exi_unsigned_t* exi_unsigned, u int exi_basetypes_convert_from_signed(const exi_signed_t* exi_signed, int32_t* value, size_t max_octets) { - uint32_t uValue = 0; - int res = exi_basetypes_convert_from_unsigned(&exi_signed->data, &uValue, max_octets); - *value = (exi_signed->is_negative == 0) ? uValue : -uValue; + uint32_t u_value = 0; + int res = exi_basetypes_convert_from_unsigned(&exi_signed->data, &u_value, max_octets); + *value = (exi_signed->is_negative == 0) ? u_value : -u_value; return res; } int exi_basetypes_convert_64_from_signed(const exi_signed_t* exi_signed, int64_t* value) { - uint64_t uValue = 0; - int res = exi_basetypes_convert_64_from_unsigned(&exi_signed->data, &uValue); - *value = (exi_signed->is_negative == 0) ? uValue : -uValue; + uint64_t u_value = 0; + int res = exi_basetypes_convert_64_from_unsigned(&exi_signed->data, &u_value); + *value = (exi_signed->is_negative == 0) ? u_value : -u_value; return res; } int exi_basetypes_convert_bytes_from_unsigned(const exi_unsigned_t* exi_unsigned, uint8_t* data, size_t* data_len, size_t data_size) -{ +{ const uint8_t* current_octet = exi_unsigned->octets; uint16_t temp = 0; *data_len = 0; size_t total_offset = 0; for (size_t n = 0; n < exi_unsigned->octets_count; n++) { - temp = temp + ((uint16_t)(*current_octet & EXI_BASETYPES_OCTET_SEQ_VALUE_MASK) << (total_offset)); + temp += ((uint16_t)(*current_octet & EXI_BASETYPES_OCTET_SEQ_VALUE_MASK) << total_offset); total_offset += 7; if (total_offset >= 8) { if (data_size == *data_len) { - return -1; + return EXI_ERROR__ENCODED_INTEGER_SIZE_LARGER_THAN_DESTINATION; } total_offset -= 8; data[(*data_len)++] = temp & 0xFF; @@ -156,11 +156,11 @@ int exi_basetypes_convert_bytes_from_unsigned(const exi_unsigned_t* exi_unsigned } if (total_offset != 0) { if (data_size == *data_len) { - return -1; + return EXI_ERROR__ENCODED_INTEGER_SIZE_LARGER_THAN_DESTINATION; } data[(*data_len)++] = temp & 0xFF; } - return 0; + return EXI_ERROR__NO_ERROR; } int exi_basetypes_convert_bytes_to_unsigned(exi_unsigned_t* exi_unsigned, const uint8_t* data, size_t data_len) @@ -171,13 +171,13 @@ int exi_basetypes_convert_bytes_to_unsigned(exi_unsigned_t* exi_unsigned, const for (size_t n = 0; n != data_len; n++, current_octet++) { if (dummy_count <= 8) { - dummy = dummy | ((data[n]) << dummy_count); + dummy |= (data[n] << dummy_count); dummy_count += 8; } exi_unsigned->octets_count++; *current_octet = (uint8_t)(dummy & EXI_BASETYPES_OCTET_SEQ_VALUE_MASK); - dummy = dummy >> 7u; + dummy >>= 7u; dummy_count -= 7; if (n == data_len) { break; @@ -190,7 +190,7 @@ int exi_basetypes_convert_bytes_to_unsigned(exi_unsigned_t* exi_unsigned, const exi_unsigned->octets_count++; *current_octet = (uint8_t)(dummy & EXI_BASETYPES_OCTET_SEQ_VALUE_MASK); } - return 0; + return EXI_ERROR__NO_ERROR; } {% endblock %} diff --git a/src/input/code_templates/c/static_code/exi_basetypes.h.jinja b/src/input/code_templates/c/static_code/exi_basetypes.h.jinja index cb377a0..1ba195a 100644 --- a/src/input/code_templates/c/static_code/exi_basetypes.h.jinja +++ b/src/input/code_templates/c/static_code/exi_basetypes.h.jinja @@ -16,7 +16,7 @@ #define EXI_STRING_MAX_LEN 64 #define EXI_BYTE_ARRAY_MAX_LEN 350 -#define EXI_BASETYPES_MAX_OCTETS_SUPPORTED 20 +#define EXI_BASETYPES_MAX_OCTETS_SUPPORTED 29 #define EXI_BASETYPES_OCTET_SEQ_FLAG_MASK 0x80 #define EXI_BASETYPES_OCTET_SEQ_VALUE_MASK 0x7F diff --git a/src/input/code_templates/c/static_code/exi_basetypes_decoder.c.jinja b/src/input/code_templates/c/static_code/exi_basetypes_decoder.c.jinja index 719720e..806cb3f 100644 --- a/src/input/code_templates/c/static_code/exi_basetypes_decoder.c.jinja +++ b/src/input/code_templates/c/static_code/exi_basetypes_decoder.c.jinja @@ -348,10 +348,9 @@ int exi_basetypes_decoder_integer_64(exi_bitstream_t* stream, int64_t* value) int exi_basetypes_decoder_signed(exi_bitstream_t* stream, exi_signed_t* value) { - int sign; - int error; + int sign = 0; - error = exi_basetypes_decoder_bool(stream, &sign); + int error = exi_basetypes_decoder_bool(stream, &sign); if (error != EXI_ERROR__NO_ERROR) { return error; diff --git a/src/input/code_templates/c/static_code/exi_basetypes_encoder.c.jinja b/src/input/code_templates/c/static_code/exi_basetypes_encoder.c.jinja index 3378e67..8c43da1 100644 --- a/src/input/code_templates/c/static_code/exi_basetypes_encoder.c.jinja +++ b/src/input/code_templates/c/static_code/exi_basetypes_encoder.c.jinja @@ -285,9 +285,7 @@ int exi_basetypes_encoder_integer_64(exi_bitstream_t* stream, int64_t value) int exi_basetypes_encoder_signed(exi_bitstream_t* stream, const exi_signed_t* value) { - int error; - - error = exi_basetypes_encoder_bool(stream, value->is_negative); + int error = exi_basetypes_encoder_bool(stream, value->is_negative); if (error != EXI_ERROR__NO_ERROR) { return error; diff --git a/src/input/code_templates/c/static_code/exi_error_codes.h.jinja b/src/input/code_templates/c/static_code/exi_error_codes.h.jinja index 7a6f7ab..9d02761 100644 --- a/src/input/code_templates/c/static_code/exi_error_codes.h.jinja +++ b/src/input/code_templates/c/static_code/exi_error_codes.h.jinja @@ -30,6 +30,7 @@ #define EXI_ERROR__ARRAY_OUT_OF_BOUNDS -110 #define EXI_ERROR__CHARACTER_BUFFER_TOO_SMALL -111 #define EXI_ERROR__BYTE_BUFFER_TOO_SMALL -112 +#define EXI_ERROR__ENCODED_INTEGER_SIZE_LARGER_THAN_DESTINATION -113 // grammar errors -130 to -149 #define EXI_ERROR__UNKNOWN_GRAMMAR_ID -130