ITS
NativeEnumerated.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2004, 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
3  * Redistribution and modifications are permitted subject to BSD license.
4  */
5 /*
6  * Read the NativeInteger.h for the explanation wrt. differences between
7  * INTEGER and NativeInteger.
8  * Basically, both are decoders and encoders of ASN.1 INTEGER type, but this
9  * implementation deals with the standard (machine-specific) representation
10  * of them instead of using the platform-independent buffer.
11  */
12 #include <asn_internal.h>
13 #include <NativeEnumerated.h>
14 
15 /*
16  * NativeEnumerated basic type description.
17  */
19  (ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
20 };
22  "ENUMERATED", /* The ASN.1 type is still ENUMERATED */
23  "ENUMERATED",
33  0, /* Use generic outmost tag fetcher */
36  asn_DEF_NativeEnumerated_tags, /* Same as above */
38  0, /* No PER visible constraints */
39  0, 0, /* No members */
40  0 /* No specifics */
41 };
42 
45  int ilevel, enum xer_encoder_flags_e flags,
46  asn_app_consume_bytes_f *cb, void *app_key) {
48  asn_enc_rval_t er;
49  const long *native = (const long *)sptr;
50  const asn_INTEGER_enum_map_t *el;
51 
52  (void)ilevel;
53  (void)flags;
54 
55  if(!native) _ASN_ENCODE_FAILED;
56 
57  el = INTEGER_map_value2enum(specs, *native);
58  if(el) {
59  size_t srcsize = el->enum_len + 5;
60  char *src = (char *)alloca(srcsize);
61 
62  er.encoded = snprintf(src, srcsize, "<%s/>", el->enum_name);
63  assert(er.encoded > 0 && (size_t)er.encoded < srcsize);
64  if(cb(src, er.encoded, app_key) < 0) _ASN_ENCODE_FAILED;
65  _ASN_ENCODED_OK(er);
66  } else {
67  ASN_DEBUG("ASN.1 forbids dealing with "
68  "unknown value of ENUMERATED type");
70  }
71 }
72 
76  void **sptr, asn_per_data_t *pd) {
78  asn_dec_rval_t rval = { RC_OK, 0 };
79  long *native = (long *)*sptr;
81  long value;
82 
83  (void)opt_codec_ctx;
84 
85  if(constraints) ct = &constraints->value;
86  else if(td->per_constraints) ct = &td->per_constraints->value;
87  else _ASN_DECODE_FAILED; /* Mandatory! */
88  if(!specs) _ASN_DECODE_FAILED;
89 
90  if(!native) {
91  native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
92  if(!native) _ASN_DECODE_FAILED;
93  }
94 
95  ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
96 
97  if(ct->flags & APC_EXTENSIBLE) {
98  int inext = per_get_few_bits(pd, 1);
99  if(inext < 0) _ASN_DECODE_STARVED;
100  if(inext) ct = 0;
101  }
102 
103  if(ct && ct->range_bits >= 0) {
104  value = per_get_few_bits(pd, ct->range_bits);
105  if(value < 0) _ASN_DECODE_STARVED;
106  if(value >= (specs->extension
107  ? specs->extension - 1 : specs->map_count))
109  } else {
110  if(!specs->extension)
112  /*
113  * X.691, #10.6: normally small non-negative whole number;
114  */
115  value = uper_get_nsnnwn(pd);
116  if(value < 0) _ASN_DECODE_STARVED;
117  value += specs->extension - 1;
118  if(value >= specs->map_count)
120  }
121 
122  *native = specs->value2enum[value].nat_value;
123  ASN_DEBUG("Decoded %s = %ld", td->name, *native);
124 
125  return rval;
126 }
127 
128 static int
129 NativeEnumerated__compar_value2enum(const void *ap, const void *bp) {
130  const asn_INTEGER_enum_map_t *a = ap;
131  const asn_INTEGER_enum_map_t *b = bp;
132  if(a->nat_value == b->nat_value)
133  return 0;
134  if(a->nat_value < b->nat_value)
135  return -1;
136  return 1;
137 }
138 
141  asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
143  asn_enc_rval_t er;
144  long native, value;
146  int inext = 0;
149 
150  if(!sptr) _ASN_ENCODE_FAILED;
151  if(!specs) _ASN_ENCODE_FAILED;
152 
153  if(constraints) ct = &constraints->value;
154  else if(td->per_constraints) ct = &td->per_constraints->value;
155  else _ASN_ENCODE_FAILED; /* Mandatory! */
156 
157  ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
158 
159  er.encoded = 0;
160 
161  native = *(long *)sptr;
162  if(native < 0) _ASN_ENCODE_FAILED;
163 
164  key.nat_value = native;
165  kf = bsearch(&key, specs->value2enum, specs->map_count,
167  if(!kf) {
168  ASN_DEBUG("No element corresponds to %ld", native);
170  }
171  value = kf - specs->value2enum;
172 
173  if(ct->range_bits >= 0) {
174  int cmpWith = specs->extension
175  ? specs->extension - 1 : specs->map_count;
176  if(value >= cmpWith)
177  inext = 1;
178  }
179  if(ct->flags & APC_EXTENSIBLE) {
180  if(per_put_few_bits(po, inext, 1))
182  if(inext) ct = 0;
183  } else if(inext) {
185  }
186 
187  if(ct && ct->range_bits >= 0) {
188  if(per_put_few_bits(po, value, ct->range_bits))
190  _ASN_ENCODED_OK(er);
191  }
192 
193  if(!specs->extension)
195 
196  /*
197  * X.691, #10.6: normally small non-negative whole number;
198  */
199  ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld",
200  value, specs->extension, inext,
201  value - (inext ? (specs->extension - 1) : 0));
202  if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0)))
204 
205  _ASN_ENCODED_OK(er);
206 }
207 
static int NativeEnumerated__compar_value2enum(const void *ap, const void *bp)
#define _ASN_DECODE_STARVED
Definition: asn_codecs.h:98
enum asn_per_constraint_s::asn_per_constraint_flags flags
xer_type_decoder_f NativeInteger_decode_xer
Definition: NativeInteger.h:28
int per_put_few_bits(asn_per_outp_t *per_data, uint32_t bits, int obits)
Definition: per_support.c:323
const asn_INTEGER_enum_map_t * INTEGER_map_value2enum(asn_INTEGER_specifics_t *specs, long value)
Definition: INTEGER.c:282
xer_encoder_flags_e
Definition: xer_encoder.h:17
asn_constr_check_f asn_generic_no_constraint
Definition: constraints.h:51
int uper_put_nsnnwn(asn_per_outp_t *po, int n)
Definition: per_support.c:245
asn_per_constraint_t value
Definition: per_support.h:31
#define CALLOC(nmemb, size)
Definition: asn_internal.h:26
#define _ASN_ENCODED_OK(rval)
Definition: asn_codecs.h:68
static ber_tlv_tag_t asn_DEF_NativeEnumerated_tags[]
ber_type_decoder_f NativeInteger_decode_ber
Definition: NativeInteger.h:26
#define _ASN_ENCODE_FAILED
Definition: asn_codecs.h:60
asn_enc_rval_t NativeEnumerated_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)
asn_TYPE_descriptor_t asn_DEF_NativeEnumerated
int() asn_app_consume_bytes_f(const void *buffer, size_t size, void *application_specific_key)
asn_dec_rval_t NativeEnumerated_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)
int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits)
Definition: per_support.c:38
static void ASN_DEBUG(const char *fmt,...)
Definition: asn_internal.h:62
asn_struct_print_f NativeInteger_print
Definition: NativeInteger.h:25
const char * enum_name
Definition: INTEGER.h:23
ssize_t uper_get_nsnnwn(asn_per_data_t *pd)
Definition: per_support.c:219
asn_per_constraints_t * per_constraints
Definition: constr_TYPE.h:116
der_type_encoder_f NativeInteger_encode_der
Definition: NativeInteger.h:27
asn_INTEGER_enum_map_t * value2enum
Definition: INTEGER.h:28
asn_struct_free_f NativeInteger_free
Definition: NativeInteger.h:24
asn_enc_rval_t NativeEnumerated_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po)
#define _ASN_DECODE_FAILED
Definition: asn_codecs.h:91
unsigned ber_tlv_tag_t
Definition: ber_tlv_tag.h:18