ITS
per_encoder.c
Go to the documentation of this file.
1 #include <asn_application.h>
2 #include <asn_internal.h>
3 #include <per_encoder.h>
4 
6 
8 uper_encode(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
9  return uper_encode_internal(td, 0, sptr, cb, app_key);
10 }
11 
12 /*
13  * Argument type and callback necessary for uper_encode_to_buffer().
14  */
15 typedef struct enc_to_buf_arg {
16  void *buffer;
17  size_t left;
19 static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) {
20  enc_to_buf_arg *arg = (enc_to_buf_arg *)key;
21 
22  if(arg->left < size)
23  return -1; /* Data exceeds the available buffer size */
24 
25  memcpy(arg->buffer, buffer, size);
26  arg->buffer = ((char *)arg->buffer) + size;
27  arg->left -= size;
28 
29  return 0;
30 }
31 
33 uper_encode_to_buffer(asn_TYPE_descriptor_t *td, void *sptr, void *buffer, size_t buffer_size) {
34  enc_to_buf_arg key;
35 
36  key.buffer = buffer;
37  key.left = buffer_size;
38 
39  if(td) ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name);
40 
41  return uper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key);
42 }
43 
44 typedef struct enc_dyn_arg {
45  void *buffer;
46  size_t length;
47  size_t allocated;
48 } enc_dyn_arg;
49 static int
50 encode_dyn_cb(const void *buffer, size_t size, void *key) {
51  enc_dyn_arg *arg = key;
52  if(arg->length + size >= arg->allocated) {
53  void *p;
54  arg->allocated = arg->allocated ? (arg->allocated << 2) : size;
55  p = REALLOC(arg->buffer, arg->allocated);
56  if(!p) {
57  FREEMEM(arg->buffer);
58  memset(arg, 0, sizeof(*arg));
59  return -1;
60  }
61  arg->buffer = p;
62  }
63  memcpy(((char *)arg->buffer) + arg->length, buffer, size);
64  arg->length += size;
65  return 0;
66 }
67 ssize_t
68 uper_encode_to_new_buffer(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, void **buffer_r) {
69  asn_enc_rval_t er;
70  enc_dyn_arg key;
71 
72  memset(&key, 0, sizeof(key));
73 
74  er = uper_encode_internal(td, constraints, sptr, encode_dyn_cb, &key);
75  switch(er.encoded) {
76  case -1:
77  FREEMEM(key.buffer);
78  return -1;
79  case 0:
80  FREEMEM(key.buffer);
81  key.buffer = MALLOC(1);
82  if(key.buffer) {
83  *(char *)key.buffer = '\0';
84  *buffer_r = key.buffer;
85  return 1;
86  } else {
87  return -1;
88  }
89  default:
90  *buffer_r = key.buffer;
91  ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
92  return ((er.encoded + 7) >> 3);
93  }
94 }
95 
96 /*
97  * Internally useful functions.
98  */
99 
100 /* Flush partially filled buffer */
101 static int
103  uint8_t *buf;
104 
105  if(po->nboff == 0 && po->buffer == po->tmpspace)
106  return 0;
107 
108  buf = po->buffer + (po->nboff >> 3);
109  /* Make sure we account for the last, partially filled */
110  if(po->nboff & 0x07) {
111  buf[0] &= 0xff << (8 - (po->nboff & 0x07));
112  buf++;
113  }
114 
115  return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key);
116 }
117 
118 static asn_enc_rval_t
120  asn_per_outp_t po;
121  asn_enc_rval_t er;
122 
123  /*
124  * Invoke type-specific encoder.
125  */
126  if(!td || !td->uper_encoder)
127  _ASN_ENCODE_FAILED; /* PER is not compiled in */
128 
129  po.buffer = po.tmpspace;
130  po.nboff = 0;
131  po.nbits = 8 * sizeof(po.tmpspace);
132  po.outper = cb;
133  po.op_key = app_key;
134  po.flushed_bytes = 0;
135 
136  er = td->uper_encoder(td, constraints, sptr, &po);
137  if(er.encoded != -1) {
138  size_t bits_to_flush;
139 
140  bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
141 
142  /* Set number of bits encoded to a firm value */
143  er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
144 
145  if(_uper_encode_flush_outp(&po))
147  }
148 
149  return er;
150 }
151 
ssize_t uper_encode_to_new_buffer(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, void **buffer_r)
Definition: per_encoder.c:68
int(* outper)(const void *data, size_t size, void *op_key)
Definition: per_support.h:98
static int encode_to_buffer_cb(const void *buffer, size_t size, void *key)
Definition: per_encoder.c:19
size_t length
Definition: per_encoder.c:46
static asn_enc_rval_t uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *, void *sptr, asn_app_consume_bytes_f *cb, void *app_key)
Definition: per_encoder.c:119
#define REALLOC(oldptr, size)
Definition: asn_internal.h:28
static int encode_dyn_cb(const void *buffer, size_t size, void *key)
Definition: per_encoder.c:50
ssize_t encoded
Definition: asn_codecs.h:48
uint8_t * buffer
Definition: per_support.h:94
size_t allocated
Definition: per_encoder.c:47
#define FREEMEM(ptr)
Definition: asn_internal.h:29
#define _ASN_ENCODE_FAILED
Definition: asn_codecs.h:60
struct enc_to_buf_arg enc_to_buf_arg
int() asn_app_consume_bytes_f(const void *buffer, size_t size, void *application_specific_key)
asn_enc_rval_t uper_encode_to_buffer(asn_TYPE_descriptor_t *td, void *sptr, void *buffer, size_t buffer_size)
Definition: per_encoder.c:33
asn_enc_rval_t uper_encode(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb, void *app_key)
Definition: per_encoder.c:8
static int _uper_encode_flush_outp(asn_per_outp_t *po)
Definition: per_encoder.c:102
struct enc_dyn_arg enc_dyn_arg
size_t flushed_bytes
Definition: per_support.h:100
per_type_encoder_f * uper_encoder
Definition: constr_TYPE.h:101
static void ASN_DEBUG(const char *fmt,...)
Definition: asn_internal.h:62
#define MALLOC(size)
Definition: asn_internal.h:27
uint8_t tmpspace[32]
Definition: per_support.h:97
void * buffer
Definition: per_encoder.c:45