blob: be2ed60bbcd9a23a65885c83c8b5dd395c486c8b [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
vlme413c122004-08-20 13:23:42 +000013SEQUENCE_OF_encode_der(asn1_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) {
vlme413c122004-08-20 13:23:42 +000016 asn1_TYPE_member_t *elm = td->elements;
vlmda674682004-08-11 09:07:36 +000017 A_SEQUENCE_OF(void) *list;
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 */
vlmda674682004-08-11 09:07:36 +000028 (void *)list = ptr;
vlmfa67ddc2004-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 */
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];
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
vlmb42843a2004-06-05 08:17:50 +000072 if(computed_size != (size_t)encoding_size) {
vlmfa67ddc2004-06-03 03:38:44 +000073 /*
74 * Encoded size is not equal to the computed size.
75 */
76 erval.encoded = -1;
vlme413c122004-08-20 13:23:42 +000077 erval.failed_type = td;
vlmfa67ddc2004-06-03 03:38:44 +000078 erval.structure_ptr = ptr;
79 } else {
80 erval.encoded = computed_size;
81 }
82
83 return erval;
84}
85
vlm39ba4c42004-09-22 16:06:28 +000086asn_enc_rval_t
87SEQUENCE_OF_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
88 int ilevel, enum xer_encoder_flags_e flags,
89 asn_app_consume_bytes_f *cb, void *app_key) {
90 asn_enc_rval_t er;
91 asn1_SET_OF_specifics_t *specs = (asn1_SET_OF_specifics_t *)td->specifics;
92 asn1_TYPE_member_t *element = td->elements;
93 A_SEQUENCE_OF(void) *list;
94 const char *mname = specs->as_XMLValueList
95 ? 0 : ((*element->name) ? element->name : element->type->name);
96 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
104 (void *)list = sptr;
105 for(i = 0; i < list->count; i++) {
106 asn_enc_rval_t tmper;
107
108 void *memb_ptr = list->array[i];
109 if(!memb_ptr) continue;
110
111 if(mname) {
112 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
113 _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
114 }
115
116 tmper = element->type->xer_encoder(element->type, memb_ptr,
117 ilevel + 1, flags, cb, app_key);
118 if(tmper.encoded == -1) return tmper;
119
120 if(mname) {
121 _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
122 er.encoded += 5;
123 }
124
125 er.encoded += (2 * mlen) + tmper.encoded;
126 }
127
128 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
129
130 return er;
131}
132