Adding initial code jy.oak@samsung.com
[ric-app/kpimon.git] / asn1c_defs / all-defs / constr_SEQUENCE_OF.c
1 /*-\r
2  * Copyright (c) 2003, 2004, 2006 Lev Walkin <vlm@lionet.info>.\r
3  * All rights reserved.\r
4  * Redistribution and modifications are permitted subject to BSD license.\r
5  */\r
6 #include <asn_internal.h>\r
7 #include <constr_SEQUENCE_OF.h>\r
8 #include <asn_SEQUENCE_OF.h>\r
9 \r
10 /*\r
11  * The DER encoder of the SEQUENCE OF type.\r
12  */\r
13 asn_enc_rval_t\r
14 SEQUENCE_OF_encode_der(const asn_TYPE_descriptor_t *td, const void *ptr,\r
15                        int tag_mode, ber_tlv_tag_t tag,\r
16                        asn_app_consume_bytes_f *cb, void *app_key) {\r
17     asn_TYPE_member_t *elm = td->elements;\r
18         const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID(ptr);\r
19         size_t computed_size = 0;\r
20         ssize_t encoding_size = 0;\r
21         asn_enc_rval_t erval = {0,0,0};\r
22         int edx;\r
23 \r
24         ASN_DEBUG("Estimating size of SEQUENCE OF %s", td->name);\r
25 \r
26         /*\r
27          * Gather the length of the underlying members sequence.\r
28          */\r
29         for(edx = 0; edx < list->count; edx++) {\r
30                 void *memb_ptr = list->array[edx];\r
31                 if(!memb_ptr) continue;\r
32                 erval = elm->type->op->der_encoder(elm->type, memb_ptr,\r
33                         0, elm->tag,\r
34                         0, 0);\r
35                 if(erval.encoded == -1)\r
36                         return erval;\r
37                 computed_size += erval.encoded;\r
38         }\r
39 \r
40         /*\r
41          * Encode the TLV for the sequence itself.\r
42          */\r
43         encoding_size = der_write_tags(td, computed_size, tag_mode, 1, tag,\r
44                 cb, app_key);\r
45         if(encoding_size == -1) {\r
46                 erval.encoded = -1;\r
47                 erval.failed_type = td;\r
48                 erval.structure_ptr = ptr;\r
49                 return erval;\r
50         }\r
51 \r
52         computed_size += encoding_size;\r
53         if(!cb) {\r
54                 erval.encoded = computed_size;\r
55                 ASN__ENCODED_OK(erval);\r
56         }\r
57 \r
58         ASN_DEBUG("Encoding members of SEQUENCE OF %s", td->name);\r
59 \r
60         /*\r
61          * Encode all members.\r
62          */\r
63         for(edx = 0; edx < list->count; edx++) {\r
64                 void *memb_ptr = list->array[edx];\r
65                 if(!memb_ptr) continue;\r
66                 erval = elm->type->op->der_encoder(elm->type, memb_ptr,\r
67                         0, elm->tag,\r
68                         cb, app_key);\r
69                 if(erval.encoded == -1)\r
70                         return erval;\r
71                 encoding_size += erval.encoded;\r
72         }\r
73 \r
74         if(computed_size != (size_t)encoding_size) {\r
75                 /*\r
76                  * Encoded size is not equal to the computed size.\r
77                  */\r
78                 erval.encoded = -1;\r
79                 erval.failed_type = td;\r
80                 erval.structure_ptr = ptr;\r
81         } else {\r
82                 erval.encoded = computed_size;\r
83                 erval.structure_ptr = 0;\r
84                 erval.failed_type = 0;\r
85         }\r
86 \r
87         return erval;\r
88 }\r
89 \r
90 asn_enc_rval_t\r
91 SEQUENCE_OF_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,\r
92                        int ilevel, enum xer_encoder_flags_e flags,\r
93                        asn_app_consume_bytes_f *cb, void *app_key) {\r
94     asn_enc_rval_t er = {0,0,0};\r
95     const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics;\r
96     const asn_TYPE_member_t *elm = td->elements;\r
97     const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID(sptr);\r
98     const char *mname = specs->as_XMLValueList\r
99                             ? 0\r
100                             : ((*elm->name) ? elm->name : elm->type->xml_tag);\r
101     size_t mlen = mname ? strlen(mname) : 0;\r
102     int xcan = (flags & XER_F_CANONICAL);\r
103     int i;\r
104 \r
105     if(!sptr) ASN__ENCODE_FAILED;\r
106 \r
107     er.encoded = 0;\r
108 \r
109     for(i = 0; i < list->count; i++) {\r
110         asn_enc_rval_t tmper = {0,0,0};\r
111         void *memb_ptr = list->array[i];\r
112         if(!memb_ptr) continue;\r
113 \r
114         if(mname) {\r
115             if(!xcan) ASN__TEXT_INDENT(1, ilevel);\r
116             ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);\r
117         }\r
118 \r
119         tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1,\r
120                                            flags, cb, app_key);\r
121         if(tmper.encoded == -1) return tmper;\r
122         er.encoded += tmper.encoded;\r
123         if(tmper.encoded == 0 && specs->as_XMLValueList) {\r
124             const char *name = elm->type->xml_tag;\r
125             size_t len = strlen(name);\r
126             if(!xcan) ASN__TEXT_INDENT(1, ilevel + 1);\r
127             ASN__CALLBACK3("<", 1, name, len, "/>", 2);\r
128         }\r
129 \r
130         if(mname) {\r
131             ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);\r
132         }\r
133     }\r
134 \r
135     if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);\r
136 \r
137     ASN__ENCODED_OK(er);\r
138 cb_failed:\r
139     ASN__ENCODE_FAILED;\r
140 }\r
141 \r
142 #ifndef ASN_DISABLE_PER_SUPPORT\r
143 \r
144 asn_enc_rval_t\r
145 SEQUENCE_OF_encode_uper(const asn_TYPE_descriptor_t *td,\r
146                         const asn_per_constraints_t *constraints,\r
147                         const void *sptr, asn_per_outp_t *po) {\r
148     const asn_anonymous_sequence_ *list;\r
149         const asn_per_constraint_t *ct;\r
150         asn_enc_rval_t er = {0,0,0};\r
151         const asn_TYPE_member_t *elm = td->elements;\r
152         size_t encoded_edx;\r
153 \r
154         if(!sptr) ASN__ENCODE_FAILED;\r
155     list = _A_CSEQUENCE_FROM_VOID(sptr);\r
156 \r
157     er.encoded = 0;\r
158 \r
159         ASN_DEBUG("Encoding %s as SEQUENCE OF (%d)", td->name, list->count);\r
160 \r
161     if(constraints) ct = &constraints->size;\r
162     else if(td->encoding_constraints.per_constraints)\r
163         ct = &td->encoding_constraints.per_constraints->size;\r
164     else ct = 0;\r
165 \r
166     /* If extensible constraint, check if size is in root */\r
167     if(ct) {\r
168         int not_in_root =\r
169             (list->count < ct->lower_bound || list->count > ct->upper_bound);\r
170         ASN_DEBUG("lb %ld ub %ld %s", ct->lower_bound, ct->upper_bound,\r
171                   ct->flags & APC_EXTENSIBLE ? "ext" : "fix");\r
172         if(ct->flags & APC_EXTENSIBLE) {\r
173             /* Declare whether size is in extension root */\r
174             if(per_put_few_bits(po, not_in_root, 1)) ASN__ENCODE_FAILED;\r
175             if(not_in_root) ct = 0;\r
176         } else if(not_in_root && ct->effective_bits >= 0) {\r
177             ASN__ENCODE_FAILED;\r
178         }\r
179 \r
180     }\r
181 \r
182     if(ct && ct->effective_bits >= 0) {\r
183         /* X.691, #19.5: No length determinant */\r
184         if(per_put_few_bits(po, list->count - ct->lower_bound,\r
185                             ct->effective_bits))\r
186             ASN__ENCODE_FAILED;\r
187     } else if(list->count == 0) {\r
188         /* When the list is empty add only the length determinant\r
189          * X.691, #20.6 and #11.9.4.1\r
190          */\r
191         if (uper_put_length(po, 0, 0)) {\r
192             ASN__ENCODE_FAILED;\r
193         }\r
194         ASN__ENCODED_OK(er);\r
195     }\r
196 \r
197     for(encoded_edx = 0; (ssize_t)encoded_edx < list->count;) {\r
198         ssize_t may_encode;\r
199         size_t edx;\r
200         int need_eom = 0;\r
201 \r
202         if(ct && ct->effective_bits >= 0) {\r
203             may_encode = list->count;\r
204         } else {\r
205             may_encode =\r
206                 uper_put_length(po, list->count - encoded_edx, &need_eom);\r
207             if(may_encode < 0) ASN__ENCODE_FAILED;\r
208         }\r
209 \r
210         for(edx = encoded_edx; edx < encoded_edx + may_encode; edx++) {\r
211             void *memb_ptr = list->array[edx];\r
212             if(!memb_ptr) ASN__ENCODE_FAILED;\r
213             er = elm->type->op->uper_encoder(\r
214                 elm->type, elm->encoding_constraints.per_constraints, memb_ptr,\r
215                 po);\r
216             if(er.encoded == -1) ASN__ENCODE_FAILED;\r
217         }\r
218 \r
219         if(need_eom && uper_put_length(po, 0, 0))\r
220             ASN__ENCODE_FAILED; /* End of Message length */\r
221 \r
222         encoded_edx += may_encode;\r
223     }\r
224 \r
225         ASN__ENCODED_OK(er);\r
226 }\r
227 \r
228 asn_enc_rval_t\r
229 SEQUENCE_OF_encode_aper(const asn_TYPE_descriptor_t *td,\r
230                         const asn_per_constraints_t *constraints,\r
231                         const void *sptr, asn_per_outp_t *po) {\r
232         const asn_anonymous_sequence_ *list;\r
233         const asn_per_constraint_t *ct;\r
234         asn_enc_rval_t er = {0,0,0};\r
235         asn_TYPE_member_t *elm = td->elements;\r
236         int seq;\r
237 \r
238         if(!sptr) ASN__ENCODE_FAILED;\r
239         list = _A_CSEQUENCE_FROM_VOID(sptr);\r
240 \r
241         er.encoded = 0;\r
242 \r
243         ASN_DEBUG("Encoding %s as SEQUENCE OF size (%d) using ALIGNED PER", td->name, list->count);\r
244 \r
245         if(constraints) ct = &constraints->size;\r
246         else if(td->encoding_constraints.per_constraints)\r
247                 ct = &td->encoding_constraints.per_constraints->size;\r
248         else ct = 0;\r
249 \r
250         /* If extensible constraint, check if size is in root */\r
251         if(ct) {\r
252                 int not_in_root = (list->count < ct->lower_bound\r
253                                 || list->count > ct->upper_bound);\r
254                 ASN_DEBUG("lb %ld ub %ld %s",\r
255                         ct->lower_bound, ct->upper_bound,\r
256                         ct->flags & APC_EXTENSIBLE ? "ext" : "fix");\r
257                 if(ct->flags & APC_EXTENSIBLE) {\r
258                         /* Declare whether size is in extension root */\r
259                         if(per_put_few_bits(po, not_in_root, 1))\r
260                                 ASN__ENCODE_FAILED;\r
261                         if(not_in_root) ct = 0;\r
262                 } else if(not_in_root && ct->effective_bits >= 0)\r
263                         ASN__ENCODE_FAILED;\r
264         }\r
265 \r
266         if(ct && ct->effective_bits >= 0) {\r
267                 /* X.691, #19.5: No length determinant */\r
268 /*               if(per_put_few_bits(po, list->count - ct->lower_bound,\r
269                                  ct->effective_bits))\r
270                          ASN__ENCODE_FAILED;\r
271 */\r
272                 if (aper_put_length(po, ct->upper_bound - ct->lower_bound + 1, list->count - ct->lower_bound) < 0)\r
273                         ASN__ENCODE_FAILED;\r
274         }\r
275 \r
276         for(seq = -1; seq < list->count;) {\r
277                 ssize_t mayEncode;\r
278                 if(seq < 0) seq = 0;\r
279                 if(ct && ct->effective_bits >= 0) {\r
280                         mayEncode = list->count;\r
281                 } else {\r
282                         mayEncode = aper_put_length(po, -1, list->count - seq);\r
283                         if(mayEncode < 0) ASN__ENCODE_FAILED;\r
284                 }\r
285 \r
286                 while(mayEncode--) {\r
287                         void *memb_ptr = list->array[seq++];\r
288                         if(!memb_ptr) ASN__ENCODE_FAILED;\r
289                         er = elm->type->op->aper_encoder(elm->type,\r
290                                 elm->encoding_constraints.per_constraints, memb_ptr, po);\r
291                         if(er.encoded == -1)\r
292                                 ASN__ENCODE_FAILED;\r
293                 }\r
294         }\r
295 \r
296         ASN__ENCODED_OK(er);\r
297 }\r
298 #endif  /* ASN_DISABLE_PER_SUPPORT */\r
299 \r
300 int\r
301 SEQUENCE_OF_compare(const asn_TYPE_descriptor_t *td, const void *aptr,\r
302                const void *bptr) {\r
303     const asn_anonymous_sequence_ *a = _A_CSEQUENCE_FROM_VOID(aptr);\r
304     const asn_anonymous_sequence_ *b = _A_CSEQUENCE_FROM_VOID(bptr);\r
305     ssize_t idx;\r
306 \r
307     if(a && b) {\r
308         ssize_t common_length = (a->count < b->count ? a->count : b->count);\r
309         for(idx = 0; idx < common_length; idx++) {\r
310             int ret = td->elements->type->op->compare_struct(\r
311                 td->elements->type, a->array[idx], b->array[idx]);\r
312             if(ret) return ret;\r
313         }\r
314 \r
315         if(idx < b->count) /* more elements in b */\r
316             return -1;    /* a is shorter, so put it first */\r
317         if(idx < a->count) return 1;\r
318 \r
319     } else if(!a) {\r
320         return -1;\r
321     } else if(!b) {\r
322         return 1;\r
323     }\r
324 \r
325     return 0;\r
326 }\r
327 \r
328 \r
329 asn_TYPE_operation_t asn_OP_SEQUENCE_OF = {\r
330         SEQUENCE_OF_free,\r
331         SEQUENCE_OF_print,\r
332         SEQUENCE_OF_compare,\r
333         SEQUENCE_OF_decode_ber,\r
334         SEQUENCE_OF_encode_der,\r
335         SEQUENCE_OF_decode_xer,\r
336         SEQUENCE_OF_encode_xer,\r
337 #ifdef  ASN_DISABLE_OER_SUPPORT\r
338         0,\r
339         0,\r
340 #else\r
341         SEQUENCE_OF_decode_oer, /* Same as SET OF decoder. */\r
342         SEQUENCE_OF_encode_oer, /* Same as SET OF encoder */\r
343 #endif  /* ASN_DISABLE_OER_SUPPORT */\r
344 #ifdef ASN_DISABLE_PER_SUPPORT\r
345         0,\r
346         0,\r
347         0,\r
348         0,\r
349 #else\r
350         SEQUENCE_OF_decode_uper, /* Same as SET OF decoder */\r
351         SEQUENCE_OF_encode_uper,\r
352         SEQUENCE_OF_decode_aper,\r
353         SEQUENCE_OF_encode_aper,\r
354 #endif /* ASN_DISABLE_PER_SUPPORT */\r
355         SEQUENCE_OF_random_fill,\r
356         0       /* Use generic outmost tag fetcher */\r
357 };\r
358 \r