2 * Copyright (c) 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
5 #include <asn_internal.h>
6 #include <aper_encoder.h>
7 #include <aper_support.h>
8 #include <aper_opentype.h>
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) {
23 ASN__STACK_OVERFLOW_CHECK(ctx);
25 ASN_DEBUG("Getting open type %s...", td->name);
28 chunk_bytes = aper_get_length(pd, -1, -1, -1, &repeat);
33 if(bufLen + chunk_bytes > bufSize) {
35 bufSize = chunk_bytes + (bufSize << 2);
36 ptr = REALLOC(buf, bufSize);
43 if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) {
47 bufLen += chunk_bytes;
50 ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name,
53 memset(&spd, 0, sizeof(spd));
55 spd.nbits = bufLen << 3;
57 ASN_DEBUG_INDENT_ADD(+4);
58 rv = td->op->aper_decoder(ctx, td, constraints, sptr, &spd);
59 ASN_DEBUG_INDENT_ADD(-4);
61 if(rv.code == RC_OK) {
62 /* Check padding validity */
63 padding = spd.nbits - spd.nboff;
64 if (((padding > 0 && padding < 8) ||
66 (spd.nboff == 0 && spd.nbits == 8 && spd.buffer == buf)) &&
67 per_get_few_bits(&spd, padding) == 0) {
68 /* Everything is cool */
74 ASN_DEBUG("Too large padding %d in open type", (int)padding);
77 ASN_DEBUG("No padding");
81 /* rv.code could be RC_WMORE, nonsense in this context */
82 rv.code = RC_FAIL; /* Noone would give us more */
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) {
97 ASN_DEBUG("Open type put %s ...", td->name);
99 size = aper_encode_to_new_buffer(td, constraints, sptr, &buf);
100 if(size <= 0) return -1;
102 for(bptr = buf, toGo = size; toGo;) {
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;
109 if(need_eom && (aper_put_length(po, -1, -1, 0, NULL) < 0)) {
118 ASN_DEBUG("Open type put %s of length %zd + overhead (1byte?)",
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) {
130 return aper_open_type_get_simple(ctx, td, constraints, sptr, pd);
134 aper_open_type_skip(const asn_codec_ctx_t *ctx, asn_per_data_t *pd) {
135 asn_TYPE_descriptor_t s_td;
137 asn_TYPE_operation_t op_t;
139 memset(&op_t, 0, sizeof(op_t));
140 s_td.name = "<unknown extension>";
142 s_td.op->aper_decoder = uper_sot_suck;
144 rv = aper_open_type_get(ctx, &s_td, 0, 0, pd);