blob: d9763fc651571b491887050f1bce6997638b2039 [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];
30 erval = elm->type->der_encoder(elm->type, memb_ptr,
31 0, elm->tag,
32 0, 0);
33 if(erval.encoded == -1)
34 return erval;
35 computed_size += erval.encoded;
36 }
37
38 /*
39 * Encode the TLV for the sequence itself.
40 */
vlm6678cb12004-09-26 13:10:40 +000041 encoding_size = der_write_tags(td, computed_size, tag_mode, 1, tag,
vlmfa67ddc2004-06-03 03:38:44 +000042 cb, app_key);
43 if(encoding_size == -1) {
44 erval.encoded = -1;
vlme413c122004-08-20 13:23:42 +000045 erval.failed_type = td;
vlmfa67ddc2004-06-03 03:38:44 +000046 erval.structure_ptr = ptr;
47 return erval;
48 }
49
50 computed_size += encoding_size;
51 if(!cb) {
52 erval.encoded = computed_size;
53 return erval;
54 }
55
vlme413c122004-08-20 13:23:42 +000056 ASN_DEBUG("Encoding members of SEQUENCE OF %s", td->name);
vlmfa67ddc2004-06-03 03:38:44 +000057
58 /*
59 * Encode all members.
60 */
61 for(edx = 0; edx < list->count; edx++) {
62 void *memb_ptr = list->array[edx];
63 erval = elm->type->der_encoder(elm->type, memb_ptr,
64 0, elm->tag,
65 cb, app_key);
66 if(erval.encoded == -1)
67 return erval;
68 encoding_size += erval.encoded;
69 }
70
vlmb42843a2004-06-05 08:17:50 +000071 if(computed_size != (size_t)encoding_size) {
vlmfa67ddc2004-06-03 03:38:44 +000072 /*
73 * Encoded size is not equal to the computed size.
74 */
75 erval.encoded = -1;
vlme413c122004-08-20 13:23:42 +000076 erval.failed_type = td;
vlmfa67ddc2004-06-03 03:38:44 +000077 erval.structure_ptr = ptr;
78 } else {
79 erval.encoded = computed_size;
80 }
81
82 return erval;
83}
84
vlm39ba4c42004-09-22 16:06:28 +000085asn_enc_rval_t
vlmef6355b2004-09-29 13:26:15 +000086SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
vlm39ba4c42004-09-22 16:06:28 +000087 int ilevel, enum xer_encoder_flags_e flags,
88 asn_app_consume_bytes_f *cb, void *app_key) {
89 asn_enc_rval_t er;
vlmef6355b2004-09-29 13:26:15 +000090 asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
91 asn_TYPE_member_t *element = td->elements;
vlm41dee122005-07-02 08:19:17 +000092 asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(sptr);
vlm39ba4c42004-09-22 16:06:28 +000093 const char *mname = specs->as_XMLValueList
vlm9de248e2004-10-20 15:50:55 +000094 ? 0 : ((*element->name)
95 ? element->name : element->type->xml_tag);
vlm39ba4c42004-09-22 16:06:28 +000096 unsigned int mlen = mname ? strlen(mname) : 0;
97 int xcan = (flags & XER_F_CANONICAL);
98 int i;
99
100 if(!sptr) _ASN_ENCODE_FAILED;
101
102 er.encoded = 0;
103
vlm39ba4c42004-09-22 16:06:28 +0000104 for(i = 0; i < list->count; i++) {
105 asn_enc_rval_t tmper;
106
107 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
115 tmper = element->type->xer_encoder(element->type, memb_ptr,
116 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) {
119 const char *name = (*element->name)
120 ? element->name : element->type->xml_tag;
121 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