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
6cd0d567
Commit
6cd0d567
authored
Aug 25, 2017
by
Lev Walkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
moved out common bit manipulation code
parent
1f4ed23a
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
520 additions
and
387 deletions
+520
-387
skeletons/Makefile.am
skeletons/Makefile.am
+1
-0
skeletons/OPEN_TYPE_oer.c
skeletons/OPEN_TYPE_oer.c
+86
-0
skeletons/asn_bit_data.c
skeletons/asn_bit_data.c
+308
-0
skeletons/asn_bit_data.h
skeletons/asn_bit_data.h
+78
-0
skeletons/constr_SEQUENCE_oer.c
skeletons/constr_SEQUENCE_oer.c
+23
-23
skeletons/file-dependencies
skeletons/file-dependencies
+1
-0
skeletons/per_encoder.c
skeletons/per_encoder.c
+2
-2
skeletons/per_opentype.c
skeletons/per_opentype.c
+5
-5
skeletons/per_support.c
skeletons/per_support.c
+0
-298
skeletons/per_support.h
skeletons/per_support.h
+12
-56
tests/tests-skeletons/check-PER-INTEGER.c
tests/tests-skeletons/check-PER-INTEGER.c
+1
-1
tests/tests-skeletons/check-PER.c
tests/tests-skeletons/check-PER.c
+3
-2
No files found.
skeletons/Makefile.am
View file @
6cd0d567
...
...
@@ -59,6 +59,7 @@ libasn1cskeletons_la_SOURCES = \
asn_application.h asn_codecs.h
\
asn_codecs_prim.c asn_codecs_prim.h
\
asn_internal.h asn_system.h
\
asn_bit_data.c asn_bit_data.h
\
ber_decoder.c ber_decoder.h
\
ber_tlv_length.c ber_tlv_length.h
\
ber_tlv_tag.c ber_tlv_tag.h
\
...
...
skeletons/OPEN_TYPE_oer.c
0 → 100644
View file @
6cd0d567
/*
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
#include <OPEN_TYPE.h>
#include <constr_CHOICE.h>
#include <oer_opentype.h>
#include <errno.h>
asn_dec_rval_t
OPEN_TYPE_oer_get
(
asn_codec_ctx_t
*
opt_codec_ctx
,
asn_TYPE_descriptor_t
*
td
,
void
*
sptr
,
asn_TYPE_member_t
*
elm
,
const
void
*
ptr
,
size_t
size
)
{
asn_type_selector_result_t
selected
;
void
*
memb_ptr
;
/* Pointer to the member */
void
**
memb_ptr2
;
/* Pointer to that pointer */
void
*
inner_value
;
asn_dec_rval_t
rv
;
size_t
ot_ret
;
if
(
!
(
elm
->
flags
&
ATF_OPEN_TYPE
)
||
!
elm
->
type_selector
)
{
ASN__DECODE_FAILED
;
}
selected
=
elm
->
type_selector
(
td
,
sptr
);
if
(
!
selected
.
presence_index
)
{
ASN__DECODE_FAILED
;
}
/* Fetch the pointer to this member */
if
(
elm
->
flags
&
ATF_POINTER
)
{
memb_ptr2
=
(
void
**
)((
char
*
)
sptr
+
elm
->
memb_offset
);
}
else
{
memb_ptr
=
(
char
*
)
sptr
+
elm
->
memb_offset
;
memb_ptr2
=
&
memb_ptr
;
}
if
(
*
memb_ptr2
!=
NULL
)
{
/* Make sure we reset the structure first before encoding */
if
(
CHOICE_variant_set_presence
(
selected
.
type_descriptor
,
*
memb_ptr2
,
0
)
!=
0
)
{
ASN__DECODE_FAILED
;
}
}
inner_value
=
(
char
*
)
*
memb_ptr2
+
elm
->
type
->
elements
[
selected
.
presence_index
-
1
].
memb_offset
;
ot_ret
=
oer_open_type_get
(
opt_codec_ctx
,
selected
.
type_descriptor
,
NULL
,
&
inner_value
,
ptr
,
size
);
switch
(
ot_ret
)
{
default:
if
(
CHOICE_variant_set_presence
(
selected
.
type_descriptor
,
*
memb_ptr2
,
selected
.
presence_index
)
==
0
)
{
rv
.
code
=
RC_OK
;
rv
.
consumed
=
ot_ret
;
return
rv
;
}
else
{
/* Oh, now a full-blown failure failure */
}
/* Fall through */
case
-
1
:
rv
.
code
=
RC_FAIL
;
rv
.
consumed
=
0
;
break
;
case
0
:
rv
.
code
=
RC_WMORE
;
rv
.
consumed
=
0
;
break
;
}
if
(
*
memb_ptr2
)
{
asn_CHOICE_specifics_t
*
specs
=
selected
.
type_descriptor
->
specifics
;
if
(
elm
->
flags
&
ATF_POINTER
)
{
ASN_STRUCT_FREE
(
*
selected
.
type_descriptor
,
inner_value
);
*
memb_ptr2
=
NULL
;
}
else
{
ASN_STRUCT_FREE_CONTENTS_ONLY
(
*
selected
.
type_descriptor
,
inner_value
);
memset
(
*
memb_ptr2
,
0
,
specs
->
struct_size
);
}
}
return
rv
;
}
skeletons/asn_bit_data.c
0 → 100644
View file @
6cd0d567
/*
* Copyright (c) 2005-2017 Lev Walkin <vlm@lionet.info>.
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_system.h>
#include <asn_internal.h>
#include <asn_bit_data.h>
char
*
asn_bit_data_string
(
asn_bit_data_t
*
pd
)
{
static
char
buf
[
2
][
32
];
static
int
n
;
n
=
(
n
+
1
)
%
2
;
snprintf
(
buf
[
n
],
sizeof
(
buf
[
n
]),
"{m=%ld span %+ld[%d..%d] (%d)}"
,
(
long
)
pd
->
moved
,
(((
long
)
pd
->
buffer
)
&
0xf
),
(
int
)
pd
->
nboff
,
(
int
)
pd
->
nbits
,
(
int
)(
pd
->
nbits
-
pd
->
nboff
));
return
buf
[
n
];
}
void
asn_get_undo
(
asn_bit_data_t
*
pd
,
int
nbits
)
{
if
((
ssize_t
)
pd
->
nboff
<
nbits
)
{
assert
((
ssize_t
)
pd
->
nboff
<
nbits
);
}
else
{
pd
->
nboff
-=
nbits
;
pd
->
moved
-=
nbits
;
}
}
/*
* Extract a small number of bits (<= 31) from the specified PER data pointer.
*/
int32_t
asn_get_few_bits
(
asn_bit_data_t
*
pd
,
int
nbits
)
{
size_t
off
;
/* Next after last bit offset */
ssize_t
nleft
;
/* Number of bits left in this stream */
uint32_t
accum
;
const
uint8_t
*
buf
;
if
(
nbits
<
0
)
return
-
1
;
nleft
=
pd
->
nbits
-
pd
->
nboff
;
if
(
nbits
>
nleft
)
{
int32_t
tailv
,
vhead
;
if
(
!
pd
->
refill
||
nbits
>
31
)
return
-
1
;
/* Accumulate unused bytes before refill */
ASN_DEBUG
(
"Obtain the rest %d bits (want %d)"
,
(
int
)
nleft
,
(
int
)
nbits
);
tailv
=
asn_get_few_bits
(
pd
,
nleft
);
if
(
tailv
<
0
)
return
-
1
;
/* Refill (replace pd contents with new data) */
if
(
pd
->
refill
(
pd
))
return
-
1
;
nbits
-=
nleft
;
vhead
=
asn_get_few_bits
(
pd
,
nbits
);
/* Combine the rest of previous pd with the head of new one */
tailv
=
(
tailv
<<
nbits
)
|
vhead
;
/* Could == -1 */
return
tailv
;
}
/*
* Normalize position indicator.
*/
if
(
pd
->
nboff
>=
8
)
{
pd
->
buffer
+=
(
pd
->
nboff
>>
3
);
pd
->
nbits
-=
(
pd
->
nboff
&
~
0x07
);
pd
->
nboff
&=
0x07
;
}
pd
->
moved
+=
nbits
;
pd
->
nboff
+=
nbits
;
off
=
pd
->
nboff
;
buf
=
pd
->
buffer
;
/*
* Extract specified number of bits.
*/
if
(
off
<=
8
)
accum
=
nbits
?
(
buf
[
0
])
>>
(
8
-
off
)
:
0
;
else
if
(
off
<=
16
)
accum
=
((
buf
[
0
]
<<
8
)
+
buf
[
1
])
>>
(
16
-
off
);
else
if
(
off
<=
24
)
accum
=
((
buf
[
0
]
<<
16
)
+
(
buf
[
1
]
<<
8
)
+
buf
[
2
])
>>
(
24
-
off
);
else
if
(
off
<=
31
)
accum
=
((
buf
[
0
]
<<
24
)
+
(
buf
[
1
]
<<
16
)
+
(
buf
[
2
]
<<
8
)
+
(
buf
[
3
]))
>>
(
32
-
off
);
else
if
(
nbits
<=
31
)
{
asn_bit_data_t
tpd
=
*
pd
;
/* Here are we with our 31-bits limit plus 1..7 bits offset. */
asn_get_undo
(
&
tpd
,
nbits
);
/* The number of available bits in the stream allow
* for the following operations to take place without
* invoking the ->refill() function */
accum
=
asn_get_few_bits
(
&
tpd
,
nbits
-
24
)
<<
24
;
accum
|=
asn_get_few_bits
(
&
tpd
,
24
);
}
else
{
asn_get_undo
(
pd
,
nbits
);
return
-
1
;
}
accum
&=
(((
uint32_t
)
1
<<
nbits
)
-
1
);
ASN_DEBUG
(
" [PER got %2d<=%2d bits => span %d %+ld[%d..%d]:%02x (%d) => 0x%x]"
,
(
int
)
nbits
,
(
int
)
nleft
,
(
int
)
pd
->
moved
,
(((
long
)
pd
->
buffer
)
&
0xf
),
(
int
)
pd
->
nboff
,
(
int
)
pd
->
nbits
,
((
pd
->
buffer
!=
NULL
)
?
pd
->
buffer
[
0
]
:
0
),
(
int
)(
pd
->
nbits
-
pd
->
nboff
),
(
int
)
accum
);
return
accum
;
}
/*
* Extract a large number of bits from the specified PER data pointer.
*/
int
asn_get_many_bits
(
asn_bit_data_t
*
pd
,
uint8_t
*
dst
,
int
alright
,
int
nbits
)
{
int32_t
value
;
if
(
alright
&&
(
nbits
&
7
))
{
/* Perform right alignment of a first few bits */
value
=
asn_get_few_bits
(
pd
,
nbits
&
0x07
);
if
(
value
<
0
)
return
-
1
;
*
dst
++
=
value
;
/* value is already right-aligned */
nbits
&=
~
7
;
}
while
(
nbits
)
{
if
(
nbits
>=
24
)
{
value
=
asn_get_few_bits
(
pd
,
24
);
if
(
value
<
0
)
return
-
1
;
*
(
dst
++
)
=
value
>>
16
;
*
(
dst
++
)
=
value
>>
8
;
*
(
dst
++
)
=
value
;
nbits
-=
24
;
}
else
{
value
=
asn_get_few_bits
(
pd
,
nbits
);
if
(
value
<
0
)
return
-
1
;
if
(
nbits
&
7
)
{
/* implies left alignment */
value
<<=
8
-
(
nbits
&
7
),
nbits
+=
8
-
(
nbits
&
7
);
if
(
nbits
>
24
)
*
dst
++
=
value
>>
24
;
}
if
(
nbits
>
16
)
*
dst
++
=
value
>>
16
;
if
(
nbits
>
8
)
*
dst
++
=
value
>>
8
;
*
dst
++
=
value
;
break
;
}
}
return
0
;
}
/*
* Put a small number of bits (<= 31).
*/
int
asn_put_few_bits
(
asn_bit_outp_t
*
po
,
uint32_t
bits
,
int
obits
)
{
size_t
off
;
/* Next after last bit offset */
size_t
omsk
;
/* Existing last byte meaningful bits mask */
uint8_t
*
buf
;
if
(
obits
<=
0
||
obits
>=
32
)
return
obits
?
-
1
:
0
;
ASN_DEBUG
(
"[PER put %d bits %x to %p+%d bits]"
,
obits
,
(
int
)
bits
,
po
->
buffer
,
(
int
)
po
->
nboff
);
/*
* Normalize position indicator.
*/
if
(
po
->
nboff
>=
8
)
{
po
->
buffer
+=
(
po
->
nboff
>>
3
);
po
->
nbits
-=
(
po
->
nboff
&
~
0x07
);
po
->
nboff
&=
0x07
;
}
/*
* Flush whole-bytes output, if necessary.
*/
if
(
po
->
nboff
+
obits
>
po
->
nbits
)
{
size_t
complete_bytes
;
if
(
!
po
->
buffer
)
po
->
buffer
=
po
->
tmpspace
;
complete_bytes
=
(
po
->
buffer
-
po
->
tmpspace
);
ASN_DEBUG
(
"[PER output %ld complete + %ld]"
,
(
long
)
complete_bytes
,
(
long
)
po
->
flushed_bytes
);
if
(
po
->
output
(
po
->
tmpspace
,
complete_bytes
,
po
->
op_key
)
<
0
)
return
-
1
;
if
(
po
->
nboff
)
po
->
tmpspace
[
0
]
=
po
->
buffer
[
0
];
po
->
buffer
=
po
->
tmpspace
;
po
->
nbits
=
8
*
sizeof
(
po
->
tmpspace
);
po
->
flushed_bytes
+=
complete_bytes
;
}
/*
* Now, due to sizeof(tmpspace), we are guaranteed large enough space.
*/
buf
=
po
->
buffer
;
omsk
=
~
((
1
<<
(
8
-
po
->
nboff
))
-
1
);
off
=
(
po
->
nboff
+
obits
);
/* Clear data of debris before meaningful bits */
bits
&=
(((
uint32_t
)
1
<<
obits
)
-
1
);
ASN_DEBUG
(
"[PER out %d %u/%x (t=%d,o=%d) %x&%x=%x]"
,
obits
,
(
int
)
bits
,
(
int
)
bits
,
(
int
)
po
->
nboff
,
(
int
)
off
,
buf
[
0
],
(
int
)(
omsk
&
0xff
),
(
int
)(
buf
[
0
]
&
omsk
));
if
(
off
<=
8
)
/* Completely within 1 byte */
po
->
nboff
=
off
,
bits
<<=
(
8
-
off
),
buf
[
0
]
=
(
buf
[
0
]
&
omsk
)
|
bits
;
else
if
(
off
<=
16
)
po
->
nboff
=
off
,
bits
<<=
(
16
-
off
),
buf
[
0
]
=
(
buf
[
0
]
&
omsk
)
|
(
bits
>>
8
),
buf
[
1
]
=
bits
;
else
if
(
off
<=
24
)
po
->
nboff
=
off
,
bits
<<=
(
24
-
off
),
buf
[
0
]
=
(
buf
[
0
]
&
omsk
)
|
(
bits
>>
16
),
buf
[
1
]
=
bits
>>
8
,
buf
[
2
]
=
bits
;
else
if
(
off
<=
31
)
po
->
nboff
=
off
,
bits
<<=
(
32
-
off
),
buf
[
0
]
=
(
buf
[
0
]
&
omsk
)
|
(
bits
>>
24
),
buf
[
1
]
=
bits
>>
16
,
buf
[
2
]
=
bits
>>
8
,
buf
[
3
]
=
bits
;
else
{
if
(
asn_put_few_bits
(
po
,
bits
>>
(
obits
-
24
),
24
))
return
-
1
;
if
(
asn_put_few_bits
(
po
,
bits
,
obits
-
24
))
return
-
1
;
}
ASN_DEBUG
(
"[PER out %u/%x => %02x buf+%ld]"
,
(
int
)
bits
,
(
int
)
bits
,
buf
[
0
],
(
long
)(
po
->
buffer
-
po
->
tmpspace
));
return
0
;
}
/*
* Output a large number of bits.
*/
int
asn_put_many_bits
(
asn_bit_outp_t
*
po
,
const
uint8_t
*
src
,
int
nbits
)
{
while
(
nbits
)
{
uint32_t
value
;
if
(
nbits
>=
24
)
{
value
=
(
src
[
0
]
<<
16
)
|
(
src
[
1
]
<<
8
)
|
src
[
2
];
src
+=
3
;
nbits
-=
24
;
if
(
asn_put_few_bits
(
po
,
value
,
24
))
return
-
1
;
}
else
{
value
=
src
[
0
];
if
(
nbits
>
8
)
value
=
(
value
<<
8
)
|
src
[
1
];
if
(
nbits
>
16
)
value
=
(
value
<<
8
)
|
src
[
2
];
if
(
nbits
&
0x07
)
value
>>=
(
8
-
(
nbits
&
0x07
));
if
(
asn_put_few_bits
(
po
,
value
,
nbits
))
return
-
1
;
break
;
}
}
return
0
;
}
int
asn_put_aligned_flush
(
asn_bit_outp_t
*
po
)
{
uint32_t
unused_bits
=
(
0x7
&
(
8
-
(
po
->
nboff
&
0x07
)));
size_t
complete_bytes
=
(
po
->
buffer
?
po
->
buffer
-
po
->
tmpspace
:
0
)
+
((
po
->
nboff
+
7
)
>>
3
);
if
(
unused_bits
)
{
po
->
buffer
[
po
->
nboff
>>
3
]
&=
~
0
<<
unused_bits
;
}
if
(
po
->
output
(
po
->
tmpspace
,
complete_bytes
,
po
->
op_key
)
<
0
)
{
return
-
1
;
}
else
{
po
->
buffer
=
po
->
tmpspace
;
po
->
nboff
=
0
;
po
->
nbits
=
8
*
sizeof
(
po
->
tmpspace
);
po
->
flushed_bytes
+=
complete_bytes
;
return
0
;
}
}
skeletons/asn_bit_data.h
0 → 100644
View file @
6cd0d567
/*
* Copyright (c) 2005-2017 Lev Walkin <vlm@lionet.info>.
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#ifndef ASN_BIT_DATA
#define ASN_BIT_DATA
#include <asn_system.h>
/* Platform-specific types */
#ifdef __cplusplus
extern
"C"
{
#endif
/*
* This structure describes a position inside an incoming PER bit stream.
*/
typedef
struct
asn_bit_data_s
{
const
uint8_t
*
buffer
;
/* Pointer to the octet stream */
size_t
nboff
;
/* Bit offset to the meaningful bit */
size_t
nbits
;
/* Number of bits in the stream */
size_t
moved
;
/* Number of bits moved through this bit stream */
int
(
*
refill
)(
struct
asn_bit_data_s
*
);
void
*
refill_key
;
}
asn_bit_data_t
;
/*
* Extract a small number of bits (<= 31) from the specified PER data pointer.
* This function returns -1 if the specified number of bits could not be
* extracted due to EOD or other conditions.
*/
int32_t
asn_get_few_bits
(
asn_bit_data_t
*
,
int
get_nbits
);
/* Undo the immediately preceeding "get_few_bits" operation */
void
asn_get_undo
(
asn_bit_data_t
*
,
int
get_nbits
);
/*
* Extract a large number of bits from the specified PER data pointer.
* This function returns -1 if the specified number of bits could not be
* extracted due to EOD or other conditions.
*/
int
asn_get_many_bits
(
asn_bit_data_t
*
,
uint8_t
*
dst
,
int
right_align
,
int
get_nbits
);
/* Non-thread-safe debugging function, don't use it */
char
*
asn_bit_data_string
(
asn_bit_data_t
*
);
/*
* This structure supports forming bit output.
*/
typedef
struct
asn_bit_outp_s
{
uint8_t
*
buffer
;
/* Pointer into the (tmpspace) */
size_t
nboff
;
/* Bit offset to the meaningful bit */
size_t
nbits
;
/* Number of bits left in (tmpspace) */
uint8_t
tmpspace
[
32
];
/* Preliminary storage to hold data */
int
(
*
output
)(
const
void
*
data
,
size_t
size
,
void
*
op_key
);
void
*
op_key
;
/* Key for (output) data callback */
size_t
flushed_bytes
;
/* Bytes already flushed through (output) */
}
asn_bit_outp_t
;
/* Output a small number of bits (<= 31) */
int
asn_put_few_bits
(
asn_bit_outp_t
*
,
uint32_t
bits
,
int
obits
);
/* Output a large number of bits */
int
asn_put_many_bits
(
asn_bit_outp_t
*
,
const
uint8_t
*
src
,
int
put_nbits
);
/*
* Flush whole bytes (0 or more) through (outper) member.
* The least significant bits which are not used are guaranteed to be set to 0.
* Returns -1 if callback returns -1. Otherwise, 0.
*/
int
asn_put_aligned_flush
(
asn_bit_outp_t
*
);
#ifdef __cplusplus
}
#endif
#endif
/* ASN_BIT_DATA */
skeletons/constr_SEQUENCE_oer.c
View file @
6cd0d567
...
...
@@ -98,7 +98,7 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
*/
ctx
=
(
asn_struct_ctx_t
*
)((
char
*
)
st
+
specs
->
ctx_offset
);
if
(
ctx
->
ptr
==
0
)
{
ctx
->
ptr
=
CALLOC
(
1
,
sizeof
(
asn_
per
_data_t
));
ctx
->
ptr
=
CALLOC
(
1
,
sizeof
(
asn_
bit
_data_t
));
if
(
!
ctx
->
ptr
)
{
RETURN
(
RC_FAIL
);
}
...
...
@@ -112,7 +112,7 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
/*
* Fetch preamble.
*/
asn_
per
_data_t
*
preamble
=
ctx
->
ptr
;
asn_
bit
_data_t
*
preamble
=
ctx
->
ptr
;
int
has_extensions_bit
=
(
specs
->
ext_before
>=
0
);
size_t
preamble_bits
=
(
has_extensions_bit
+
specs
->
roms_count
);
size_t
preamble_bytes
=
((
7
+
preamble_bits
)
>>
3
);
...
...
@@ -143,7 +143,7 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
/* FALL THROUGH */
case
1
:
{
/* Decode components of the extension root */
asn_
per
_data_t
*
preamble
=
ctx
->
ptr
;
asn_
bit
_data_t
*
preamble
=
ctx
->
ptr
;
size_t
edx
;
ASN_DEBUG
(
"OER SEQUENCE %s Decoding PHASE 1"
,
td
->
name
);
...
...
@@ -165,7 +165,7 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
}
if
(
elm
->
optional
)
{
int32_t
present
=
per
_get_few_bits
(
preamble
,
1
);
int32_t
present
=
asn
_get_few_bits
(
preamble
,
1
);
if
(
present
<
0
)
{
ASN_DEBUG
(
"Presence map ended prematurely: %d"
,
present
);
RETURN
(
RC_FAIL
);
...
...
@@ -226,8 +226,8 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
/* FALL THROUGH */
case
2
:
{
/* Cleanup preamble. */
asn_
per
_data_t
*
preamble
=
ctx
->
ptr
;
asn_
per
_data_t
*
extadds
;
asn_
bit
_data_t
*
preamble
=
ctx
->
ptr
;
asn_
bit
_data_t
*
extadds
;
int
has_extensions_bit
=
(
specs
->
ext_before
>=
0
);
int
extensions_present
=
has_extensions_bit
&&
(((
const
uint8_t
*
)
preamble
->
buffer
)[
0
]
&
0x80
);
...
...
@@ -303,12 +303,12 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
case
3
:
ASN_DEBUG
(
"OER SEQUENCE %s Decoding PHASE 3"
,
td
->
name
);
for
(;
ctx
->
step
<
specs
->
ext_before
-
1
;
ctx
->
step
++
)
{
asn_
per
_data_t
*
extadds
=
ctx
->
ptr
;
asn_
bit
_data_t
*
extadds
=
ctx
->
ptr
;
size_t
edx
=
ctx
->
step
;
asn_TYPE_member_t
*
elm
=
&
td
->
elements
[
edx
];
void
**
memb_ptr2
=
element_ptrptr
(
st
,
elm
);
switch
(
per
_get_few_bits
(
extadds
,
1
))
{
switch
(
asn
_get_few_bits
(
extadds
,
1
))
{
case
-
1
:
/*
* Not every one of our extensions is known to the remote side.
...
...
@@ -332,7 +332,7 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
RETURN
(
RC_FAIL
);
}
else
{
/* Roll back open type parsing */
per
_get_undo
(
extadds
,
1
);
asn
_get_undo
(
extadds
,
1
);
ASN_STRUCT_FREE
(
*
elm
->
type
,
*
memb_ptr2
);
*
memb_ptr2
=
NULL
;
RETURN
(
RC_WMORE
);
...
...
@@ -350,8 +350,8 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
ASN_DEBUG
(
"OER SEQUENCE %s Decoding PHASE 4"
,
td
->
name
);
/* Read in the rest of Open Types while ignoring them */
for
(;;)
{
asn_
per
_data_t
*
extadds
=
ctx
->
ptr
;
switch
(
per
_get_few_bits
(
extadds
,
1
))
{
asn_
bit
_data_t
*
extadds
=
ctx
->
ptr
;
switch
(
asn
_get_few_bits
(
extadds
,
1
))
{
case
0
:
continue
;
case
1
:
{
...
...
@@ -361,7 +361,7 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
}
else
if
(
skipped
<
0
)
{
RETURN
(
RC_FAIL
);
}
else
{
per
_get_undo
(
extadds
,
1
);
asn
_get_undo
(
extadds
,
1
);
RETURN
(
RC_WMORE
);
}
continue
;
...
...
@@ -397,10 +397,10 @@ SEQUENCE_encode_oer(asn_TYPE_descriptor_t *td,
(
void
)
constraints
;
if
(
preamble_bits
)
{
asn_
per
_outp_t
preamble
;
asn_
bit
_outp_t
preamble
;
memset
(
&
preamble
,
0
,
sizeof
(
preamble
));
preamble
.
outp
er
=
cb
;
preamble
.
outp
ut
=
cb
;
preamble
.
op_key
=
app_key
;
if
(
has_extensions_bit
)
{
...
...
@@ -412,7 +412,7 @@ SEQUENCE_encode_oer(asn_TYPE_descriptor_t *td,
break
;
}
}
ret
=
per
_put_few_bits
(
&
preamble
,
has_extensions
,
1
);
ret
=
asn
_put_few_bits
(
&
preamble
,
has_extensions
,
1
);
assert
(
ret
==
0
);
if
(
ret
<
0
)
{
ASN__ENCODE_FAILED
;
...
...
@@ -430,7 +430,7 @@ SEQUENCE_encode_oer(asn_TYPE_descriptor_t *td,
if
(
elm
->
optional
)
{
uint32_t
has_component
=
(
element_ptr
(
sptr
,
elm
)
!=
NULL
);
ret
=
per
_put_few_bits
(
&
preamble
,
has_component
,
1
);
ret
=
asn
_put_few_bits
(
&
preamble
,
has_component
,
1
);
if
(
ret
<
0
)
{
ASN__ENCODE_FAILED
;
}
...
...
@@ -438,7 +438,7 @@ SEQUENCE_encode_oer(asn_TYPE_descriptor_t *td,
}
}
per
_put_aligned_flush
(
&
preamble
);
asn
_put_aligned_flush
(
&
preamble
);
computed_size
+=
preamble
.
flushed_bytes
;
}
/* if(preamble_bits) */
...
...
@@ -477,7 +477,7 @@ SEQUENCE_encode_oer(asn_TYPE_descriptor_t *td,
# X.696 (08/2015) #16.4.
*/
if
(
has_extensions
)
{
asn_
per
_outp_t
extadds
;
asn_
bit
_outp_t
extadds
;
/* Special case allowing us to use exactly one byte for #8.6 */
size_t
aoms_length_bits
=
specs
->
aoms_count
;
...
...
@@ -487,15 +487,15 @@ SEQUENCE_encode_oer(asn_TYPE_descriptor_t *td,
assert
(
1
+
aoms_length_bytes
<=
127
);
memset
(
&
extadds
,
0
,
sizeof
(
extadds
));
extadds
.
outp
er
=
cb
;
extadds
.
outp
ut
=
cb
;
extadds
.
op_key
=
app_key
;
/* #8.6 length determinant */
ret
=
per
_put_few_bits
(
&
extadds
,
(
1
+
aoms_length_bytes
),
8
);
ret
=
asn
_put_few_bits
(
&
extadds
,
(
1
+
aoms_length_bytes
),
8
);
if
(
ret
<
0
)
ASN__ENCODE_FAILED
;
/* Number of unused bytes, #16.4.2 */
ret
=
per
_put_few_bits
(
&
extadds
,
unused_bits
,
8
);
ret
=
asn
_put_few_bits
(
&
extadds
,
unused_bits
,
8
);
if
(
ret
<
0
)
ASN__ENCODE_FAILED
;
/* Encode presence bitmap #16.4.3 */
...
...
@@ -503,11 +503,11 @@ SEQUENCE_encode_oer(asn_TYPE_descriptor_t *td,
edx
++
)
{
asn_TYPE_member_t
*
elm
=
&
td
->
elements
[
edx
];
void
*
memb_ptr
=
element_ptr
(
sptr
,
elm
);
ret
|=
per
_put_few_bits
(
&
extadds
,
memb_ptr
?
1
:
0
,
1
);
ret
|=
asn
_put_few_bits
(
&
extadds
,
memb_ptr
?
1
:
0
,
1
);
}
if
(
ret
<
0
)
ASN__ENCODE_FAILED
;
per
_put_aligned_flush
(
&
extadds
);
asn
_put_aligned_flush
(
&
extadds
);
computed_size
+=
extadds
.
flushed_bytes
;
/* Now, encode extensions */
...
...
skeletons/file-dependencies
View file @
6cd0d567
...
...
@@ -46,6 +46,7 @@ asn_ioc.h # Information Object Classes, runtime support
asn_system.h # Platform-dependent types
asn_codecs.h # Return types of encoders and decoders
asn_internal.h # Internal stuff
asn_bit_data.h asn_bit_data.c # Bit streaming support
OCTET_STRING.h OCTET_STRING.c # This one is used too widely
BIT_STRING.h BIT_STRING.c # This one is necessary for the above one
asn_codecs_prim.c asn_codecs_prim.h # enc/decoders for primitive types
...
...
skeletons/per_encoder.c
View file @
6cd0d567
...
...
@@ -114,7 +114,7 @@ _uper_encode_flush_outp(asn_per_outp_t *po) {
buf
++
;
}
return
po
->
outp
er
(
po
->
tmpspace
,
buf
-
po
->
tmpspace
,
po
->
op_key
);
return
po
->
outp
ut
(
po
->
tmpspace
,
buf
-
po
->
tmpspace
,
po
->
op_key
);
}
static
asn_enc_rval_t
...
...
@@ -133,7 +133,7 @@ uper_encode_internal(asn_TYPE_descriptor_t *td,
po
.
buffer
=
po
.
tmpspace
;
po
.
nboff
=
0
;
po
.
nbits
=
8
*
sizeof
(
po
.
tmpspace
);
po
.
outp
er
=
cb
;
po
.
outp
ut
=
cb
;
po
.
op_key
=
app_key
;
po
.
flushed_bytes
=
0
;
...
...
skeletons/per_opentype.c
View file @
6cd0d567
...
...
@@ -144,7 +144,7 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
ASN__STACK_OVERFLOW_CHECK
(
ctx
);
ASN_DEBUG
(
"Getting open type %s from %s"
,
td
->
name
,
per
_data_string
(
pd
));
asn_bit
_data_string
(
pd
));
arg
.
oldpd
=
*
pd
;
arg
.
unclaimed
=
0
;
arg
.
ot_moved
=
0
;
...
...
@@ -172,8 +172,8 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
}
ASN_DEBUG
(
"OpenType %s pd%s old%s unclaimed=%d, repeat=%d"
,
td
->
name
,
per
_data_string
(
pd
),
per
_data_string
(
&
arg
.
oldpd
),
asn_bit
_data_string
(
pd
),
asn_bit
_data_string
(
&
arg
.
oldpd
),
(
int
)
arg
.
unclaimed
,
(
int
)
arg
.
repeat
);
padding
=
pd
->
moved
%
8
;
...
...
@@ -204,7 +204,7 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
}
if
(
pd
->
nboff
!=
pd
->
nbits
)
{
ASN_DEBUG
(
"Open type %s overhead pd%s old%s"
,
td
->
name
,
per_data_string
(
pd
),
per
_data_string
(
&
arg
.
oldpd
));
asn_bit_data_string
(
pd
),
asn_bit
_data_string
(
&
arg
.
oldpd
));
if
(
1
)
{
UPDRESTOREPD
;
ASN__DECODE_FAILED
;
...
...
@@ -354,7 +354,7 @@ uper_ugot_refill(asn_per_data_t *pd) {
pd
->
buffer
=
oldpd
->
buffer
;
pd
->
nboff
=
oldpd
->
nboff
;
ASN_DEBUG
(
"Refilled pd%s old%s"
,
per_data_string
(
pd
),
per
_data_string
(
oldpd
));
asn_bit_data_string
(
pd
),
asn_bit
_data_string
(
oldpd
));
return
0
;
}
...
...
skeletons/per_support.c
View file @
6cd0d567
...
...
@@ -7,159 +7,6 @@
#include <asn_internal.h>
#include <per_support.h>
char
*
per_data_string
(
asn_per_data_t
*
pd
)
{
static
char
buf
[
2
][
32
];
static
int
n
;
n
=
(
n
+
1
)
%
2
;
snprintf
(
buf
[
n
],
sizeof
(
buf
[
n
]),
"{m=%ld span %+ld[%d..%d] (%d)}"
,
(
long
)
pd
->
moved
,
(((
long
)
pd
->
buffer
)
&
0xf
),
(
int
)
pd
->
nboff
,
(
int
)
pd
->
nbits
,
(
int
)(
pd
->
nbits
-
pd
->
nboff
));
return
buf
[
n
];
}
void
per_get_undo
(
asn_per_data_t
*
pd
,
int
nbits
)
{
if
((
ssize_t
)
pd
->
nboff
<
nbits
)
{
assert
((
ssize_t
)
pd
->
nboff
<
nbits
);
}
else
{
pd
->
nboff
-=
nbits
;
pd
->
moved
-=
nbits
;
}
}
/*
* Extract a small number of bits (<= 31) from the specified PER data pointer.
*/
int32_t
per_get_few_bits
(
asn_per_data_t
*
pd
,
int
nbits
)
{
size_t
off
;
/* Next after last bit offset */
ssize_t
nleft
;
/* Number of bits left in this stream */
uint32_t
accum
;
const
uint8_t
*
buf
;
if
(
nbits
<
0
)
return
-
1
;
nleft
=
pd
->
nbits
-
pd
->
nboff
;
if
(
nbits
>
nleft
)
{
int32_t
tailv
,
vhead
;
if
(
!
pd
->
refill
||
nbits
>
31
)
return
-
1
;
/* Accumulate unused bytes before refill */
ASN_DEBUG
(
"Obtain the rest %d bits (want %d)"
,
(
int
)
nleft
,
(
int
)
nbits
);
tailv
=
per_get_few_bits
(
pd
,
nleft
);
if
(
tailv
<
0
)
return
-
1
;
/* Refill (replace pd contents with new data) */
if
(
pd
->
refill
(
pd
))
return
-
1
;
nbits
-=
nleft
;
vhead
=
per_get_few_bits
(
pd
,
nbits
);
/* Combine the rest of previous pd with the head of new one */
tailv
=
(
tailv
<<
nbits
)
|
vhead
;
/* Could == -1 */
return
tailv
;
}
/*
* Normalize position indicator.
*/
if
(
pd
->
nboff
>=
8
)
{
pd
->
buffer
+=
(
pd
->
nboff
>>
3
);
pd
->
nbits
-=
(
pd
->
nboff
&
~
0x07
);
pd
->
nboff
&=
0x07
;
}
pd
->
moved
+=
nbits
;
pd
->
nboff
+=
nbits
;
off
=
pd
->
nboff
;
buf
=
pd
->
buffer
;
/*
* Extract specified number of bits.
*/
if
(
off
<=
8
)
accum
=
nbits
?
(
buf
[
0
])
>>
(
8
-
off
)
:
0
;
else
if
(
off
<=
16
)
accum
=
((
buf
[
0
]
<<
8
)
+
buf
[
1
])
>>
(
16
-
off
);
else
if
(
off
<=
24
)
accum
=
((
buf
[
0
]
<<
16
)
+
(
buf
[
1
]
<<
8
)
+
buf
[
2
])
>>
(
24
-
off
);
else
if
(
off
<=
31
)
accum
=
((
buf
[
0
]
<<
24
)
+
(
buf
[
1
]
<<
16
)
+
(
buf
[
2
]
<<
8
)
+
(
buf
[
3
]))
>>
(
32
-
off
);
else
if
(
nbits
<=
31
)
{
asn_per_data_t
tpd
=
*
pd
;
/* Here are we with our 31-bits limit plus 1..7 bits offset. */
per_get_undo
(
&
tpd
,
nbits
);
/* The number of available bits in the stream allow
* for the following operations to take place without
* invoking the ->refill() function */
accum
=
per_get_few_bits
(
&
tpd
,
nbits
-
24
)
<<
24
;
accum
|=
per_get_few_bits
(
&
tpd
,
24
);
}
else
{
per_get_undo
(
pd
,
nbits
);
return
-
1
;
}
accum
&=
(((
uint32_t
)
1
<<
nbits
)
-
1
);
ASN_DEBUG
(
" [PER got %2d<=%2d bits => span %d %+ld[%d..%d]:%02x (%d) => 0x%x]"
,
(
int
)
nbits
,
(
int
)
nleft
,
(
int
)
pd
->
moved
,
(((
long
)
pd
->
buffer
)
&
0xf
),
(
int
)
pd
->
nboff
,
(
int
)
pd
->
nbits
,
((
pd
->
buffer
!=
NULL
)
?
pd
->
buffer
[
0
]
:
0
),
(
int
)(
pd
->
nbits
-
pd
->
nboff
),
(
int
)
accum
);
return
accum
;
}
/*
* Extract a large number of bits from the specified PER data pointer.
*/
int
per_get_many_bits
(
asn_per_data_t
*
pd
,
uint8_t
*
dst
,
int
alright
,
int
nbits
)
{
int32_t
value
;
if
(
alright
&&
(
nbits
&
7
))
{
/* Perform right alignment of a first few bits */
value
=
per_get_few_bits
(
pd
,
nbits
&
0x07
);
if
(
value
<
0
)
return
-
1
;
*
dst
++
=
value
;
/* value is already right-aligned */
nbits
&=
~
7
;
}
while
(
nbits
)
{
if
(
nbits
>=
24
)
{
value
=
per_get_few_bits
(
pd
,
24
);
if
(
value
<
0
)
return
-
1
;
*
(
dst
++
)
=
value
>>
16
;
*
(
dst
++
)
=
value
>>
8
;
*
(
dst
++
)
=
value
;
nbits
-=
24
;
}
else
{
value
=
per_get_few_bits
(
pd
,
nbits
);
if
(
value
<
0
)
return
-
1
;
if
(
nbits
&
7
)
{
/* implies left alignment */
value
<<=
8
-
(
nbits
&
7
),
nbits
+=
8
-
(
nbits
&
7
);
if
(
nbits
>
24
)
*
dst
++
=
value
>>
24
;
}
if
(
nbits
>
16
)
*
dst
++
=
value
>>
16
;
if
(
nbits
>
8
)
*
dst
++
=
value
>>
8
;
*
dst
++
=
value
;
break
;
}
}
return
0
;
}
/*
* X.691-201508 #10.9 General rules for encoding a length determinant.
* Get the optionally constrained length "n" from the stream.
...
...
@@ -322,151 +169,6 @@ int uper_put_constrained_whole_number_u(asn_per_outp_t *po, unsigned long v, int
}
}
int
per_put_aligned_flush
(
asn_per_outp_t
*
po
)
{
uint32_t
unused_bits
=
(
0x7
&
(
8
-
(
po
->
nboff
&
0x07
)));
size_t
complete_bytes
=
(
po
->
buffer
?
po
->
buffer
-
po
->
tmpspace
:
0
)
+
((
po
->
nboff
+
7
)
>>
3
);
if
(
unused_bits
)
{
po
->
buffer
[
po
->
nboff
>>
3
]
&=
~
0
<<
unused_bits
;
}
if
(
po
->
outper
(
po
->
tmpspace
,
complete_bytes
,
po
->
op_key
)
<
0
)
{
return
-
1
;
}
else
{
po
->
buffer
=
po
->
tmpspace
;
po
->
nboff
=
0
;
po
->
nbits
=
8
*
sizeof
(
po
->
tmpspace
);
po
->
flushed_bytes
+=
complete_bytes
;
return
0
;
}
}
/*
* Put a small number of bits (<= 31).
*/
int
per_put_few_bits
(
asn_per_outp_t
*
po
,
uint32_t
bits
,
int
obits
)
{
size_t
off
;
/* Next after last bit offset */
size_t
omsk
;
/* Existing last byte meaningful bits mask */
uint8_t
*
buf
;
if
(
obits
<=
0
||
obits
>=
32
)
return
obits
?
-
1
:
0
;
ASN_DEBUG
(
"[PER put %d bits %x to %p+%d bits]"
,
obits
,
(
int
)
bits
,
po
->
buffer
,
(
int
)
po
->
nboff
);
/*
* Normalize position indicator.
*/
if
(
po
->
nboff
>=
8
)
{
po
->
buffer
+=
(
po
->
nboff
>>
3
);
po
->
nbits
-=
(
po
->
nboff
&
~
0x07
);
po
->
nboff
&=
0x07
;
}
/*
* Flush whole-bytes output, if necessary.
*/
if
(
po
->
nboff
+
obits
>
po
->
nbits
)
{
size_t
complete_bytes
;
if
(
!
po
->
buffer
)
po
->
buffer
=
po
->
tmpspace
;
complete_bytes
=
(
po
->
buffer
-
po
->
tmpspace
);
ASN_DEBUG
(
"[PER output %ld complete + %ld]"
,
(
long
)
complete_bytes
,
(
long
)
po
->
flushed_bytes
);
if
(
po
->
outper
(
po
->
tmpspace
,
complete_bytes
,
po
->
op_key
)
<
0
)
return
-
1
;
if
(
po
->
nboff
)
po
->
tmpspace
[
0
]
=
po
->
buffer
[
0
];
po
->
buffer
=
po
->
tmpspace
;
po
->
nbits
=
8
*
sizeof
(
po
->
tmpspace
);
po
->
flushed_bytes
+=
complete_bytes
;
}
/*
* Now, due to sizeof(tmpspace), we are guaranteed large enough space.
*/
buf
=
po
->
buffer
;
omsk
=
~
((
1
<<
(
8
-
po
->
nboff
))
-
1
);
off
=
(
po
->
nboff
+
obits
);
/* Clear data of debris before meaningful bits */
bits
&=
(((
uint32_t
)
1
<<
obits
)
-
1
);
ASN_DEBUG
(
"[PER out %d %u/%x (t=%d,o=%d) %x&%x=%x]"
,
obits
,
(
int
)
bits
,
(
int
)
bits
,
(
int
)
po
->
nboff
,
(
int
)
off
,
buf
[
0
],
(
int
)(
omsk
&
0xff
),
(
int
)(
buf
[
0
]
&
omsk
));
if
(
off
<=
8
)
/* Completely within 1 byte */
po
->
nboff
=
off
,
bits
<<=
(
8
-
off
),
buf
[
0
]
=
(
buf
[
0
]
&
omsk
)
|
bits
;
else
if
(
off
<=
16
)
po
->
nboff
=
off
,
bits
<<=
(
16
-
off
),
buf
[
0
]
=
(
buf
[
0
]
&
omsk
)
|
(
bits
>>
8
),
buf
[
1
]
=
bits
;
else
if
(
off
<=
24
)
po
->
nboff
=
off
,
bits
<<=
(
24
-
off
),
buf
[
0
]
=
(
buf
[
0
]
&
omsk
)
|
(
bits
>>
16
),
buf
[
1
]
=
bits
>>
8
,
buf
[
2
]
=
bits
;
else
if
(
off
<=
31
)
po
->
nboff
=
off
,
bits
<<=
(
32
-
off
),
buf
[
0
]
=
(
buf
[
0
]
&
omsk
)
|
(
bits
>>
24
),
buf
[
1
]
=
bits
>>
16
,
buf
[
2
]
=
bits
>>
8
,
buf
[
3
]
=
bits
;
else
{
if
(
per_put_few_bits
(
po
,
bits
>>
(
obits
-
24
),
24
))
return
-
1
;
if
(
per_put_few_bits
(
po
,
bits
,
obits
-
24
))
return
-
1
;
}
ASN_DEBUG
(
"[PER out %u/%x => %02x buf+%ld]"
,
(
int
)
bits
,
(
int
)
bits
,
buf
[
0
],
(
long
)(
po
->
buffer
-
po
->
tmpspace
));
return
0
;
}
/*
* Output a large number of bits.
*/
int
per_put_many_bits
(
asn_per_outp_t
*
po
,
const
uint8_t
*
src
,
int
nbits
)
{
while
(
nbits
)
{
uint32_t
value
;
if
(
nbits
>=
24
)
{
value
=
(
src
[
0
]
<<
16
)
|
(
src
[
1
]
<<
8
)
|
src
[
2
];
src
+=
3
;
nbits
-=
24
;
if
(
per_put_few_bits
(
po
,
value
,
24
))
return
-
1
;
}
else
{
value
=
src
[
0
];
if
(
nbits
>
8
)
value
=
(
value
<<
8
)
|
src
[
1
];
if
(
nbits
>
16
)
value
=
(
value
<<
8
)
|
src
[
2
];
if
(
nbits
&
0x07
)
value
>>=
(
8
-
(
nbits
&
0x07
));
if
(
per_put_few_bits
(
po
,
value
,
nbits
))
return
-
1
;
break
;
}
}
return
0
;
}
/*
* Put the length "n" (or part of it) into the stream.
*/
...
...
skeletons/per_support.h
View file @
6cd0d567
...
...
@@ -7,6 +7,7 @@
#define _PER_SUPPORT_H_
#include <asn_system.h>
/* Platform-specific types */
#include <asn_bit_data.h>
#ifdef __cplusplus
extern
"C"
{
...
...
@@ -34,35 +35,12 @@ typedef struct asn_per_constraints_s {
int
(
*
code2value
)(
unsigned
int
code
);
}
asn_per_constraints_t
;
/*
* This structure describes a position inside an incoming PER bit stream.
*/
typedef
struct
asn_per_data_s
{
const
uint8_t
*
buffer
;
/* Pointer to the octet stream */
size_t
nboff
;
/* Bit offset to the meaningful bit */
size_t
nbits
;
/* Number of bits in the stream */
size_t
moved
;
/* Number of bits moved through this bit stream */
int
(
*
refill
)(
struct
asn_per_data_s
*
);
void
*
refill_key
;
}
asn_per_data_t
;
/*
* Extract a small number of bits (<= 31) from the specified PER data pointer.
* This function returns -1 if the specified number of bits could not be
* extracted due to EOD or other conditions.
*/
int32_t
per_get_few_bits
(
asn_per_data_t
*
per_data
,
int
get_nbits
);
/* Undo the immediately preceeding "get_few_bits" operation */
void
per_get_undo
(
asn_per_data_t
*
per_data
,
int
get_nbits
);
/*
* Extract a large number of bits from the specified PER data pointer.
* This function returns -1 if the specified number of bits could not be
* extracted due to EOD or other conditions.
*/
int
per_get_many_bits
(
asn_per_data_t
*
pd
,
uint8_t
*
dst
,
int
right_align
,
int
get_nbits
);
/* Temporary compatibility layer. Will get removed. */
typedef
struct
asn_bit_data_s
asn_per_data_t
;
#define per_get_few_bits(data, bits) asn_get_few_bits(data, bits)
#define per_get_undo(data, bits) asn_get_undo(data, bits)
#define per_get_many_bits(data, dst, align, bits) \
asn_get_many_bits(data, dst, align, bits)
/*
* Get the length "n" from the Unaligned PER stream.
...
...
@@ -84,34 +62,12 @@ ssize_t uper_get_nsnnwn(asn_per_data_t *pd);
/* X.691-2008/11, #11.5.6 */
int
uper_get_constrained_whole_number
(
asn_per_data_t
*
pd
,
unsigned
long
*
v
,
int
nbits
);
/* Non-thread-safe debugging function, don't use it */
char
*
per_data_string
(
asn_per_data_t
*
pd
);
/*
* This structure supports forming PER output.
*/
typedef
struct
asn_per_outp_s
{
uint8_t
*
buffer
;
/* Pointer into the (tmpspace) */
size_t
nboff
;
/* Bit offset to the meaningful bit */
size_t
nbits
;
/* Number of bits left in (tmpspace) */
uint8_t
tmpspace
[
32
];
/* Preliminary storage to hold data */
int
(
*
outper
)(
const
void
*
data
,
size_t
size
,
void
*
op_key
);
void
*
op_key
;
/* Key for (outper) data callback */
size_t
flushed_bytes
;
/* Bytes already flushed through (outper) */
}
asn_per_outp_t
;
/* Output a small number of bits (<= 31) */
int
per_put_few_bits
(
asn_per_outp_t
*
per_data
,
uint32_t
bits
,
int
obits
);
/* Output a large number of bits */
int
per_put_many_bits
(
asn_per_outp_t
*
po
,
const
uint8_t
*
src
,
int
put_nbits
);
/*
* Flush whole bytes (0 or more) through (outper) member.
* The least significant bits which are not used are guaranteed to be set to 0.
* Returns -1 if callback returns -1. Otherwise, 0.
*/
int
per_put_aligned_flush
(
asn_per_outp_t
*
po
);
/* Temporary compatibility layer. Will get removed. */
typedef
struct
asn_bit_outp_s
asn_per_outp_t
;
#define per_put_few_bits(out, bits, obits) asn_put_few_bits(out, bits, obits)
#define per_put_many_bits(out, src, nbits) asn_put_many_bits(out, src, nbits)
#define per_put_aligned_flush(out) asn_put_aligned_flush(out)
/* X.691-2008/11, #11.5 */
int
uper_put_constrained_whole_number_s
(
asn_per_outp_t
*
po
,
long
v
,
int
nbits
);
...
...
tests/tests-skeletons/check-PER-INTEGER.c
View file @
6cd0d567
...
...
@@ -60,7 +60,7 @@ check_per_encode_constrained(int lineno, int unsigned_, long value, long lbound,
po
.
buffer
=
po
.
tmpspace
;
po
.
nboff
=
0
;
po
.
nbits
=
8
*
sizeof
(
po
.
tmpspace
);
po
.
outp
er
=
FailOut
;
po
.
outp
ut
=
FailOut
;
specs
.
field_width
=
sizeof
(
long
);
specs
.
field_unsigned
=
unsigned_
;
...
...
tests/tests-skeletons/check-PER.c
View file @
6cd0d567
#include <stdio.h>
#include <assert.h>
#include <asn_bit_data.c>
#include <per_support.c>
#include <per_support.h>
...
...
@@ -192,7 +193,7 @@ check_per_encoding() {
po
.
buffer
=
po
.
tmpspace
;
po
.
nboff
=
0
;
po
.
nbits
=
0
;
po
.
outp
er
=
Ignore
;
po
.
outp
ut
=
Ignore
;
po
.
op_key
=
0
;
po
.
tmpspace
[
0
]
=
0xff
;
...
...
@@ -285,7 +286,7 @@ check_per_encoding_auto() {
po
.
buffer
=
po
.
tmpspace
;
po
.
nboff
=
0
;
po
.
nbits
=
0
;
po
.
outp
er
=
Ignore
;
po
.
outp
ut
=
Ignore
;
po
.
op_key
=
0
;
po
.
tmpspace
[
0
]
=
0xff
;
...
...
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