2 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
4 * Redistribution and modifications are permitted subject to BSD license.
6 #include <asn_internal.h>
7 #include <constr_SET_OF.h>
9 asn_random_fill_result_t
10 SET_OF_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
11 const asn_encoding_constraints_t *constraints,
13 const asn_SET_OF_specifics_t *specs =
14 (const asn_SET_OF_specifics_t *)td->specifics;
15 asn_random_fill_result_t res_ok = {ARFILL_OK, 0};
16 asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
17 asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
18 const asn_TYPE_member_t *elm = td->elements;
20 long max_elements = 5;
21 long slb = 0; /* Lower size bound */
22 long sub = 0; /* Upper size bound */
25 if(max_length == 0) return result_skipped;
28 st = (*sptr = CALLOC(1, specs->struct_size));
34 switch(asn_random_between(0, 6)) {
35 case 0: max_elements = 0; break;
36 case 1: max_elements = 1; break;
37 case 2: max_elements = 5; break;
38 case 3: max_elements = max_length; break;
39 case 4: max_elements = max_length / 2; break;
40 case 5: max_elements = max_length / 4; break;
43 sub = slb + max_elements;
45 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
46 if(!constraints || !constraints->per_constraints)
47 constraints = &td->encoding_constraints;
48 if(constraints->per_constraints) {
49 const asn_per_constraint_t *pc = &constraints->per_constraints->size;
50 if(pc->flags & APC_SEMI_CONSTRAINED) {
51 slb = pc->lower_bound;
52 sub = pc->lower_bound + max_elements;
53 } else if(pc->flags & APC_CONSTRAINED) {
54 slb = pc->lower_bound;
55 sub = pc->upper_bound;
56 if(sub - slb > max_elements) sub = slb + max_elements;
60 if(!constraints) constraints = &td->encoding_constraints;
61 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
63 /* Bias towards edges of allowed space */
64 switch(asn_random_between(-1, 4)) {
67 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
68 /* Prepare lengths somewhat outside of constrained range. */
69 if(constraints->per_constraints
70 && (constraints->per_constraints->size.flags & APC_EXTENSIBLE)) {
71 switch(asn_random_between(0, 5)) {
84 rnd_len = asn_random_between(0, slb);
87 if(sub < (ssize_t)max_length) {
94 if(sub < (ssize_t)max_length) {
95 rnd_len = asn_random_between(sub + 1, max_length);
101 rnd_len = max_length;
106 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
109 rnd_len = asn_random_between(slb, sub);
113 rnd_len = asn_random_between(slb + 1, sub);
118 rnd_len = asn_random_between(slb, slb);
122 rnd_len = asn_random_between(slb, sub - 1);
127 rnd_len = asn_random_between(sub, sub);
131 for(; rnd_len > 0; rnd_len--) {
132 asn_anonymous_set_ *list = _A_SET_FROM_VOID(st);
134 asn_random_fill_result_t tmpres = elm->type->op->random_fill(
135 elm->type, &ptr, &elm->encoding_constraints,
136 (max_length > res_ok.length ? max_length - res_ok.length : 0)
138 switch(tmpres.code) {
140 ASN_SET_ADD(list, ptr);
141 res_ok.length += tmpres.length;