blob: 0a58f09a175805e3acd7c9d59a06ff6545c9ced2 [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 */
5#include <constr_SEQUENCE_OF.h>
6#include <asn_SEQUENCE_OF.h>
7
8/*
9 * The DER encoder of the SEQUENCE OF type.
10 */
11der_enc_rval_t
Lev Walkin449f8322004-08-20 13:23:42 +000012SEQUENCE_OF_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
Lev Walkinf15320b2004-06-03 03:38:44 +000013 int tag_mode, ber_tlv_tag_t tag,
14 asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkin449f8322004-08-20 13:23:42 +000015 asn1_TYPE_member_t *elm = td->elements;
Lev Walkinc2346572004-08-11 09:07:36 +000016 A_SEQUENCE_OF(void) *list;
Lev Walkinf15320b2004-06-03 03:38:44 +000017 size_t computed_size = 0;
18 ssize_t encoding_size = 0;
19 der_enc_rval_t erval;
20 int edx;
21
Lev Walkin449f8322004-08-20 13:23:42 +000022 ASN_DEBUG("Estimating size of SEQUENCE OF %s", td->name);
Lev Walkinf15320b2004-06-03 03:38:44 +000023
24 /*
25 * Gather the length of the underlying members sequence.
26 */
Lev Walkinc2346572004-08-11 09:07:36 +000027 (void *)list = ptr;
Lev Walkinf15320b2004-06-03 03:38:44 +000028 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 */
Lev Walkin449f8322004-08-20 13:23:42 +000041 encoding_size = der_write_tags(td, computed_size, tag_mode, tag,
Lev Walkinf15320b2004-06-03 03:38:44 +000042 cb, app_key);
43 if(encoding_size == -1) {
44 erval.encoded = -1;
Lev Walkin449f8322004-08-20 13:23:42 +000045 erval.failed_type = td;
Lev Walkinf15320b2004-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
Lev Walkin449f8322004-08-20 13:23:42 +000056 ASN_DEBUG("Encoding members of SEQUENCE OF %s", td->name);
Lev Walkinf15320b2004-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
Lev Walkind9bd7752004-06-05 08:17:50 +000071 if(computed_size != (size_t)encoding_size) {
Lev Walkinf15320b2004-06-03 03:38:44 +000072 /*
73 * Encoded size is not equal to the computed size.
74 */
75 erval.encoded = -1;
Lev Walkin449f8322004-08-20 13:23:42 +000076 erval.failed_type = td;
Lev Walkinf15320b2004-06-03 03:38:44 +000077 erval.structure_ptr = ptr;
78 } else {
79 erval.encoded = computed_size;
80 }
81
82 return erval;
83}
84