blob: 12233a6c1fd34b4126fdd8c76af465d6b26c1e34 [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 Walkin7e033b52005-07-02 08:19:17 +000017 asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(ptr);
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 */
28 for(edx = 0; edx < list->count; edx++) {
29 void *memb_ptr = list->array[edx];
Lev Walkinda9a3b82005-08-16 17:00:21 +000030 if(!memb_ptr) continue;
Lev Walkinf15320b2004-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 */
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;
Lev Walkind1bfea62005-11-08 03:06:16 +000054 erval.structure_ptr = 0;
55 erval.failed_type = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +000056 return erval;
57 }
58
Lev Walkin449f8322004-08-20 13:23:42 +000059 ASN_DEBUG("Encoding members of SEQUENCE OF %s", td->name);
Lev Walkinf15320b2004-06-03 03:38:44 +000060
61 /*
62 * Encode all members.
63 */
64 for(edx = 0; edx < list->count; edx++) {
65 void *memb_ptr = list->array[edx];
Lev Walkinda9a3b82005-08-16 17:00:21 +000066 if(!memb_ptr) continue;
Lev Walkinf15320b2004-06-03 03:38:44 +000067 erval = elm->type->der_encoder(elm->type, memb_ptr,
68 0, elm->tag,
69 cb, app_key);
70 if(erval.encoded == -1)
71 return erval;
72 encoding_size += erval.encoded;
73 }
74
Lev Walkind9bd7752004-06-05 08:17:50 +000075 if(computed_size != (size_t)encoding_size) {
Lev Walkinf15320b2004-06-03 03:38:44 +000076 /*
77 * Encoded size is not equal to the computed size.
78 */
79 erval.encoded = -1;
Lev Walkin449f8322004-08-20 13:23:42 +000080 erval.failed_type = td;
Lev Walkinf15320b2004-06-03 03:38:44 +000081 erval.structure_ptr = ptr;
82 } else {
83 erval.encoded = computed_size;
Lev Walkind1bfea62005-11-08 03:06:16 +000084 erval.structure_ptr = 0;
85 erval.failed_type = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +000086 }
87
88 return erval;
89}
90
Lev Walkina9cc46e2004-09-22 16:06:28 +000091asn_enc_rval_t
Lev Walkin5e033762004-09-29 13:26:15 +000092SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
Lev Walkina9cc46e2004-09-22 16:06:28 +000093 int ilevel, enum xer_encoder_flags_e flags,
94 asn_app_consume_bytes_f *cb, void *app_key) {
95 asn_enc_rval_t er;
Lev Walkin5e033762004-09-29 13:26:15 +000096 asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
Lev Walkinda9a3b82005-08-16 17:00:21 +000097 asn_TYPE_member_t *elm = td->elements;
Lev Walkin7e033b52005-07-02 08:19:17 +000098 asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(sptr);
Lev Walkina9cc46e2004-09-22 16:06:28 +000099 const char *mname = specs->as_XMLValueList
Lev Walkinda9a3b82005-08-16 17:00:21 +0000100 ? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag);
Lev Walkina9cc46e2004-09-22 16:06:28 +0000101 unsigned int mlen = mname ? strlen(mname) : 0;
102 int xcan = (flags & XER_F_CANONICAL);
103 int i;
104
105 if(!sptr) _ASN_ENCODE_FAILED;
106
107 er.encoded = 0;
108
Lev Walkina9cc46e2004-09-22 16:06:28 +0000109 for(i = 0; i < list->count; i++) {
110 asn_enc_rval_t tmper;
Lev Walkina9cc46e2004-09-22 16:06:28 +0000111 void *memb_ptr = list->array[i];
112 if(!memb_ptr) continue;
113
114 if(mname) {
115 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
116 _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
117 }
118
Lev Walkinda9a3b82005-08-16 17:00:21 +0000119 tmper = elm->type->xer_encoder(elm->type, memb_ptr,
Lev Walkina9cc46e2004-09-22 16:06:28 +0000120 ilevel + 1, flags, cb, app_key);
121 if(tmper.encoded == -1) return tmper;
Lev Walkin642962a2005-02-24 22:37:07 +0000122 if(tmper.encoded == 0 && specs->as_XMLValueList) {
Lev Walkind1bfea62005-11-08 03:06:16 +0000123 const char *name = elm->type->xml_tag;
Lev Walkin642962a2005-02-24 22:37:07 +0000124 size_t len = strlen(name);
125 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel + 1);
126 _ASN_CALLBACK3("<", 1, name, len, "/>", 2);
127 }
Lev Walkina9cc46e2004-09-22 16:06:28 +0000128
129 if(mname) {
130 _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
131 er.encoded += 5;
132 }
133
134 er.encoded += (2 * mlen) + tmper.encoded;
135 }
136
137 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
138
139 return er;
Lev Walkin942fd082004-10-03 09:13:02 +0000140cb_failed:
141 _ASN_ENCODE_FAILED;
Lev Walkina9cc46e2004-09-22 16:06:28 +0000142}
143