blob: 3ddd5a39875ea8f3ef04f19028cfad2ff5a7fe8b [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 Walkin59b176e2005-11-26 11:25:14 +000054 _ASN_ENCODED_OK(erval);
Lev Walkinf15320b2004-06-03 03:38:44 +000055 }
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];
Lev Walkinda9a3b82005-08-16 17:00:21 +000064 if(!memb_ptr) continue;
Lev Walkinf15320b2004-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
Lev Walkind9bd7752004-06-05 08:17:50 +000073 if(computed_size != (size_t)encoding_size) {
Lev Walkinf15320b2004-06-03 03:38:44 +000074 /*
75 * Encoded size is not equal to the computed size.
76 */
77 erval.encoded = -1;
Lev Walkin449f8322004-08-20 13:23:42 +000078 erval.failed_type = td;
Lev Walkinf15320b2004-06-03 03:38:44 +000079 erval.structure_ptr = ptr;
80 } else {
81 erval.encoded = computed_size;
Lev Walkind1bfea62005-11-08 03:06:16 +000082 erval.structure_ptr = 0;
83 erval.failed_type = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +000084 }
85
86 return erval;
87}
88
Lev Walkina9cc46e2004-09-22 16:06:28 +000089asn_enc_rval_t
Lev Walkin5e033762004-09-29 13:26:15 +000090SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
Lev Walkina9cc46e2004-09-22 16:06:28 +000091 int ilevel, enum xer_encoder_flags_e flags,
92 asn_app_consume_bytes_f *cb, void *app_key) {
93 asn_enc_rval_t er;
Lev Walkin5e033762004-09-29 13:26:15 +000094 asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
Lev Walkinda9a3b82005-08-16 17:00:21 +000095 asn_TYPE_member_t *elm = td->elements;
Lev Walkin7e033b52005-07-02 08:19:17 +000096 asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(sptr);
Lev Walkina9cc46e2004-09-22 16:06:28 +000097 const char *mname = specs->as_XMLValueList
Lev Walkinda9a3b82005-08-16 17:00:21 +000098 ? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag);
Lev Walkina9cc46e2004-09-22 16:06:28 +000099 unsigned int mlen = mname ? strlen(mname) : 0;
100 int xcan = (flags & XER_F_CANONICAL);
101 int i;
102
103 if(!sptr) _ASN_ENCODE_FAILED;
104
105 er.encoded = 0;
106
Lev Walkina9cc46e2004-09-22 16:06:28 +0000107 for(i = 0; i < list->count; i++) {
108 asn_enc_rval_t tmper;
Lev Walkina9cc46e2004-09-22 16:06:28 +0000109 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
Lev Walkinda9a3b82005-08-16 17:00:21 +0000117 tmper = elm->type->xer_encoder(elm->type, memb_ptr,
Lev Walkina9cc46e2004-09-22 16:06:28 +0000118 ilevel + 1, flags, cb, app_key);
119 if(tmper.encoded == -1) return tmper;
Lev Walkin642962a2005-02-24 22:37:07 +0000120 if(tmper.encoded == 0 && specs->as_XMLValueList) {
Lev Walkind1bfea62005-11-08 03:06:16 +0000121 const char *name = elm->type->xml_tag;
Lev Walkin642962a2005-02-24 22:37:07 +0000122 size_t len = strlen(name);
123 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel + 1);
124 _ASN_CALLBACK3("<", 1, name, len, "/>", 2);
125 }
Lev Walkina9cc46e2004-09-22 16:06:28 +0000126
127 if(mname) {
128 _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
129 er.encoded += 5;
130 }
131
132 er.encoded += (2 * mlen) + tmper.encoded;
133 }
134
135 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
136
Lev Walkin59b176e2005-11-26 11:25:14 +0000137 _ASN_ENCODED_OK(er);
Lev Walkin942fd082004-10-03 09:13:02 +0000138cb_failed:
139 _ASN_ENCODE_FAILED;
Lev Walkina9cc46e2004-09-22 16:06:28 +0000140}
141