blob: 55307649e8a3a2f1019e9eccad1e7ca6b53862a3 [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001/*-
2 * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
4 */
vlm39ba4c42004-09-22 16:06:28 +00005#include <asn_internal.h>
vlmfa67ddc2004-06-03 03:38:44 +00006#include <constr_SEQUENCE_OF.h>
7#include <asn_SEQUENCE_OF.h>
8
9/*
10 * The DER encoder of the SEQUENCE OF type.
11 */
vlm39ba4c42004-09-22 16:06:28 +000012asn_enc_rval_t
vlmef6355b2004-09-29 13:26:15 +000013SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
vlmfa67ddc2004-06-03 03:38:44 +000014 int tag_mode, ber_tlv_tag_t tag,
15 asn_app_consume_bytes_f *cb, void *app_key) {
vlmef6355b2004-09-29 13:26:15 +000016 asn_TYPE_member_t *elm = td->elements;
vlm41dee122005-07-02 08:19:17 +000017 asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(ptr);
vlmfa67ddc2004-06-03 03:38:44 +000018 size_t computed_size = 0;
19 ssize_t encoding_size = 0;
vlm39ba4c42004-09-22 16:06:28 +000020 asn_enc_rval_t erval;
vlmfa67ddc2004-06-03 03:38:44 +000021 int edx;
22
vlme413c122004-08-20 13:23:42 +000023 ASN_DEBUG("Estimating size of SEQUENCE OF %s", td->name);
vlmfa67ddc2004-06-03 03:38:44 +000024
25 /*
26 * Gather the length of the underlying members sequence.
27 */
28 for(edx = 0; edx < list->count; edx++) {
29 void *memb_ptr = list->array[edx];
vlm5a6fc652005-08-16 17:00:21 +000030 if(!memb_ptr) continue;
vlmfa67ddc2004-06-03 03:38:44 +000031 erval = elm->type->der_encoder(elm->type, memb_ptr,
32 0, elm->tag,
33 0, 0);
34 if(erval.encoded == -1)
35 return erval;
36 computed_size += erval.encoded;
37 }
38
39 /*
40 * Encode the TLV for the sequence itself.
41 */
vlm6678cb12004-09-26 13:10:40 +000042 encoding_size = der_write_tags(td, computed_size, tag_mode, 1, tag,
vlmfa67ddc2004-06-03 03:38:44 +000043 cb, app_key);
44 if(encoding_size == -1) {
45 erval.encoded = -1;
vlme413c122004-08-20 13:23:42 +000046 erval.failed_type = td;
vlmfa67ddc2004-06-03 03:38:44 +000047 erval.structure_ptr = ptr;
48 return erval;
49 }
50
51 computed_size += encoding_size;
52 if(!cb) {
53 erval.encoded = computed_size;
54 return erval;
55 }
56
vlme413c122004-08-20 13:23:42 +000057 ASN_DEBUG("Encoding members of SEQUENCE OF %s", td->name);
vlmfa67ddc2004-06-03 03:38:44 +000058
59 /*
60 * Encode all members.
61 */
62 for(edx = 0; edx < list->count; edx++) {
63 void *memb_ptr = list->array[edx];
vlm5a6fc652005-08-16 17:00:21 +000064 if(!memb_ptr) continue;
vlmfa67ddc2004-06-03 03:38:44 +000065 erval = elm->type->der_encoder(elm->type, memb_ptr,
66 0, elm->tag,
67 cb, app_key);
68 if(erval.encoded == -1)
69 return erval;
70 encoding_size += erval.encoded;
71 }
72
vlmb42843a2004-06-05 08:17:50 +000073 if(computed_size != (size_t)encoding_size) {
vlmfa67ddc2004-06-03 03:38:44 +000074 /*
75 * Encoded size is not equal to the computed size.
76 */
77 erval.encoded = -1;
vlme413c122004-08-20 13:23:42 +000078 erval.failed_type = td;
vlmfa67ddc2004-06-03 03:38:44 +000079 erval.structure_ptr = ptr;
80 } else {
81 erval.encoded = computed_size;
82 }
83
84 return erval;
85}
86
vlm39ba4c42004-09-22 16:06:28 +000087asn_enc_rval_t
vlmef6355b2004-09-29 13:26:15 +000088SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
vlm39ba4c42004-09-22 16:06:28 +000089 int ilevel, enum xer_encoder_flags_e flags,
90 asn_app_consume_bytes_f *cb, void *app_key) {
91 asn_enc_rval_t er;
vlmef6355b2004-09-29 13:26:15 +000092 asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
vlm5a6fc652005-08-16 17:00:21 +000093 asn_TYPE_member_t *elm = td->elements;
vlm41dee122005-07-02 08:19:17 +000094 asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(sptr);
vlm39ba4c42004-09-22 16:06:28 +000095 const char *mname = specs->as_XMLValueList
vlm5a6fc652005-08-16 17:00:21 +000096 ? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag);
vlm39ba4c42004-09-22 16:06:28 +000097 unsigned int mlen = mname ? strlen(mname) : 0;
98 int xcan = (flags & XER_F_CANONICAL);
99 int i;
100
101 if(!sptr) _ASN_ENCODE_FAILED;
102
103 er.encoded = 0;
104
vlm39ba4c42004-09-22 16:06:28 +0000105 for(i = 0; i < list->count; i++) {
106 asn_enc_rval_t tmper;
vlm39ba4c42004-09-22 16:06:28 +0000107 void *memb_ptr = list->array[i];
108 if(!memb_ptr) continue;
109
110 if(mname) {
111 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
112 _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
113 }
114
vlm5a6fc652005-08-16 17:00:21 +0000115 tmper = elm->type->xer_encoder(elm->type, memb_ptr,
vlm39ba4c42004-09-22 16:06:28 +0000116 ilevel + 1, flags, cb, app_key);
117 if(tmper.encoded == -1) return tmper;
vlmaa930cb2005-02-24 22:37:07 +0000118 if(tmper.encoded == 0 && specs->as_XMLValueList) {
vlm5a6fc652005-08-16 17:00:21 +0000119 const char *name = (*elm->name)
120 ? elm->name : elm->type->xml_tag;
vlmaa930cb2005-02-24 22:37:07 +0000121 size_t len = strlen(name);
122 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel + 1);
123 _ASN_CALLBACK3("<", 1, name, len, "/>", 2);
124 }
vlm39ba4c42004-09-22 16:06:28 +0000125
126 if(mname) {
127 _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
128 er.encoded += 5;
129 }
130
131 er.encoded += (2 * mlen) + tmper.encoded;
132 }
133
134 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
135
136 return er;
vlm84d551b2004-10-03 09:13:02 +0000137cb_failed:
138 _ASN_ENCODE_FAILED;
vlm39ba4c42004-09-22 16:06:28 +0000139}
140