Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions asn1tools/source/c/uper.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from .uper_functions import functions
from ...codecs import uper


def does_bits_match_range(number_of_bits, minimum, maximum):
return 2 ** number_of_bits == (maximum - minimum + 1)

Expand Down Expand Up @@ -62,6 +61,8 @@ def format_type(self, type_, checker):
return self.format_enumerated(type_)
elif isinstance(type_, uper.BitString):
return self.format_bit_string(type_, checker)
elif isinstance(type_, uper.IA5String):
return self.format_ia5string(checker)
else:
raise self.error(
"Unsupported type '{}'.".format(type_.type_name))
Expand Down Expand Up @@ -90,6 +91,9 @@ def generate_type_declaration_process(self, type_, checker):
elif isinstance(type_, uper.OctetString):
lines = self.format_octet_string(checker)[1:-1]
lines = dedent_lines(lines)
elif isinstance(type_, uper.IA5String):
lines = self.format_ia5string(checker)[1:-1]
lines = dedent_lines(lines)
elif isinstance(type_, uper.BitString):
lines = self.format_bit_string(type_, checker)
lines[0] += ' value;'
Expand All @@ -116,6 +120,8 @@ def generate_definition_inner_process(self, type_, checker):
return self.format_choice_inner(type_, checker)
elif isinstance(type_, uper.OctetString):
return self.format_octet_string_inner(type_, checker)
elif isinstance(type_, uper.IA5String):
return self.format_ia5_string_inner(type_, checker)
elif isinstance(type_, uper.BitString):
return self.format_bit_string_inner(type_, checker)
elif isinstance(type_, uper.Enumerated):
Expand Down Expand Up @@ -339,6 +345,36 @@ def format_octet_string_inner(self, type_, checker):

return encode_lines, decode_lines

def format_ia5_string_inner(self, type_, checker):
location = self.location_inner('', '.')

if checker.minimum == checker.maximum:
encode_lines = [
'encoder_append_ia5str(encoder_p,',
' &src_p->{}buf[0],'.format(location),
' {});'.format(checker.maximum)
]
decode_lines = [
'decoder_read_ia5str(decoder_p,',
' &dst_p->{}buf[0],'.format(location),
' {});'.format(checker.maximum)
]
else:
encode_lines = [
'encoder_append_non_negative_binary_integer(encoder_p, src_p->{}length, 14);'.format(location),
'encoder_append_ia5str(encoder_p,',
' &src_p->{}buf[0],'.format(location),
' src_p->{}length);'.format(location)
]
decode_lines = [
'dst_p->{}length = decoder_read_non_negative_binary_integer(decoder_p, 14);'.format(location),
'decoder_read_ia5str(decoder_p,',
' &dst_p->{}buf[0],'.format(location),
' dst_p->{}length);'.format(location)
]

return encode_lines, decode_lines

def format_user_type_inner(self, type_name, module_name):
module_name_snake = camel_to_snake_case(module_name)
type_name_snake = camel_to_snake_case(type_name)
Expand Down Expand Up @@ -379,7 +415,7 @@ def format_choice_inner(self, type_, checker):
member_checker)

index = type_.root_name_to_index[member.name]

choice_encode_lines = [
'encoder_append_non_negative_binary_integer(encoder_p, {}, {});'.format(
index,
Expand Down Expand Up @@ -598,6 +634,8 @@ def format_type_inner(self, type_, checker):
type_.module_name)
elif isinstance(type_, uper.OctetString):
return self.format_octet_string_inner(type_, checker)
elif isinstance(type_, uper.IA5String):
return self.format_ia5_string_inner(type_, checker)
elif isinstance(type_, uper.Sequence):
return self.format_sequence_inner(type_, checker)
elif isinstance(type_, uper.Choice):
Expand Down
22 changes: 22 additions & 0 deletions asn1tools/source/c/uper_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@
}\
'''

ENCODER_APPEND_IA5STR = '''
static void encoder_append_ia5str(struct encoder_t *self_p,
const uint8_t *buf_p,
size_t size)
{
for (int i = 0; i < size; ++i) {
encoder_append_non_negative_binary_integer(self_p, buf_p[i], 7);
}
}
'''

ENCODER_APPEND_BYTES = '''
static void encoder_append_bytes(struct encoder_t *self_p,
const uint8_t *buf_p,
Expand Down Expand Up @@ -269,6 +280,15 @@
}\
'''

DECODER_READ_IA5STR = '''
static void decoder_read_ia5str(struct decoder_t *self_p, uint8_t *buf, int size)
{
for (int i = 0; i < size; ++i) {
buf[i] = decoder_read_non_negative_binary_integer(self_p,7);
}
}
'''

DECODER_READ_BYTES = '''
static void decoder_read_bytes(struct decoder_t *self_p,
uint8_t *buf_p,
Expand Down Expand Up @@ -427,6 +447,7 @@
'''

functions = [
('decoder_read_ia5str(', DECODER_READ_IA5STR),
(
'decoder_read_non_negative_binary_integer(',
DECODER_READ_NON_NEGATIVE_BINARY_INTEGER
Expand All @@ -446,6 +467,7 @@
('decoder_abort(', DECODER_ABORT),
('decoder_get_result(', DECODER_GET_RESULT),
('decoder_init(', DECODER_INIT),
('encoder_append_ia5str(', ENCODER_APPEND_IA5STR),
(
'encoder_append_non_negative_binary_integer(',
ENCODER_APPEND_NON_NEGATIVE_BINARY_INTEGER
Expand Down
18 changes: 17 additions & 1 deletion asn1tools/source/c/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,23 @@ def format_octet_string(self, checker):
'}'
]

def format_ia5string(self, checker):
if not checker.has_upper_bound():
raise self.error('IA5String has no maximum length.')

if checker.minimum == checker.maximum:
lines = []
if checker.maximum < 256:
lines = [' uint8_t length;']
else:
lines = [' uint32_t length;']
return [
'struct {'
] + lines + [
' uint8_t buf[{}];'.format(checker.maximum),
'}'
]

def format_bit_string(self, type_, checker):
def get_value(value):
byte = (length - 1) - (value // 8)
Expand Down Expand Up @@ -698,7 +715,6 @@ def generate(self, compiled):

if not type_declaration:
continue

declaration = self.generate_declaration()
definition_inner = self.generate_definition_inner(compiled_type)
definition = self.generate_definition()
Expand Down