Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Havar
asn1c
Commits
d703ff45
Commit
d703ff45
authored
Oct 21, 2004
by
Lev Walkin
Browse files
XER decoding and asn_long2INTEGER()
parent
4fd7318e
Changes
2
Hide whitespace changes
Inline
Side-by-side
skeletons/INTEGER.c
View file @
d703ff45
/*-
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Copyright (c) 2003
, 2004
Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
#include <INTEGER.h>
#include <
ber
_codec_prim.h>
/* Encoder and decoder of a primitive */
#include <
asn
_codec
s
_prim.h>
/* Encoder and decoder of a primitive
type
*/
#include <assert.h>
#include <errno.h>
...
...
@@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_INTEGER = {
asn_generic_no_constraint
,
ber_decode_primitive
,
INTEGER_encode_der
,
0
,
/* Not implemented yet */
INTEGER_decode_xer
,
INTEGER_encode_xer
,
0
,
/* Use generic outmost tag fetcher */
asn_DEF_INTEGER_tags
,
...
...
@@ -176,6 +176,84 @@ INTEGER_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
return
(
ret
<
0
)
?
-
1
:
0
;
}
/*
* Decode the chunk of XML text encoding INTEGER.
*/
static
ssize_t
INTEGER__xer_body_decode
(
INTEGER_t
*
st
,
void
*
chunk_buf
,
size_t
chunk_size
)
{
long
sign
=
1
;
long
value
;
char
*
lstart
=
(
char
*
)
chunk_buf
;
char
*
lstop
=
chunk_buf
+
chunk_size
;
enum
{
ST_SKIPSPACE
,
ST_WAITDIGITS
,
ST_DIGITS
,
}
state
=
ST_SKIPSPACE
;
/*
* We may receive a tag here. But we aren't ready to deal with it yet.
* So, just use stroul()-like code and serialize the result.
*/
for
(
value
=
0
;
lstart
<
lstop
;
lstart
++
)
{
int
lv
=
*
lstart
;
switch
(
lv
)
{
case
0x09
:
case
0x0a
:
case
0x0d
:
case
0x20
:
if
(
state
==
ST_SKIPSPACE
)
continue
;
break
;
case
0x2d
:
/* '-' */
if
(
state
==
ST_SKIPSPACE
)
{
sign
=
-
1
;
state
=
ST_WAITDIGITS
;
continue
;
}
break
;
case
0x2b
:
/* '+' */
if
(
state
==
ST_SKIPSPACE
)
{
state
=
ST_WAITDIGITS
;
continue
;
}
break
;
case
0x30
:
case
0x31
:
case
0x32
:
case
0x33
:
case
0x34
:
case
0x35
:
case
0x36
:
case
0x37
:
case
0x38
:
case
0x39
:
if
(
state
!=
ST_DIGITS
)
state
=
ST_DIGITS
;
value
=
value
*
10
+
(
lv
-
0x30
);
/* Check for two's complement overflow */
if
(
value
<
0
)
{
/* Check whether it is a LONG_MIN */
if
(
sign
==
-
1
&&
value
==
~
((
unsigned
long
)
-
1
>>
1
))
{
sign
=
0
;
}
else
{
/* Overflow */
return
-
1
;
}
}
continue
;
}
}
if
(
state
!=
ST_DIGITS
)
return
-
1
;
/* No digits */
value
*=
sign
;
/* Change sign, if needed */
if
(
asn_long2INTEGER
(
st
,
value
))
return
-
1
;
return
lstop
-
lstart
;
}
asn_dec_rval_t
INTEGER_decode_xer
(
asn_codec_ctx_t
*
opt_codec_ctx
,
asn_TYPE_descriptor_t
*
td
,
void
**
sptr
,
const
char
*
opt_mname
,
void
*
buf_ptr
,
size_t
size
)
{
return
xer_decode_primitive
(
opt_codec_ctx
,
td
,
(
ASN__PRIMITIVE_TYPE_t
**
)
sptr
,
opt_mname
,
buf_ptr
,
size
,
INTEGER__xer_body_decode
);
}
asn_enc_rval_t
INTEGER_encode_xer
(
asn_TYPE_descriptor_t
*
td
,
void
*
sptr
,
int
ilevel
,
enum
xer_encoder_flags_e
flags
,
...
...
@@ -254,3 +332,48 @@ asn_INTEGER2long(const INTEGER_t *iptr, long *lptr) {
*
lptr
=
l
;
return
0
;
}
int
asn_long2INTEGER
(
INTEGER_t
*
st
,
long
value
)
{
uint8_t
*
buf
,
*
bp
;
uint8_t
*
p
;
uint8_t
*
pstart
;
uint8_t
*
pend1
;
if
(
!
st
)
{
errno
=
EINVAL
;
return
-
1
;
}
buf
=
MALLOC
(
sizeof
(
value
));
if
(
!
buf
)
return
-
1
;
pstart
=
(
uint8_t
*
)
&
value
;
pend1
=
pstart
+
sizeof
(
value
)
-
1
;
/*
* If the contents octet consists of more than one octet,
* then bits of the first octet and bit 8 of the second octet:
* a) shall not all be ones; and
* b) shall not all be zero.
*/
for
(
p
=
pstart
;
p
<
pend1
;
p
++
)
{
switch
(
*
p
)
{
case
0x00
:
if
((
p
[
1
]
&
0x80
)
==
0
)
continue
;
break
;
case
0xff
:
if
((
p
[
1
]
&
0x80
))
continue
;
break
;
}
break
;
}
/* Copy the integer body */
for
(
pstart
=
p
,
bp
=
buf
;
p
<=
pend1
;)
*
bp
++
=
*
p
++
;
if
(
st
->
buf
)
FREEMEM
(
st
->
buf
);
st
->
buf
=
buf
;
st
->
size
=
p
-
pstart
;
return
0
;
}
skeletons/INTEGER.h
View file @
d703ff45
...
...
@@ -6,7 +6,7 @@
#define _INTEGER_H_
#include <asn_application.h>
#include <
ber
_codec_prim.h>
#include <
asn
_codec
s
_prim.h>
typedef
ASN__PRIMITIVE_TYPE_t
INTEGER_t
;
...
...
@@ -15,6 +15,7 @@ extern asn_TYPE_descriptor_t asn_DEF_INTEGER;
asn_struct_print_f
INTEGER_print
;
ber_type_decoder_f
INTEGER_decode_ber
;
der_type_encoder_f
INTEGER_encode_der
;
xer_type_decoder_f
INTEGER_decode_xer
;
xer_type_encoder_f
INTEGER_encode_xer
;
/***********************************
...
...
@@ -25,7 +26,9 @@ xer_type_encoder_f INTEGER_encode_xer;
* Returns 0 if it was possible to convert, -1 otherwise.
* -1/EINVAL: Mandatory argument missing
* -1/ERANGE: Value encoded is out of range for long representation
* -1/ENOMEM: Memory allocation failed (in asn_long2INTEGER()).
*/
int
asn_INTEGER2long
(
const
INTEGER_t
*
i
,
long
*
l
);
int
asn_long2INTEGER
(
INTEGER_t
*
i
,
long
l
);
#endif
/* _INTEGER_H_ */
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