blob: a1c77118dc6277e1ff9119ca16e82c75643048bc [file] [log] [blame]
Lev Walkina737f3b2004-09-02 12:11:47 +00001/*-
2 * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
4 */
Lev Walkina9cc46e2004-09-22 16:06:28 +00005#include <asn_internal.h>
Lev Walkina737f3b2004-09-02 12:11:47 +00006#include <ANY.h>
7#include <assert.h>
8#include <errno.h>
9
10asn1_TYPE_descriptor_t asn1_DEF_ANY = {
11 "ANY",
Lev Walkina9cc46e2004-09-22 16:06:28 +000012 OCTET_STRING_free,
13 OCTET_STRING_print,
Lev Walkina737f3b2004-09-02 12:11:47 +000014 asn_generic_no_constraint,
15 OCTET_STRING_decode_ber,
16 OCTET_STRING_encode_der,
Lev Walkina9cc46e2004-09-22 16:06:28 +000017 0, /* Not implemented yet */
18 ANY_encode_xer,
Lev Walkina737f3b2004-09-02 12:11:47 +000019 0, /* Use generic outmost tag fetcher */
Lev Walkind563d392004-09-13 08:26:57 +000020 0, 0, 0, 0,
Lev Walkina737f3b2004-09-02 12:11:47 +000021 -1, /* Both ways are fine (primitive and constructed) */
22 0, 0, /* No members */
23 (void *)1 /* Special indicator that this is an ANY type */
24};
Lev Walkind563d392004-09-13 08:26:57 +000025
26
Lev Walkina9cc46e2004-09-22 16:06:28 +000027asn_enc_rval_t
28ANY_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
29 int ilevel, enum xer_encoder_flags_e flags,
30 asn_app_consume_bytes_f *cb, void *app_key) {
31
32 (void)ilevel;
33 (void)flags;
34 (void)cb;
35 (void)app_key;
36
37 /*
38 * XER-encoding of ANY type is not supported.
39 */
40
41 _ASN_ENCODE_FAILED;
42}
43
Lev Walkind563d392004-09-13 08:26:57 +000044struct _callback_arg {
45 uint8_t *buffer;
46 size_t offset;
47 size_t size;
48};
49
50static int ANY__consume_bytes(const void *buffer, size_t size, void *key);
51
52int
53ANY_fromType(ANY_t *st, asn1_TYPE_descriptor_t *td, void *sptr) {
54 struct _callback_arg arg;
Lev Walkina9cc46e2004-09-22 16:06:28 +000055 asn_enc_rval_t erval;
Lev Walkind563d392004-09-13 08:26:57 +000056
57 if(!st || !td) {
58 errno = EINVAL;
59 return -1;
60 }
61
62 if(!sptr) {
63 if(st->buf) FREEMEM(st->buf);
64 st->size = 0;
65 return 0;
66 }
67
68 arg.offset = arg.size = 0;
69 arg.buffer = 0;
70
71 erval = der_encode(td, sptr, ANY__consume_bytes, &arg);
72 if(erval.encoded == -1) {
73 if(arg.buffer) FREEMEM(arg.buffer);
74 return -1;
75 }
Lev Walkina9cc46e2004-09-22 16:06:28 +000076 assert((size_t)erval.encoded == arg.offset);
Lev Walkind563d392004-09-13 08:26:57 +000077
78 if(st->buf) FREEMEM(st->buf);
79 st->buf = arg.buffer;
80 st->size = arg.offset;
81
82 return 0;
83}
84
85ANY_t *
86ANY_new_fromType(asn1_TYPE_descriptor_t *td, void *sptr) {
87 ANY_t tmp;
88 ANY_t *st;
89
90 if(!td || !sptr) {
91 errno = EINVAL;
92 return 0;
93 }
94
95 memset(&tmp, 0, sizeof(tmp));
96
97 if(ANY_fromType(&tmp, td, sptr)) return 0;
98
99 st = (ANY_t *)MALLOC(sizeof(*st));
100 if(st) {
101 *st = tmp;
102 return st;
103 } else {
104 FREEMEM(tmp.buf);
105 return 0;
106 }
107}
108
109int
110ANY_to_type(ANY_t *st, asn1_TYPE_descriptor_t *td, void **struct_ptr) {
111 ber_dec_rval_t rval;
112 void *newst = 0;
113
114 if(!st || !td || !struct_ptr) {
115 errno = EINVAL;
116 return -1;
117 }
118
119 if(st->buf == 0) {
120 /* Nothing to convert, make it empty. */
121 *struct_ptr = (void *)0;
122 return 0;
123 }
124
125 rval = ber_decode(td, (void **)&newst, st->buf, st->size);
126 if(rval.code == RC_OK) {
127 *struct_ptr = newst;
128 return 0;
129 } else {
130 /* Remove possibly partially decoded data. */
131 td->free_struct(td, newst, 0);
132 return -1;
133 }
134}
135
136static int ANY__consume_bytes(const void *buffer, size_t size, void *key) {
137 struct _callback_arg *arg = (struct _callback_arg *)key;
138
139 if((arg->offset + size) >= arg->size) {
140 size_t nsize = (arg->size ? arg->size << 2 : 16) + size;
141 void *p = REALLOC(arg->buffer, nsize);
142 if(!p) return -1;
143 (void *)arg->buffer = p;
144 arg->size = nsize;
145 }
146
147 memcpy(arg->buffer + arg->offset, buffer, size);
148 arg->offset += size;
149 assert(arg->offset < arg->size);
150
151 return 0;
152}
153