blob: f126d78a11d7a1fa6c9fbd9a45dcccf7ee747b98 [file] [log] [blame]
Lev Walkinf15320b2004-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 */
Lev Walkina9cc46e2004-09-22 16:06:28 +00005#include <asn_internal.h>
Lev Walkinf15320b2004-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 */
Lev Walkina9cc46e2004-09-22 16:06:28 +000012asn_enc_rval_t
Lev Walkin5e033762004-09-29 13:26:15 +000013SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
Lev Walkinf15320b2004-06-03 03:38:44 +000014 int tag_mode, ber_tlv_tag_t tag,
15 asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkin5e033762004-09-29 13:26:15 +000016 asn_TYPE_member_t *elm = td->elements;
Lev Walkinc2346572004-08-11 09:07:36 +000017 A_SEQUENCE_OF(void) *list;
Lev Walkinf15320b2004-06-03 03:38:44 +000018 size_t computed_size = 0;
19 ssize_t encoding_size = 0;
Lev Walkina9cc46e2004-09-22 16:06:28 +000020 asn_enc_rval_t erval;
Lev Walkinf15320b2004-06-03 03:38:44 +000021 int edx;
22
Lev Walkin449f8322004-08-20 13:23:42 +000023 ASN_DEBUG("Estimating size of SEQUENCE OF %s", td->name);
Lev Walkinf15320b2004-06-03 03:38:44 +000024
25 /*
26 * Gather the length of the underlying members sequence.
27 */
Lev Walkinabc76b02005-01-27 17:55:42 +000028 (void *)list = ptr;
Lev Walkinf15320b2004-06-03 03:38:44 +000029 for(edx = 0; edx < list->count; edx++) {
30 void *memb_ptr = list->array[edx];
31 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 */
Lev Walkin8e8078a2004-09-26 13:10:40 +000042 encoding_size = der_write_tags(td, computed_size, tag_mode, 1, tag,
Lev Walkinf15320b2004-06-03 03:38:44 +000043 cb, app_key);
44 if(encoding_size == -1) {
45 erval.encoded = -1;
Lev Walkin449f8322004-08-20 13:23:42 +000046 erval.failed_type = td;
Lev Walkinf15320b2004-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
Lev Walkin449f8322004-08-20 13:23:42 +000057 ASN_DEBUG("Encoding members of SEQUENCE OF %s", td->name);
Lev Walkinf15320b2004-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];
64 erval = elm->type->der_encoder(elm->type, memb_ptr,
65 0, elm->tag,
66 cb, app_key);
67 if(erval.encoded == -1)
68 return erval;
69 encoding_size += erval.encoded;
70 }
71
Lev Walkind9bd7752004-06-05 08:17:50 +000072 if(computed_size != (size_t)encoding_size) {
Lev Walkinf15320b2004-06-03 03:38:44 +000073 /*
74 * Encoded size is not equal to the computed size.
75 */
76 erval.encoded = -1;
Lev Walkin449f8322004-08-20 13:23:42 +000077 erval.failed_type = td;
Lev Walkinf15320b2004-06-03 03:38:44 +000078 erval.structure_ptr = ptr;
79 } else {
80 erval.encoded = computed_size;
81 }
82
83 return erval;
84}
85
Lev Walkina9cc46e2004-09-22 16:06:28 +000086asn_enc_rval_t
Lev Walkin5e033762004-09-29 13:26:15 +000087SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
Lev Walkina9cc46e2004-09-22 16:06:28 +000088 int ilevel, enum xer_encoder_flags_e flags,
89 asn_app_consume_bytes_f *cb, void *app_key) {
90 asn_enc_rval_t er;
Lev Walkin5e033762004-09-29 13:26:15 +000091 asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
92 asn_TYPE_member_t *element = td->elements;
Lev Walkina9cc46e2004-09-22 16:06:28 +000093 A_SEQUENCE_OF(void) *list;
94 const char *mname = specs->as_XMLValueList
Lev Walkindc06f6b2004-10-20 15:50:55 +000095 ? 0 : ((*element->name)
96 ? element->name : element->type->xml_tag);
Lev Walkina9cc46e2004-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
Lev Walkinabc76b02005-01-27 17:55:42 +0000105 (void *)list = sptr;
Lev Walkina9cc46e2004-09-22 16:06:28 +0000106 for(i = 0; i < list->count; i++) {
107 asn_enc_rval_t tmper;
108
109 void *memb_ptr = list->array[i];
110 if(!memb_ptr) continue;
111
112 if(mname) {
113 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
114 _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
115 }
116
117 tmper = element->type->xer_encoder(element->type, memb_ptr,
118 ilevel + 1, flags, cb, app_key);
119 if(tmper.encoded == -1) return tmper;
120
121 if(mname) {
122 _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
123 er.encoded += 5;
124 }
125
126 er.encoded += (2 * mlen) + tmper.encoded;
127 }
128
129 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
130
131 return er;
Lev Walkin942fd082004-10-03 09:13:02 +0000132cb_failed:
133 _ASN_ENCODE_FAILED;
Lev Walkina9cc46e2004-09-22 16:06:28 +0000134}
135