2 * Copyright (c) 2004-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
\r
3 * Redistribution and modifications are permitted subject to BSD license.
\r
5 #include <asn_internal.h>
\r
9 asn_OCTET_STRING_specifics_t asn_SPC_ANY_specs = {
\r
11 offsetof(ANY_t, _asn_ctx),
\r
14 asn_TYPE_operation_t asn_OP_ANY = {
\r
17 OCTET_STRING_compare,
\r
18 OCTET_STRING_decode_ber,
\r
19 OCTET_STRING_encode_der,
\r
20 OCTET_STRING_decode_xer_hex,
\r
22 #ifdef ASN_DISABLE_OER_SUPPORT
\r
28 #endif /* ASN_DISABLE_OER_SUPPORT */
\r
29 #ifdef ASN_DISABLE_PER_SUPPORT
\r
36 #endif /* ASN_DISABLE_PER_SUPPORT */
\r
37 0, /* Random fill is not defined for ANY type */
\r
38 0 /* Use generic outmost tag fetcher */
\r
40 asn_TYPE_descriptor_t asn_DEF_ANY = {
\r
45 { 0, 0, asn_generic_no_constraint }, /* No constraints */
\r
46 0, 0, /* No members */
\r
51 #define RETURN(_code) \
\r
53 asn_dec_rval_t tmprval; \
\r
54 tmprval.code = _code; \
\r
55 tmprval.consumed = consumed_myself; \
\r
60 ANY_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
\r
61 enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb,
\r
63 if(flags & XER_F_CANONICAL) {
\r
65 * Canonical XER-encoding of ANY type is not supported.
\r
70 /* Dump as binary */
\r
71 return OCTET_STRING_encode_xer(td, sptr, ilevel, flags, cb, app_key);
\r
74 struct _callback_arg {
\r
80 static int ANY__consume_bytes(const void *buffer, size_t size, void *key);
\r
83 ANY_fromType(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
\r
84 struct _callback_arg arg;
\r
85 asn_enc_rval_t erval = {0,0,0};
\r
93 if(st->buf) FREEMEM(st->buf);
\r
98 arg.offset = arg.size = 0;
\r
101 erval = der_encode(td, sptr, ANY__consume_bytes, &arg);
\r
102 if(erval.encoded == -1) {
\r
103 if(arg.buffer) FREEMEM(arg.buffer);
\r
106 assert((size_t)erval.encoded == arg.offset);
\r
108 if(st->buf) FREEMEM(st->buf);
\r
109 st->buf = arg.buffer;
\r
110 st->size = arg.offset;
\r
116 ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
\r
117 uint8_t *buffer = NULL;
\r
126 if(st->buf) FREEMEM(st->buf);
\r
131 erval = aper_encode_to_new_buffer(td, td->encoding_constraints.per_constraints, sptr, (void**)&buffer);
\r
134 if(buffer) FREEMEM(buffer);
\r
137 assert((size_t)erval > 0);
\r
139 if(st->buf) FREEMEM(st->buf);
\r
147 ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
\r
156 memset(&tmp, 0, sizeof(tmp));
\r
158 if(ANY_fromType(&tmp, td, sptr)) return 0;
\r
160 st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
\r
171 ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr) {
\r
180 memset(&tmp, 0, sizeof(tmp));
\r
182 if(ANY_fromType_aper(&tmp, td, sptr)) return 0;
\r
184 st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
\r
195 ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
\r
196 asn_dec_rval_t rval;
\r
199 if(!st || !td || !struct_ptr) {
\r
205 /* Nothing to convert, make it empty. */
\r
206 *struct_ptr = (void *)0;
\r
210 rval = ber_decode(0, td, (void **)&newst, st->buf, st->size);
\r
211 if(rval.code == RC_OK) {
\r
212 *struct_ptr = newst;
\r
215 /* Remove possibly partially decoded data. */
\r
216 ASN_STRUCT_FREE(*td, newst);
\r
222 ANY_to_type_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
\r
223 asn_dec_rval_t rval;
\r
226 if(!st || !td || !struct_ptr) {
\r
232 /* Nothing to convert, make it empty. */
\r
233 *struct_ptr = (void *)0;
\r
237 rval = aper_decode(0, td, (void **)&newst, st->buf, st->size, 0, 0);
\r
238 if(rval.code == RC_OK) {
\r
239 *struct_ptr = newst;
\r
242 /* Remove possibly partially decoded data. */
\r
243 ASN_STRUCT_FREE(*td, newst);
\r
248 static int ANY__consume_bytes(const void *buffer, size_t size, void *key) {
\r
249 struct _callback_arg *arg = (struct _callback_arg *)key;
\r
251 if((arg->offset + size) >= arg->size) {
\r
252 size_t nsize = (arg->size ? arg->size << 2 : 16) + size;
\r
253 void *p = REALLOC(arg->buffer, nsize);
\r
255 arg->buffer = (uint8_t *)p;
\r
259 memcpy(arg->buffer + arg->offset, buffer, size);
\r
260 arg->offset += size;
\r
261 assert(arg->offset < arg->size);
\r
266 #ifndef ASN_DISABLE_PER_SUPPORT
\r
269 ANY_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
\r
270 const asn_TYPE_descriptor_t *td,
\r
271 const asn_per_constraints_t *constraints, void **sptr,
\r
272 asn_per_data_t *pd) {
\r
273 const asn_OCTET_STRING_specifics_t *specs =
\r
274 td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
\r
275 : &asn_SPC_ANY_specs;
\r
276 size_t consumed_myself = 0;
\r
278 ANY_t *st = (ANY_t *)*sptr;
\r
280 (void)opt_codec_ctx;
\r
284 * Allocate the structure.
\r
287 st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size));
\r
288 if(!st) RETURN(RC_FAIL);
\r
291 ASN_DEBUG("UPER Decoding ANY type");
\r
301 /* Get the PER length */
\r
302 raw_len = uper_get_length(pd, -1, 0, &repeat);
\r
303 if(raw_len < 0) RETURN(RC_WMORE);
\r
304 if(raw_len == 0 && st->buf) break;
\r
306 ASN_DEBUG("Got PER length len %" ASN_PRI_SIZE ", %s (%s)", raw_len,
\r
307 repeat ? "repeat" : "once", td->name);
\r
308 len_bytes = raw_len;
\r
309 len_bits = len_bytes * 8;
\r
311 p = REALLOC(st->buf, st->size + len_bytes + 1);
\r
312 if(!p) RETURN(RC_FAIL);
\r
313 st->buf = (uint8_t *)p;
\r
315 ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
\r
316 if(ret < 0) RETURN(RC_WMORE);
\r
317 consumed_myself += len_bits;
\r
318 st->size += len_bytes;
\r
320 st->buf[st->size] = 0; /* nul-terminate */
\r
326 ANY_encode_uper(const asn_TYPE_descriptor_t *td,
\r
327 const asn_per_constraints_t *constraints, const void *sptr,
\r
328 asn_per_outp_t *po) {
\r
329 const ANY_t *st = (const ANY_t *)sptr;
\r
330 asn_enc_rval_t er = {0, 0, 0};
\r
331 const uint8_t *buf;
\r
337 if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED;
\r
343 ssize_t may_save = uper_put_length(po, size, &need_eom);
\r
344 if(may_save < 0) ASN__ENCODE_FAILED;
\r
346 ret = per_put_many_bits(po, buf, may_save * 8);
\r
347 if(ret) ASN__ENCODE_FAILED;
\r
351 assert(!(may_save & 0x07) || !size);
\r
352 if(need_eom && uper_put_length(po, 0, 0))
\r
353 ASN__ENCODE_FAILED; /* End of Message length */
\r
356 ASN__ENCODED_OK(er);
\r
360 ANY_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
\r
361 const asn_TYPE_descriptor_t *td,
\r
362 const asn_per_constraints_t *constraints, void **sptr,
\r
363 asn_per_data_t *pd) {
\r
364 const asn_OCTET_STRING_specifics_t *specs =
\r
365 td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
\r
366 : &asn_SPC_ANY_specs;
\r
367 size_t consumed_myself = 0;
\r
369 ANY_t *st = (ANY_t *)*sptr;
\r
371 (void)opt_codec_ctx;
\r
375 * Allocate the structure.
\r
378 st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size));
\r
379 if(!st) RETURN(RC_FAIL);
\r
382 ASN_DEBUG("APER Decoding ANY type");
\r
392 /* Get the PER length */
\r
393 raw_len = aper_get_length(pd, -1, 0, &repeat);
\r
394 if(raw_len < 0) RETURN(RC_WMORE);
\r
395 if(raw_len == 0 && st->buf) break;
\r
397 ASN_DEBUG("Got PER length len %" ASN_PRI_SIZE ", %s (%s)", raw_len,
\r
398 repeat ? "repeat" : "once", td->name);
\r
399 len_bytes = raw_len;
\r
400 len_bits = len_bytes * 8;
\r
402 p = REALLOC(st->buf, st->size + len_bytes + 1);
\r
403 if(!p) RETURN(RC_FAIL);
\r
404 st->buf = (uint8_t *)p;
\r
406 ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
\r
407 if(ret < 0) RETURN(RC_WMORE);
\r
408 consumed_myself += len_bits;
\r
409 st->size += len_bytes;
\r
411 st->buf[st->size] = 0; /* nul-terminate */
\r
417 ANY_encode_aper(const asn_TYPE_descriptor_t *td,
\r
418 const asn_per_constraints_t *constraints, const void *sptr,
\r
419 asn_per_outp_t *po) {
\r
420 const ANY_t *st = (const ANY_t *)sptr;
\r
421 asn_enc_rval_t er = {0, 0, 0};
\r
422 const uint8_t *buf;
\r
428 if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED;
\r
434 ssize_t may_save = uper_put_length(po, size, &need_eom);
\r
435 if(may_save < 0) ASN__ENCODE_FAILED;
\r
437 ret = per_put_many_bits(po, buf, may_save * 8);
\r
438 if(ret) ASN__ENCODE_FAILED;
\r
442 assert(!(may_save & 0x07) || !size);
\r
443 if(need_eom && uper_put_length(po, 0, 0))
\r
444 ASN__ENCODE_FAILED; /* End of Message length */
\r
447 ASN__ENCODED_OK(er);
\r
449 #endif /* ASN_DISABLE_PER_SUPPORT */
\r