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
Oct 23, 2017
by
Lev Walkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
abstract out sorting
parent
b2219ac6
Changes
1
Hide 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,42 +271,130 @@ 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
;
struct
_el_buffer
*
el_buf
=
(
struct
_el_buffer
*
)
el_buf_ptr
;
if
(
el_buf
->
length
+
size
>
el_buf
->
size
)
return
-
1
;
if
(
el_buf
->
length
+
size
>
el_buf
->
allocated_size
)
{
size_t
new_size
;
void
*
p
;
memcpy
(
el_buf
->
buf
+
el_buf
->
length
,
buffer
,
size
)
;
new_size
=
el_buf
->
allocated_size
?
2
*
el_buf
->
allocated_size
:
16
;
el_buf
->
length
+=
size
;
return
0
;
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
);
el_buf
->
length
+=
size
;
return
0
;
}
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
;
if
(
a
->
length
<
b
->
length
)
common_len
=
a
->
length
;
else
common_len
=
b
->
length
;
ret
=
memcmp
(
a
->
buf
,
b
->
buf
,
common_len
);
if
(
ret
==
0
)
{
if
(
a
->
length
<
b
->
length
)
ret
=
-
1
;
else
if
(
a
->
length
>
b
->
length
)
ret
=
1
;
const
struct
_el_buffer
*
a
=
(
const
struct
_el_buffer
*
)
ap
;
const
struct
_el_buffer
*
b
=
(
const
struct
_el_buffer
*
)
bp
;
size_t
common_len
;
int
ret
;
if
(
a
->
length
<
b
->
length
)
common_len
=
a
->
length
;
else
common_len
=
b
->
length
;
ret
=
memcmp
(
a
->
buf
,
b
->
buf
,
common_len
);
if
(
ret
==
0
)
{
if
(
a
->
length
<
b
->
length
)
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
;
}
return
ret
;
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,134 +403,78 @@ 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
;
ssize_t
encoding_size
=
0
;
struct
_el_buffer
*
encoded_els
;
int
edx
;
ASN_DEBUG
(
"Estimating size for SET OF %s"
,
td
->
name
);
/*
* Gather the length of the underlying members sequence.
*/
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
;
/* Compute maximum encoding's size */
if
(
max_encoded_len
<
(
size_t
)
erval
.
encoded
)
max_encoded_len
=
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
;
/*
* Gather the length of the underlying members sequence.
*/
for
(
edx
=
0
;
edx
<
list
->
count
;
edx
++
)
{
void
*
memb_ptr
=
list
->
array
[
edx
];
asn_enc_rval_t
erval
;
if
(
!
memb_ptr
)
ASN__ENCODE_FAILED
;
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
;
}
computed_size
+=
encoding_size
;
if
(
!
cb
||
list
->
count
==
0
)
{
erval
.
encoded
=
computed_size
;
ASN__ENCODED_OK
(
erval
);
}
/*
* 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
)
{
/*
* 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
<
0
)
{
ASN__ENCODE_FAILED
;
}
computed_size
+=
encoding_size
;
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
;
if
(
!
cb
||
list
->
count
==
0
)
{
asn_enc_rval_t
erval
;
erval
.
encoded
=
computed_size
;
ASN__ENCODED_OK
(
erval
);
}
/*
* 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
;
}
ASN_DEBUG
(
"Encoding members of %s SET OF"
,
td
->
name
);
/*
* 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
++
;
}
/*
* DER mandates dynamic sorting of the SET OF elements
* according to their encodings. Build an array of the
* encoded elements.
*/
encoded_els
=
SET_OF__encode_sorted
(
elm
,
list
,
SOES_DER
);
/*
* Sort the encoded elements according to their encoding.
*/
qsort
(
encoded_els
,
eels_count
,
sizeof
(
encoded_els
[
0
]),
_el_buf_cmp
);
/*
* Report encoded elements to the application.
* Dispose of temporary sorted members table.
*/
for
(
edx
=
0
;
edx
<
list
->
count
;
edx
++
)
{
struct
_el_buffer
*
encoded_el
=
&
encoded_els
[
edx
];
/* Report encoded chunks to the application */
if
(
cb
(
encoded_el
->
buf
,
encoded_el
->
length
,
app_key
)
<
0
)
{
break
;
}
else
{
encoding_size
+=
encoded_el
->
length
;
}
}
/*
* Report encoded elements to the application.
* Dispose of temporary sorted members table.
*/
ret
=
0
;
for
(
edx
=
0
;
edx
<
eels_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
);
}
FREEMEM
(
encoded_els
);
SET_OF__encode_sorted_free
(
encoded_els
,
list
->
count
);
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
{
erval
.
encoded
=
computed_size
;
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
;
}
}
...
...
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