SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / aper_opentype.c
1 /*
2  * Copyright (c) 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
3  * Redistribution and modifications are permitted subject to BSD license.
4  */
5 #include <asn_internal.h>
6 #include <aper_encoder.h>
7 #include <aper_support.h>
8 #include <aper_opentype.h>
9
10 static asn_dec_rval_t
11 aper_open_type_get_simple(const asn_codec_ctx_t *ctx,
12                           const asn_TYPE_descriptor_t *td,
13                           const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
14         asn_dec_rval_t rv;
15         ssize_t chunk_bytes;
16         int repeat;
17         uint8_t *buf = 0;
18         size_t bufLen = 0;
19         size_t bufSize = 0;
20         asn_per_data_t spd;
21         size_t padding;
22
23         ASN__STACK_OVERFLOW_CHECK(ctx);
24
25         ASN_DEBUG("Getting open type %s...", td->name);
26
27         do {
28                 chunk_bytes = aper_get_length(pd, -1, -1, -1, &repeat);
29                 if(chunk_bytes < 0) {
30                         FREEMEM(buf);
31                         ASN__DECODE_STARVED;
32                 }
33                 if(bufLen + chunk_bytes > bufSize) {
34                         void *ptr;
35                         bufSize = chunk_bytes + (bufSize << 2);
36                         ptr = REALLOC(buf, bufSize);
37                         if(!ptr) {
38                                 FREEMEM(buf);
39                                 ASN__DECODE_FAILED;
40                         }
41                         buf = ptr;
42                 }
43                 if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) {
44                         FREEMEM(buf);
45                         ASN__DECODE_STARVED;
46                 }
47                 bufLen += chunk_bytes;
48         } while(repeat);
49
50         ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name,
51                 (long)bufLen);
52
53         memset(&spd, 0, sizeof(spd));
54         spd.buffer = buf;
55         spd.nbits = bufLen << 3;
56
57         ASN_DEBUG_INDENT_ADD(+4);
58         rv = td->op->aper_decoder(ctx, td, constraints, sptr, &spd);
59         ASN_DEBUG_INDENT_ADD(-4);
60
61         if(rv.code == RC_OK) {
62                 /* Check padding validity */
63                 padding = spd.nbits - spd.nboff;
64                 if (((padding > 0 && padding < 8) ||
65                 /* X.691#10.1.3 */
66                 (spd.nboff == 0 && spd.nbits == 8 && spd.buffer == buf)) &&
67                     per_get_few_bits(&spd, padding) == 0) {
68                         /* Everything is cool */
69                         FREEMEM(buf);
70                         return rv;
71                 }
72                 FREEMEM(buf);
73                 if(padding >= 8) {
74                         ASN_DEBUG("Too large padding %d in open type", (int)padding);
75                         ASN__DECODE_FAILED;
76                 } else {
77                         ASN_DEBUG("No padding");
78                 }
79         } else {
80                 FREEMEM(buf);
81                 /* rv.code could be RC_WMORE, nonsense in this context */
82                 rv.code = RC_FAIL; /* Noone would give us more */
83         }
84
85         return rv;
86 }
87
88 int
89 aper_open_type_put(const asn_TYPE_descriptor_t *td,
90                    const asn_per_constraints_t *constraints,
91                    const void *sptr, asn_per_outp_t *po) {
92         void *buf;
93         void *bptr;
94         ssize_t size;
95         size_t toGo;
96
97         ASN_DEBUG("Open type put %s ...", td->name);
98
99         size = aper_encode_to_new_buffer(td, constraints, sptr, &buf);
100         if(size <= 0) return -1;
101
102         for(bptr = buf, toGo = size; toGo;) {
103         int need_eom = 0;
104                 ssize_t maySave = aper_put_length(po, -1, -1, toGo, &need_eom);
105                 if(maySave < 0) break;
106                 if(per_put_many_bits(po, bptr, maySave * 8)) break;
107                 bptr = (char *)bptr + maySave;
108                 toGo -= maySave;
109         if(need_eom && (aper_put_length(po, -1, -1, 0, NULL) < 0)) {
110             FREEMEM(buf);
111             return -1;
112         }
113         }
114
115         FREEMEM(buf);
116         if(toGo) return -1;
117
118         ASN_DEBUG("Open type put %s of length %zd + overhead (1byte?)",
119                           td->name, size);
120
121         return 0;
122 }
123
124 asn_dec_rval_t
125 aper_open_type_get(const asn_codec_ctx_t *ctx,
126                    const asn_TYPE_descriptor_t *td,
127                    const asn_per_constraints_t *constraints,
128                    void **sptr, asn_per_data_t *pd) {
129
130         return aper_open_type_get_simple(ctx, td, constraints, sptr, pd);
131 }
132
133 int
134 aper_open_type_skip(const asn_codec_ctx_t *ctx, asn_per_data_t *pd) {
135         asn_TYPE_descriptor_t s_td;
136         asn_dec_rval_t rv;
137         asn_TYPE_operation_t op_t;
138
139         memset(&op_t, 0, sizeof(op_t));
140         s_td.name = "<unknown extension>";
141         s_td.op = &op_t;
142         s_td.op->aper_decoder = uper_sot_suck;
143
144         rv = aper_open_type_get(ctx, &s_td, 0, 0, pd);
145         if(rv.code != RC_OK)
146                 return -1;
147         else
148                 return 0;
149 }