ITS
NativeInteger.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
3  * All rights reserved.
4  * Redistribution and modifications are permitted subject to BSD license.
5  */
6 /*
7  * Read the NativeInteger.h for the explanation wrt. differences between
8  * INTEGER and NativeInteger.
9  * Basically, both are decoders and encoders of ASN.1 INTEGER type, but this
10  * implementation deals with the standard (machine-specific) representation
11  * of them instead of using the platform-independent buffer.
12  */
13 #include <asn_internal.h>
14 #include <NativeInteger.h>
15 
16 /*
17  * NativeInteger basic type description.
18  */
20  (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
21 };
23  "INTEGER", /* The ASN.1 type is still INTEGER */
24  "INTEGER",
32  NativeInteger_decode_uper, /* Unaligned PER decoder */
33  NativeInteger_encode_uper, /* Unaligned PER encoder */
34  0, /* Use generic outmost tag fetcher */
37  asn_DEF_NativeInteger_tags, /* Same as above */
39  0, /* No PER visible constraints */
40  0, 0, /* No members */
41  0 /* No specifics */
42 };
43 
44 /*
45  * Decode INTEGER type.
46  */
50  void **nint_ptr, const void *buf_ptr, size_t size, int tag_mode) {
52  long *native = (long *)*nint_ptr;
53  asn_dec_rval_t rval;
54  ber_tlv_len_t length;
55 
56  /*
57  * If the structure is not there, allocate it.
58  */
59  if(native == NULL) {
60  native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
61  if(native == NULL) {
62  rval.code = RC_FAIL;
63  rval.consumed = 0;
64  return rval;
65  }
66  }
67 
68  ASN_DEBUG("Decoding %s as INTEGER (tm=%d)",
69  td->name, tag_mode);
70 
71  /*
72  * Check tags.
73  */
74  rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
75  tag_mode, 0, &length, 0);
76  if(rval.code != RC_OK)
77  return rval;
78 
79  ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
80 
81  /*
82  * Make sure we have this length.
83  */
84  buf_ptr = ((const char *)buf_ptr) + rval.consumed;
85  size -= rval.consumed;
86  if(length > (ber_tlv_len_t)size) {
87  rval.code = RC_WMORE;
88  rval.consumed = 0;
89  return rval;
90  }
91 
92  /*
93  * ASN.1 encoded INTEGER: buf_ptr, length
94  * Fill the native, at the same time checking for overflow.
95  * If overflow occured, return with RC_FAIL.
96  */
97  {
98  INTEGER_t tmp;
99  union {
100  const void *constbuf;
101  void *nonconstbuf;
102  } unconst_buf;
103  long l;
104 
105  unconst_buf.constbuf = buf_ptr;
106  tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
107  tmp.size = length;
108 
109  if((specs&&specs->field_unsigned)
110  ? asn_INTEGER2ulong(&tmp, (unsigned long *)&l) /* sic */
111  : asn_INTEGER2long(&tmp, &l)) {
112  rval.code = RC_FAIL;
113  rval.consumed = 0;
114  return rval;
115  }
116 
117  *native = l;
118  }
119 
120  rval.code = RC_OK;
121  rval.consumed += length;
122 
123  ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)",
124  (long)rval.consumed, (long)length, td->name, (long)*native);
125 
126  return rval;
127 }
128 
129 /*
130  * Encode the NativeInteger using the standard INTEGER type DER encoder.
131  */
134  int tag_mode, ber_tlv_tag_t tag,
135  asn_app_consume_bytes_f *cb, void *app_key) {
136  unsigned long native = *(unsigned long *)ptr; /* Disable sign ext. */
137  asn_enc_rval_t erval;
138  INTEGER_t tmp;
139 
140 #ifdef WORDS_BIGENDIAN /* Opportunistic optimization */
141 
142  tmp.buf = (uint8_t *)&native;
143  tmp.size = sizeof(native);
144 
145 #else /* Works even if WORDS_BIGENDIAN is not set where should've been */
146  uint8_t buf[sizeof(native)];
147  uint8_t *p;
148 
149  /* Prepare a fake INTEGER */
150  for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
151  *p = (uint8_t)native;
152 
153  tmp.buf = buf;
154  tmp.size = sizeof(buf);
155 #endif /* WORDS_BIGENDIAN */
156 
157  /* Encode fake INTEGER */
158  erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key);
159  if(erval.encoded == -1) {
160  assert(erval.structure_ptr == &tmp);
161  erval.structure_ptr = ptr;
162  }
163  return erval;
164 }
165 
166 /*
167  * Decode the chunk of XML text encoding INTEGER.
168  */
171  asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
172  const void *buf_ptr, size_t size) {
174  asn_dec_rval_t rval;
175  INTEGER_t st;
176  void *st_ptr = (void *)&st;
177  long *native = (long *)*sptr;
178 
179  if(!native) {
180  native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
181  if(!native) _ASN_DECODE_FAILED;
182  }
183 
184  memset(&st, 0, sizeof(st));
185  rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr,
186  opt_mname, buf_ptr, size);
187  if(rval.code == RC_OK) {
188  long l;
189  if((specs&&specs->field_unsigned)
190  ? asn_INTEGER2ulong(&st, (unsigned long *)&l) /* sic */
191  : asn_INTEGER2long(&st, &l)) {
192  rval.code = RC_FAIL;
193  rval.consumed = 0;
194  } else {
195  *native = l;
196  }
197  } else {
198  /*
199  * Cannot restart from the middle;
200  * there is no place to save state in the native type.
201  * Request a continuation from the very beginning.
202  */
203  rval.consumed = 0;
204  }
206  return rval;
207 }
208 
209 
212  int ilevel, enum xer_encoder_flags_e flags,
213  asn_app_consume_bytes_f *cb, void *app_key) {
215  char scratch[32]; /* Enough for 64-bit int */
216  asn_enc_rval_t er;
217  const long *native = (const long *)sptr;
218 
219  (void)ilevel;
220  (void)flags;
221 
222  if(!native) _ASN_ENCODE_FAILED;
223 
224  er.encoded = snprintf(scratch, sizeof(scratch),
225  (specs && specs->field_unsigned)
226  ? "%lu" : "%ld", *native);
227  if(er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch)
228  || cb(scratch, er.encoded, app_key) < 0)
230 
231  _ASN_ENCODED_OK(er);
232 }
233 
237  asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
238 
240  asn_dec_rval_t rval;
241  long *native = (long *)*sptr;
242  INTEGER_t tmpint;
243  void *tmpintptr = &tmpint;
244 
245  (void)opt_codec_ctx;
246  ASN_DEBUG("Decoding NativeInteger %s (UPER)", td->name);
247 
248  if(!native) {
249  native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
250  if(!native) _ASN_DECODE_FAILED;
251  }
252 
253  memset(&tmpint, 0, sizeof tmpint);
254  rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints,
255  &tmpintptr, pd);
256  if(rval.code == RC_OK) {
257  if((specs&&specs->field_unsigned)
258  ? asn_INTEGER2ulong(&tmpint, (unsigned long *)native)
259  : asn_INTEGER2long(&tmpint, native))
260  rval.code = RC_FAIL;
261  else
262  ASN_DEBUG("NativeInteger %s got value %ld",
263  td->name, *native);
264  }
266 
267  return rval;
268 }
269 
272  asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
274  asn_enc_rval_t er;
275  long native;
276  INTEGER_t tmpint;
277 
278  if(!sptr) _ASN_ENCODE_FAILED;
279 
280  native = *(long *)sptr;
281 
282  ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native);
283 
284  memset(&tmpint, 0, sizeof(tmpint));
285  if((specs&&specs->field_unsigned)
286  ? asn_ulong2INTEGER(&tmpint, native)
287  : asn_long2INTEGER(&tmpint, native))
289  er = INTEGER_encode_uper(td, constraints, &tmpint, po);
291  return er;
292 }
293 
294 /*
295  * INTEGER specific human-readable output.
296  */
297 int
298 NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
299  asn_app_consume_bytes_f *cb, void *app_key) {
301  const long *native = (const long *)sptr;
302  char scratch[32]; /* Enough for 64-bit int */
303  int ret;
304 
305  (void)td; /* Unused argument */
306  (void)ilevel; /* Unused argument */
307 
308  if(native) {
309  ret = snprintf(scratch, sizeof(scratch),
310  (specs && specs->field_unsigned)
311  ? "%lu" : "%ld", *native);
312  assert(ret > 0 && (size_t)ret < sizeof(scratch));
313  return (cb(scratch, ret, app_key) < 0) ? -1 : 0;
314  } else {
315  return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
316  }
317 }
318 
319 void
320 NativeInteger_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
321 
322  if(!td || !ptr)
323  return;
324 
325  ASN_DEBUG("Freeing %s as INTEGER (%d, %p, Native)",
326  td->name, contents_only, ptr);
327 
328  if(!contents_only) {
329  FREEMEM(ptr);
330  }
331 }
332 
int asn_ulong2INTEGER(INTEGER_t *i, unsigned long l)
Definition: INTEGER.c:857
xer_type_decoder_f INTEGER_decode_xer
Definition: INTEGER.h:40
static ber_tlv_tag_t asn_DEF_NativeInteger_tags[]
Definition: NativeInteger.c:19
asn_TYPE_descriptor_t asn_DEF_NativeInteger
Definition: NativeInteger.c:22
void * structure_ptr
Definition: asn_codecs.h:58
asn_dec_rval_t NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd)
der_type_encoder_f INTEGER_encode_der
Definition: INTEGER.h:39
asn_enc_rval_t NativeInteger_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po)
asn_dec_rval_t NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **nint_ptr, const void *buf_ptr, size_t size, int tag_mode)
Definition: NativeInteger.c:48
void NativeInteger_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only)
per_type_encoder_f INTEGER_encode_uper
Definition: INTEGER.h:43
xer_encoder_flags_e
Definition: xer_encoder.h:17
asn_constr_check_f asn_generic_no_constraint
Definition: constraints.h:51
asn_enc_rval_t NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr, int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key)
ssize_t encoded
Definition: asn_codecs.h:48
int asn_long2INTEGER(INTEGER_t *i, long l)
Definition: INTEGER.c:882
ssize_t ber_tlv_len_t
#define ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr)
Definition: constr_TYPE.h:57
#define CALLOC(nmemb, size)
Definition: asn_internal.h:26
#define _ASN_ENCODED_OK(rval)
Definition: asn_codecs.h:68
int asn_INTEGER2ulong(const INTEGER_t *i, unsigned long *l)
Definition: INTEGER.c:825
asn_dec_rval_t ber_check_tags(struct asn_codec_ctx_s *opt_codec_ctx, struct asn_TYPE_descriptor_s *type_descriptor, asn_struct_ctx_t *opt_ctx, const void *ptr, size_t size, int tag_mode, int last_tag_form, ber_tlv_len_t *last_length, int *opt_tlv_form)
Definition: ber_decoder.c:65
#define FREEMEM(ptr)
Definition: asn_internal.h:29
int asn_INTEGER2long(const INTEGER_t *i, long *l)
Definition: INTEGER.c:765
#define _ASN_ENCODE_FAILED
Definition: asn_codecs.h:60
asn_enc_rval_t NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key)
int() asn_app_consume_bytes_f(const void *buffer, size_t size, void *application_specific_key)
size_t consumed
Definition: asn_codecs.h:89
enum asn_dec_rval_code_e code
Definition: asn_codecs.h:88
static void ASN_DEBUG(const char *fmt,...)
Definition: asn_internal.h:62
int NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, asn_app_consume_bytes_f *cb, void *app_key)
per_type_decoder_f INTEGER_decode_uper
Definition: INTEGER.h:42
asn_dec_rval_t NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname, const void *buf_ptr, size_t size)
asn_TYPE_descriptor_t asn_DEF_INTEGER
Definition: INTEGER.c:17
#define _ASN_DECODE_FAILED
Definition: asn_codecs.h:91
unsigned ber_tlv_tag_t
Definition: ber_tlv_tag.h:18