Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
asn1c
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
asn1c
Commits
005f8799
Commit
005f8799
authored
7 years ago
by
Lev Walkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
abstract out sorting
parent
b2219ac6
vlm_master
velichkov_s1ap_plus_option_group
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
167 additions
and
135 deletions
+167
-135
skeletons/constr_SET_OF.c
skeletons/constr_SET_OF.c
+167
-135
No files found.
skeletons/constr_SET_OF.c
View file @
005f8799
...
...
@@ -271,14 +271,27 @@ SET_OF_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
struct
_el_buffer
{
uint8_t
*
buf
;
size_t
length
;
size_t
size
;
size_t
allocated_size
;
unsigned
bits_unused
;
};
/* Append bytes to the above structure */
static
int
_el_addbytes
(
const
void
*
buffer
,
size_t
size
,
void
*
el_buf_ptr
)
{
struct
_el_buffer
*
el_buf
=
(
struct
_el_buffer
*
)
el_buf_ptr
;
if
(
el_buf
->
length
+
size
>
el_buf
->
size
)
if
(
el_buf
->
length
+
size
>
el_buf
->
allocated_size
)
{
size_t
new_size
;
void
*
p
;
new_size
=
el_buf
->
allocated_size
?
2
*
el_buf
->
allocated_size
:
16
;
p
=
REALLOC
(
el_buf
->
buf
,
new_size
);
if
(
p
)
{
el_buf
->
buf
=
p
;
el_buf
->
allocated_size
=
new_size
;
}
else
{
return
-
1
;
}
}
memcpy
(
el_buf
->
buf
+
el_buf
->
length
,
buffer
,
size
);
...
...
@@ -288,8 +301,8 @@ static int _el_addbytes(const void *buffer, size_t size, void *el_buf_ptr) {
static
int
_el_buf_cmp
(
const
void
*
ap
,
const
void
*
bp
)
{
const
struct
_el_buffer
*
a
=
(
const
struct
_el_buffer
*
)
ap
;
const
struct
_el_buffer
*
b
=
(
const
struct
_el_buffer
*
)
bp
;
int
ret
;
size_t
common_len
;
int
ret
;
if
(
a
->
length
<
b
->
length
)
common_len
=
a
->
length
;
...
...
@@ -302,11 +315,86 @@ static int _el_buf_cmp(const void *ap, const void *bp) {
ret
=
-
1
;
else
if
(
a
->
length
>
b
->
length
)
ret
=
1
;
/* Ignore unused bits. */
if
(
a
->
length
)
{
assert
((
a
->
buf
[
a
->
length
-
1
]
&
~
(
0xff
<<
a
->
bits_unused
))
==
0
);
assert
((
b
->
buf
[
b
->
length
-
1
]
&
~
(
0xff
<<
b
->
bits_unused
))
==
0
);
}
else
{
assert
(
a
->
bits_unused
==
0
);
assert
(
b
->
bits_unused
==
0
);
}
}
return
ret
;
}
static
void
SET_OF__encode_sorted_free
(
struct
_el_buffer
*
el_buf
,
size_t
count
)
{
size_t
i
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
FREEMEM
(
el_buf
[
i
].
buf
);
}
FREEMEM
(
el_buf
);
}
enum
SET_OF__encode_method
{
SOES_DER
};
static
struct
_el_buffer
*
SET_OF__encode_sorted
(
const
asn_TYPE_member_t
*
elm
,
const
asn_anonymous_set_
*
list
,
enum
SET_OF__encode_method
method
)
{
static
struct
_el_buffer
*
encoded_els
;
int
edx
;
encoded_els
=
(
struct
_el_buffer
*
)
CALLOC
(
list
->
count
,
sizeof
(
encoded_els
[
0
]));
if
(
encoded_els
==
NULL
)
{
return
NULL
;
}
/*
* Encode all members.
*/
for
(
edx
=
0
;
edx
<
list
->
count
;
edx
++
)
{
const
void
*
memb_ptr
=
list
->
array
[
edx
];
struct
_el_buffer
*
encoded_el
=
&
encoded_els
[
edx
];
asn_enc_rval_t
erval
;
if
(
!
memb_ptr
)
break
;
/*
* Encode the member into the prepared space.
*/
switch
(
method
)
{
case
SOES_DER
:
erval
=
elm
->
type
->
op
->
der_encoder
(
elm
->
type
,
memb_ptr
,
0
,
elm
->
tag
,
_el_addbytes
,
encoded_el
);
break
;
default:
assert
(
!
"Unreachable"
);
break
;
}
if
(
erval
.
encoded
<
0
)
break
;
}
if
(
edx
==
list
->
count
)
{
/*
* Sort the encoded elements according to their encoding.
*/
qsort
(
encoded_els
,
list
->
count
,
sizeof
(
encoded_els
[
0
]),
_el_buf_cmp
);
return
encoded_els
;
}
else
{
SET_OF__encode_sorted_free
(
encoded_els
,
edx
);
return
NULL
;
}
}
/*
* The DER encoder of the SET OF type.
*/
...
...
@@ -315,16 +403,10 @@ SET_OF_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr,
int
tag_mode
,
ber_tlv_tag_t
tag
,
asn_app_consume_bytes_f
*
cb
,
void
*
app_key
)
{
const
asn_TYPE_member_t
*
elm
=
td
->
elements
;
const
asn_TYPE_descriptor_t
*
elm_type
=
elm
->
type
;
der_type_encoder_f
*
der_encoder
=
elm_type
->
op
->
der_encoder
;
const
asn_anonymous_set_
*
list
=
_A_CSET_FROM_VOID
(
sptr
);
size_t
computed_size
=
0
;
ssize_t
encoding_size
=
0
;
struct
_el_buffer
*
encoded_els
;
ssize_t
eels_count
=
0
;
size_t
max_encoded_len
=
1
;
asn_enc_rval_t
erval
;
int
ret
;
int
edx
;
ASN_DEBUG
(
"Estimating size for SET OF %s"
,
td
->
name
);
...
...
@@ -334,115 +416,65 @@ SET_OF_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr,
*/
for
(
edx
=
0
;
edx
<
list
->
count
;
edx
++
)
{
void
*
memb_ptr
=
list
->
array
[
edx
];
if
(
!
memb_ptr
)
continue
;
erval
=
der_encoder
(
elm_type
,
memb_ptr
,
0
,
elm
->
tag
,
0
,
0
);
if
(
erval
.
encoded
==
-
1
)
return
erval
;
computed_size
+=
erval
.
encoded
;
asn_enc_rval_t
erval
;
if
(
!
memb_ptr
)
ASN__ENCODE_FAILED
;
/* Compute maximum encoding's size */
if
(
max_encoded_len
<
(
size_t
)
erval
.
encoded
)
max_encoded_len
=
erval
.
encoded
;
erval
=
elm
->
type
->
op
->
der_encoder
(
elm
->
type
,
memb_ptr
,
0
,
elm
->
tag
,
0
,
0
);
if
(
erval
.
encoded
==
-
1
)
return
erval
;
computed_size
+=
erval
.
encoded
;
}
/*
* Encode the TLV for the sequence itself.
*/
encoding_size
=
der_write_tags
(
td
,
computed_size
,
tag_mode
,
1
,
tag
,
cb
,
app_key
);
if
(
encoding_size
==
-
1
)
{
erval
.
encoded
=
-
1
;
erval
.
failed_type
=
td
;
erval
.
structure_ptr
=
sptr
;
return
erval
;
encoding_size
=
der_write_tags
(
td
,
computed_size
,
tag_mode
,
1
,
tag
,
cb
,
app_key
);
if
(
encoding_size
<
0
)
{
ASN__ENCODE_FAILED
;
}
computed_size
+=
encoding_size
;
if
(
!
cb
||
list
->
count
==
0
)
{
asn_enc_rval_t
erval
;
erval
.
encoded
=
computed_size
;
ASN__ENCODED_OK
(
erval
);
}
ASN_DEBUG
(
"Encoding members of %s SET OF"
,
td
->
name
);
/*
* DER mandates dynamic sorting of the SET OF elements
* according to their encodings. Build an array of the
* encoded elements.
*/
encoded_els
=
(
struct
_el_buffer
*
)
MALLOC
(
list
->
count
*
sizeof
(
encoded_els
[
0
]));
if
(
encoded_els
==
NULL
)
{
ASN__ENCODE_FAILED
;
}
ASN_DEBUG
(
"Encoding members of %s SET OF"
,
td
->
name
);
/*
* Encode all members.
*/
for
(
edx
=
0
;
edx
<
list
->
count
;
edx
++
)
{
const
void
*
memb_ptr
=
list
->
array
[
edx
];
struct
_el_buffer
*
encoded_el
=
&
encoded_els
[
eels_count
];
if
(
!
memb_ptr
)
continue
;
/*
* Prepare space for encoding.
*/
encoded_el
->
buf
=
(
uint8_t
*
)
MALLOC
(
max_encoded_len
);
if
(
encoded_el
->
buf
)
{
encoded_el
->
length
=
0
;
encoded_el
->
size
=
max_encoded_len
;
}
else
{
for
(
edx
--
;
edx
>=
0
;
edx
--
)
FREEMEM
(
encoded_els
[
edx
].
buf
);
FREEMEM
(
encoded_els
);
ASN__ENCODE_FAILED
;
}
/*
* Encode the member into the prepared space.
*/
erval
=
der_encoder
(
elm_type
,
memb_ptr
,
0
,
elm
->
tag
,
_el_addbytes
,
encoded_el
);
if
(
erval
.
encoded
==
-
1
)
{
for
(;
edx
>=
0
;
edx
--
)
FREEMEM
(
encoded_els
[
edx
].
buf
);
FREEMEM
(
encoded_els
);
return
erval
;
}
encoding_size
+=
erval
.
encoded
;
eels_count
++
;
}
/*
* Sort the encoded elements according to their encoding.
*/
qsort
(
encoded_els
,
eels_count
,
sizeof
(
encoded_els
[
0
]),
_el_buf_cmp
);
encoded_els
=
SET_OF__encode_sorted
(
elm
,
list
,
SOES_DER
);
/*
* Report encoded elements to the application.
* Dispose of temporary sorted members table.
*/
ret
=
0
;
for
(
edx
=
0
;
edx
<
eels_count
;
edx
++
)
{
for
(
edx
=
0
;
edx
<
list
->
count
;
edx
++
)
{
struct
_el_buffer
*
encoded_el
=
&
encoded_els
[
edx
];
/* Report encoded chunks to the application */
if
(
ret
==
0
&&
cb
(
encoded_el
->
buf
,
encoded_el
->
length
,
app_key
)
<
0
)
ret
=
-
1
;
FREEMEM
(
encoded_el
->
buf
);
if
(
cb
(
encoded_el
->
buf
,
encoded_el
->
length
,
app_key
)
<
0
)
{
break
;
}
else
{
encoding_size
+=
encoded_el
->
length
;
}
}
FREEMEM
(
encoded_els
);
if
(
ret
||
computed_size
!=
(
size_t
)
encoding_size
)
{
/*
* Standard callback failed, or
* encoded size is not equal to the computed size.
*/
ASN__ENCODE_FAILED
;
}
else
{
SET_OF__encode_sorted_free
(
encoded_els
,
list
->
count
);
if
(
edx
==
list
->
count
)
{
assert
(
computed_size
==
(
size_t
)
encoding_size
);
asn_enc_rval_t
erval
;
erval
.
encoded
=
computed_size
;
ASN__ENCODED_OK
(
erval
);
}
else
{
ASN__ENCODE_FAILED
;
}
}
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment