constr_SET_OF.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
3  * All rights reserved.
4  * Redistribution and modifications are permitted subject to BSD license.
5  */
8 
11 #if !defined(ASN_DISABLE_PRINT_SUPPORT)
13 #else
14  0,
15 #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
18 #if !defined(ASN_DISABLE_BER_SUPPORT)
21 #else
22  0,
23  0,
24 #endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
25 #if !defined(ASN_DISABLE_XER_SUPPORT)
28 #else
29  0,
30  0,
31 #endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
32 #if !defined(ASN_DISABLE_JER_SUPPORT)
35 #else
36  0,
37  0,
38 #endif /* !defined(ASN_DISABLE_JER_SUPPORT) */
39 #if !defined(ASN_DISABLE_OER_SUPPORT)
42 #else
43  0,
44  0,
45 #endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
46 #if !defined(ASN_DISABLE_UPER_SUPPORT)
49 #else
50  0,
51  0,
52 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
53 #if !defined(ASN_DISABLE_APER_SUPPORT)
56 #else
57  0,
58  0,
59 #endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
60 #if !defined(ASN_DISABLE_RFILL_SUPPORT)
62 #else
63  0,
64 #endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
65  0 /* Use generic outmost tag fetcher */
66 };
67 
68 /* Append bytes to the above structure */
69 static int _el_addbytes(const void *buffer, size_t size, void *el_buf_ptr) {
70  struct _el_buffer *el_buf = (struct _el_buffer *)el_buf_ptr;
71 
72  if(el_buf->length + size > el_buf->allocated_size) {
73  size_t new_size = el_buf->allocated_size ? el_buf->allocated_size : 8;
74  void *p;
75 
76  do {
77  new_size <<= 2;
78  } while(el_buf->length + size > new_size);
79 
80  p = REALLOC(el_buf->buf, new_size);
81  if(p) {
82  el_buf->buf = p;
83  el_buf->allocated_size = new_size;
84  } else {
85  return -1;
86  }
87  }
88 
89  memcpy(el_buf->buf + el_buf->length, buffer, size);
90 
91  el_buf->length += size;
92  return 0;
93 }
94 
95 static void assert_unused_bits(const struct _el_buffer* p) {
96  if(p->length) {
97  assert((p->buf[p->length-1] & ~(0xff << p->bits_unused)) == 0);
98  } else {
99  assert(p->bits_unused == 0);
100  }
101 }
102 
103 static int _el_buf_cmp(const void *ap, const void *bp) {
104  const struct _el_buffer *a = (const struct _el_buffer *)ap;
105  const struct _el_buffer *b = (const struct _el_buffer *)bp;
106  size_t common_len;
107  int ret = 0;
108 
109  if(a->length < b->length)
110  common_len = a->length;
111  else
112  common_len = b->length;
113 
114  if (a->buf && b->buf) {
115  ret = memcmp(a->buf, b->buf, common_len);
116  }
117  if(ret == 0) {
118  if(a->length < b->length)
119  ret = -1;
120  else if(a->length > b->length)
121  ret = 1;
122  /* Ignore unused bits. */
125  }
126 
127  return ret;
128 }
129 
130 void
131 SET_OF__encode_sorted_free(struct _el_buffer *el_buf, size_t count) {
132  size_t i;
133 
134  for(i = 0; i < count; i++) {
135  FREEMEM(el_buf[i].buf);
136  }
137 
138  FREEMEM(el_buf);
139 }
140 
141 struct _el_buffer *
143  const asn_anonymous_set_ *list,
144  enum SET_OF__encode_method method) {
145  struct _el_buffer *encoded_els;
146  int edx;
147 
148  encoded_els =
149  (struct _el_buffer *)CALLOC(list->count, sizeof(encoded_els[0]));
150  if(encoded_els == NULL) {
151  return NULL;
152  }
153 
154  /*
155  * Encode all members.
156  */
157  for(edx = 0; edx < list->count; edx++) {
158  const void *memb_ptr = list->array[edx];
159  struct _el_buffer *encoding_el = &encoded_els[edx];
160  asn_enc_rval_t erval = {0,0,0};
161 
162  if(!memb_ptr) break;
163 
164  /*
165  * Encode the member into the prepared space.
166  */
167  switch(method) {
168 #if !defined(ASN_DISABLE_BER_SUPPORT)
169  case SOES_DER:
170  erval = elm->type->op->der_encoder(elm->type, memb_ptr, elm->tag_mode, elm->tag,
171  _el_addbytes, encoding_el);
172  break;
173 #endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
174 #if !defined(ASN_DISABLE_UPER_SUPPORT)
175  case SOES_CUPER:
176  erval = uper_encode(elm->type,
178  memb_ptr, _el_addbytes, encoding_el);
179  if(erval.encoded != -1) {
180  size_t extra_bits = erval.encoded % 8;
181  assert(encoding_el->length == (size_t)(erval.encoded + 7) / 8);
182  encoding_el->bits_unused = (8 - extra_bits) & 0x7;
183  }
184  break;
185 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
186 #if !defined(ASN_DISABLE_APER_SUPPORT)
187  case SOES_CAPER:
188  erval = aper_encode(elm->type,
190  memb_ptr, _el_addbytes, encoding_el);
191  if(erval.encoded != -1) {
192  size_t extra_bits = erval.encoded % 8;
193  assert(encoding_el->length == (size_t)(erval.encoded + 7) / 8);
194  encoding_el->bits_unused = (8 - extra_bits) & 0x7;
195  }
196  break;
197 #endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
198 
199  default:
200  assert(!"Unreachable");
201  break;
202  }
203  if(erval.encoded < 0) break;
204  }
205 
206  if(edx == list->count) {
207  /*
208  * Sort the encoded elements according to their encoding.
209  */
210  qsort(encoded_els, list->count, sizeof(encoded_els[0]), _el_buf_cmp);
211 
212  return encoded_els;
213  } else {
214  SET_OF__encode_sorted_free(encoded_els, edx);
215  return NULL;
216  }
217 }
218 
219 void
220 SET_OF_free(const asn_TYPE_descriptor_t *td, void *ptr,
221  enum asn_struct_free_method method) {
222  if(td && ptr) {
223  const asn_SET_OF_specifics_t *specs;
224  asn_TYPE_member_t *elm = td->elements;
225  asn_anonymous_set_ *list = _A_SET_FROM_VOID(ptr);
226  asn_struct_ctx_t *ctx; /* Decoder context */
227  int i;
228 
229  /*
230  * Could not use set_of_empty() because of (*free)
231  * incompatibility.
232  */
233  for(i = 0; i < list->count; i++) {
234  void *memb_ptr = list->array[i];
235  if(memb_ptr)
236  ASN_STRUCT_FREE(*elm->type, memb_ptr);
237  }
238  list->count = 0; /* No meaningful elements left */
239 
240  asn_set_empty(list); /* Remove (list->array) */
241 
242  specs = (const asn_SET_OF_specifics_t *)td->specifics;
243  ctx = (asn_struct_ctx_t *)((char *)ptr + specs->ctx_offset);
244  if(ctx->ptr) {
245  ASN_STRUCT_FREE(*elm->type, ctx->ptr);
246  ctx->ptr = 0;
247  }
248 
249  switch(method) {
251  FREEMEM(ptr);
252  break;
254  break;
256  memset(ptr, 0, specs->struct_size);
257  break;
258  }
259  }
260 }
261 
262 int
263 SET_OF_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
264  asn_app_constraint_failed_f *ctfailcb, void *app_key) {
265  const asn_TYPE_member_t *elm = td->elements;
266  asn_constr_check_f *constr;
267  const asn_anonymous_set_ *list = _A_CSET_FROM_VOID(sptr);
268  int i;
269 
270  if(!sptr) {
271  ASN__CTFAIL(app_key, td, sptr,
272  "%s: value not given (%s:%d)",
273  td->name, __FILE__, __LINE__);
274  return -1;
275  }
276 
278  if(!constr) constr = elm->type->encoding_constraints.general_constraints;
279 
280  /*
281  * Iterate over the members of an array.
282  * Validate each in turn, until one fails.
283  */
284  for(i = 0; i < list->count; i++) {
285  const void *memb_ptr = list->array[i];
286  int ret;
287 
288  if(!memb_ptr) continue;
289 
290  ret = constr(elm->type, memb_ptr, ctfailcb, app_key);
291  if(ret) return ret;
292  }
293 
294  return 0;
295 }
296 
299  const void *sptr;
300 };
301 
302 static int
303 SET_OF__compare_cb(const void *aptr, const void *bptr) {
304  const struct comparable_ptr *a = aptr;
305  const struct comparable_ptr *b = bptr;
306  assert(a->td == b->td);
307  return a->td->op->compare_struct(a->td, a->sptr, b->sptr);
308 }
309 
310 int
311 SET_OF_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
312  const void *bptr) {
313  const asn_anonymous_set_ *a = _A_CSET_FROM_VOID(aptr);
314  const asn_anonymous_set_ *b = _A_CSET_FROM_VOID(bptr);
315 
316  if(a && b) {
317  struct comparable_ptr *asorted;
318  struct comparable_ptr *bsorted;
319  ssize_t common_length;
320  ssize_t idx;
321 
322  if(a->count == 0) {
323  if(b->count) return -1;
324  return 0;
325  } else if(b->count == 0) {
326  return 1;
327  }
328 
329  asorted = MALLOC(a->count * sizeof(asorted[0]));
330  bsorted = MALLOC(b->count * sizeof(bsorted[0]));
331  if(!asorted || !bsorted) {
332  FREEMEM(asorted);
333  FREEMEM(bsorted);
334  return -1;
335  }
336 
337  for(idx = 0; idx < a->count; idx++) {
338  asorted[idx].td = td->elements->type;
339  asorted[idx].sptr = a->array[idx];
340  }
341 
342  for(idx = 0; idx < b->count; idx++) {
343  bsorted[idx].td = td->elements->type;
344  bsorted[idx].sptr = b->array[idx];
345  }
346 
347  qsort(asorted, a->count, sizeof(asorted[0]), SET_OF__compare_cb);
348  qsort(bsorted, b->count, sizeof(bsorted[0]), SET_OF__compare_cb);
349 
350  common_length = (a->count < b->count ? a->count : b->count);
351  for(idx = 0; idx < common_length; idx++) {
352  int ret = td->elements->type->op->compare_struct(
353  td->elements->type, asorted[idx].sptr, bsorted[idx].sptr);
354  if(ret) {
355  FREEMEM(asorted);
356  FREEMEM(bsorted);
357  return ret;
358  }
359  }
360 
361  FREEMEM(asorted);
362  FREEMEM(bsorted);
363 
364  if(idx < b->count) /* more elements in b */
365  return -1; /* a is shorter, so put it first */
366  if(idx < a->count) return 1;
367  } else if(!a) {
368  return -1;
369  } else if(!b) {
370  return 1;
371  }
372 
373  return 0;
374 }
375 
376 int
378  const void *bptr) {
379  if(!td) return -1;
380 
381  const asn_SET_OF_specifics_t *specs =
383  void *st = *aptr;
384 
385  if(!bptr) {
386  if(*aptr) {
388  *aptr = 0;
389  }
390  return 0;
391  }
392 
393  if(st == 0) {
394  st = *aptr = CALLOC(1, specs->struct_size);
395  if(st == 0) return -1;
396  }
397 
398  asn_anonymous_set_ *a = _A_SET_FROM_VOID(*aptr);
399  const asn_anonymous_set_ *b = _A_CSET_FROM_VOID(bptr);
400 
401  if(b->size) {
402  void *_new_arr;
403  _new_arr = REALLOC(a->array, b->size * sizeof(b->array[0]));
404  if(_new_arr) {
405  a->array = (void **)_new_arr;
406  a->size = b->size;
407  } else {
408  return -1;
409  }
410  a->count = b->count;
411 
412  for(int i = 0; i < b->count; i++) {
413  void *bmemb = b->array[i];
414  if(bmemb) {
415  void *amemb = 0;
416  int ret;
417  ret = td->elements->type->op->copy_struct(
418  td->elements->type,
419  &amemb, bmemb);
420  if(ret != 0) return ret;
421  a->array[i] = amemb;
422  } else {
423  a->array[i] = 0;
424  }
425  }
426  }
427 
428  return 0;
429 }
ASN_STRUCT_FREE
#define ASN_STRUCT_FREE(asn_DEF, ptr)
Definition: constr_TYPE.h:102
asn_struct_ctx_s
Definition: constr_TYPE.h:29
asn_TYPE_operation_s
Definition: constr_TYPE.h:184
ASFM_FREE_UNDERLYING
@ ASFM_FREE_UNDERLYING
Definition: constr_TYPE.h:92
asn_SET_OF_specifics_s::ctx_offset
unsigned ctx_offset
Definition: constr_SET_OF.h:20
_el_buf_cmp
static int _el_buf_cmp(const void *ap, const void *bp)
Definition: constr_SET_OF.c:103
asn_OP_SET_OF
asn_TYPE_operation_t asn_OP_SET_OF
Definition: constr_SET_OF.c:9
aper_encode
asn_enc_rval_t aper_encode(const struct asn_TYPE_descriptor_s *type_descriptor, const asn_per_constraints_t *constraints, const void *struct_ptr, asn_app_consume_bytes_f *consume_bytes_cb, void *app_key)
_el_buffer::bits_unused
unsigned bits_unused
Definition: constr_SET_OF.h:82
asn_app_constraint_failed_f
void() asn_app_constraint_failed_f(void *application_specific_key, const struct asn_TYPE_descriptor_s *type_descriptor_which_failed, const void *structure_which_failed_ptr, const char *error_message_format,...) CC_PRINTFLIKE(4
Definition: asn_application.h:167
SET_OF_encode_aper
per_type_encoder_f SET_OF_encode_aper
Definition: constr_SET_OF.h:66
SET_OF_random_fill
asn_random_fill_f SET_OF_random_fill
Definition: constr_SET_OF.h:70
asn_TYPE_descriptor_s::name
const char * name
Definition: constr_TYPE.h:225
asn_enc_rval_s
Definition: asn_codecs.h:41
CALLOC
#define CALLOC(nmemb, size)
Definition: asn_internal.h:37
ASFM_FREE_UNDERLYING_AND_RESET
@ ASFM_FREE_UNDERLYING_AND_RESET
Definition: constr_TYPE.h:93
ASFM_FREE_EVERYTHING
@ ASFM_FREE_EVERYTHING
Definition: constr_TYPE.h:91
SET_OF_constraint
int SET_OF_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key)
Definition: constr_SET_OF.c:263
asn_TYPE_operation_s::der_encoder
der_type_encoder_f * der_encoder
Definition: constr_TYPE.h:190
SOES_DER
@ SOES_DER
Definition: constr_SET_OF.h:86
comparable_ptr::td
const asn_TYPE_descriptor_t * td
Definition: constr_SET_OF.c:298
assert_unused_bits
static void assert_unused_bits(const struct _el_buffer *p)
Definition: constr_SET_OF.c:95
SET_OF_decode_uper
per_type_decoder_f SET_OF_decode_uper
Definition: constr_SET_OF.h:61
SET_OF_decode_xer
xer_type_decoder_f SET_OF_decode_xer
Definition: constr_SET_OF.h:46
asn_TYPE_operation_s::copy_struct
asn_struct_copy_f * copy_struct
Definition: constr_TYPE.h:188
SET_OF__compare_cb
static int SET_OF__compare_cb(const void *aptr, const void *bptr)
Definition: constr_SET_OF.c:303
SOES_CUPER
@ SOES_CUPER
Definition: constr_SET_OF.h:87
REALLOC
#define REALLOC(oldptr, size)
Definition: asn_internal.h:39
FREEMEM
#define FREEMEM(ptr)
Definition: asn_internal.h:40
_el_buffer::allocated_size
size_t allocated_size
Definition: constr_SET_OF.h:81
SET_OF__encode_method
SET_OF__encode_method
Definition: constr_SET_OF.h:85
SET_OF_compare
int SET_OF_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const void *bptr)
Definition: constr_SET_OF.c:311
SET_OF_print
asn_struct_print_f SET_OF_print
Definition: constr_SET_OF.h:32
_el_buffer::length
size_t length
Definition: constr_SET_OF.h:80
asn_TYPE_descriptor_s
Definition: constr_TYPE.h:224
asn_TYPE_member_s::type
asn_TYPE_descriptor_t * type
Definition: constr_TYPE.h:278
_el_buffer
Definition: constr_SET_OF.h:78
SOES_CAPER
@ SOES_CAPER
Definition: constr_SET_OF.h:88
asn_TYPE_descriptor_s::specifics
const void * specifics
Definition: constr_TYPE.h:259
SET_OF__encode_sorted_free
void SET_OF__encode_sorted_free(struct _el_buffer *el_buf, size_t count)
Definition: constr_SET_OF.c:131
asn_SET_OF_specifics_s::struct_size
unsigned struct_size
Definition: constr_SET_OF.h:19
uper_encode
asn_enc_rval_t uper_encode(const struct asn_TYPE_descriptor_s *type_descriptor, const asn_per_constraints_t *constraints, const void *struct_ptr, asn_app_consume_bytes_f *consume_bytes_cb, void *app_key)
SET_OF_copy
int SET_OF_copy(const asn_TYPE_descriptor_t *td, void **aptr, const void *bptr)
Definition: constr_SET_OF.c:377
SET_OF_decode_oer
oer_type_decoder_f SET_OF_decode_oer
Definition: constr_SET_OF.h:56
_A_SET_FROM_VOID
#define _A_SET_FROM_VOID(ptr)
Definition: asn_SET_OF.h:65
asn_TYPE_descriptor_s::op
asn_TYPE_operation_t * op
Definition: constr_TYPE.h:232
asn_struct_free_method
asn_struct_free_method
Definition: constr_TYPE.h:90
comparable_ptr::sptr
const void * sptr
Definition: constr_SET_OF.c:299
SET_OF_decode_ber
ber_type_decoder_f SET_OF_decode_ber
Definition: constr_SET_OF.h:41
asn_TYPE_operation_s::compare_struct
asn_struct_compare_f * compare_struct
Definition: constr_TYPE.h:187
constr_SET_OF.h
SET_OF_encode_uper
per_type_encoder_f SET_OF_encode_uper
Definition: constr_SET_OF.h:62
_A_CSET_FROM_VOID
#define _A_CSET_FROM_VOID(ptr)
Definition: asn_SET_OF.h:66
asn_constr_check_f
int() asn_constr_check_f(const struct asn_TYPE_descriptor_s *type_descriptor, const void *struct_ptr, asn_app_constraint_failed_f *optional_callback, void *optional_app_key)
Definition: constraints.h:41
SET_OF_encode_xer
xer_type_encoder_f SET_OF_encode_xer
Definition: constr_SET_OF.h:47
MALLOC
#define MALLOC(size)
Definition: asn_internal.h:38
_el_addbytes
static int _el_addbytes(const void *buffer, size_t size, void *el_buf_ptr)
Definition: constr_SET_OF.c:69
asn_encoding_constraints_s::per_constraints
const struct asn_per_constraints_s * per_constraints
Definition: constr_TYPE.h:213
SET_OF_decode_jer
jer_type_decoder_f SET_OF_decode_jer
Definition: constr_SET_OF.h:51
asn_set_empty
void asn_set_empty(void *asn_set_of_x)
Definition: asn_SET_OF.c:71
asn_internal.h
ASN__CTFAIL
#define ASN__CTFAIL
Definition: constraints.h:57
SET_OF_decode_aper
per_type_decoder_f SET_OF_decode_aper
Definition: constr_SET_OF.h:65
asn_TYPE_descriptor_s::elements
struct asn_TYPE_member_s * elements
Definition: constr_TYPE.h:252
asn_encoding_constraints_s::general_constraints
asn_constr_check_f * general_constraints
Definition: constr_TYPE.h:218
asn_TYPE_member_s::tag_mode
int tag_mode
Definition: constr_TYPE.h:277
SET_OF_encode_der
der_type_encoder_f SET_OF_encode_der
Definition: constr_SET_OF.h:42
comparable_ptr
Definition: constr_SET_OF.c:297
SET_OF_encode_oer
oer_type_encoder_f SET_OF_encode_oer
Definition: constr_SET_OF.h:57
asn_enc_rval_s::encoded
ssize_t encoded
Definition: asn_codecs.h:47
SET_OF_encode_jer
jer_type_encoder_f SET_OF_encode_jer
Definition: constr_SET_OF.h:52
SET_OF__encode_sorted
struct _el_buffer * SET_OF__encode_sorted(const asn_TYPE_member_t *elm, const asn_anonymous_set_ *list, enum SET_OF__encode_method method)
Definition: constr_SET_OF.c:142
asn_struct_ctx_s::ptr
void * ptr
Definition: constr_TYPE.h:33
asn_TYPE_member_s
Definition: constr_TYPE.h:272
asn_TYPE_descriptor_s::encoding_constraints
asn_encoding_constraints_t encoding_constraints
Definition: constr_TYPE.h:247
asn_TYPE_member_s::tag
ber_tlv_tag_t tag
Definition: constr_TYPE.h:276
asn_SET_OF_specifics_s
Definition: constr_SET_OF.h:15
_el_buffer::buf
uint8_t * buf
Definition: constr_SET_OF.h:79
SET_OF_free
void SET_OF_free(const asn_TYPE_descriptor_t *td, void *ptr, enum asn_struct_free_method method)
Definition: constr_SET_OF.c:220
asn_TYPE_member_s::encoding_constraints
asn_encoding_constraints_t encoding_constraints
Definition: constr_TYPE.h:280


etsi_its_vam_ts_coding
Author(s): Jean-Pierre Busch , Guido Küppers , Lennart Reiher
autogenerated on Sun May 18 2025 02:30:55