Moving in e2sim originally from it/test/simulators
[sim/e2-interface.git] / e2sim / ASN1c / constraints.c
1 /*****************************************************************************
2 #                                                                            *
3 # Copyright 2019 AT&T Intellectual Property                                  *
4 #                                                                            *
5 # Licensed under the Apache License, Version 2.0 (the "License");            *
6 # you may not use this file except in compliance with the License.           *
7 # You may obtain a copy of the License at                                    *
8 #                                                                            *
9 #      http://www.apache.org/licenses/LICENSE-2.0                            *
10 #                                                                            *
11 # Unless required by applicable law or agreed to in writing, software        *
12 # distributed under the License is distributed on an "AS IS" BASIS,          *
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
14 # See the License for the specific language governing permissions and        *
15 # limitations under the License.                                             *
16 #                                                                            *
17 ******************************************************************************/
18
19 #include <asn_internal.h>
20 #include <constraints.h>
21
22 int
23 asn_generic_no_constraint(const asn_TYPE_descriptor_t *type_descriptor,
24                           const void *struct_ptr,
25                           asn_app_constraint_failed_f *cb, void *key) {
26     (void)type_descriptor;      /* Unused argument */
27         (void)struct_ptr;       /* Unused argument */
28         (void)cb;       /* Unused argument */
29         (void)key;      /* Unused argument */
30
31         /* Nothing to check */
32         return 0;
33 }
34
35 int
36 asn_generic_unknown_constraint(const asn_TYPE_descriptor_t *type_descriptor,
37                                const void *struct_ptr,
38                                asn_app_constraint_failed_f *cb, void *key) {
39     (void)type_descriptor;      /* Unused argument */
40         (void)struct_ptr;       /* Unused argument */
41         (void)cb;       /* Unused argument */
42         (void)key;      /* Unused argument */
43
44         /* Unknown how to check */
45         return 0;
46 }
47
48 struct errbufDesc {
49     const asn_TYPE_descriptor_t *failed_type;
50     const void *failed_struct_ptr;
51         char *errbuf;
52         size_t errlen;
53 };
54
55 static void
56 _asn_i_ctfailcb(void *key, const asn_TYPE_descriptor_t *td, const void *sptr,
57                 const char *fmt, ...) {
58     struct errbufDesc *arg = key;
59         va_list ap;
60         ssize_t vlen;
61         ssize_t maxlen;
62
63         arg->failed_type = td;
64         arg->failed_struct_ptr = sptr;
65
66         maxlen = arg->errlen;
67         if(maxlen <= 0)
68                 return;
69
70         va_start(ap, fmt);
71         vlen = vsnprintf(arg->errbuf, maxlen, fmt, ap);
72         va_end(ap);
73         if(vlen >= maxlen) {
74                 arg->errbuf[maxlen-1] = '\0';   /* Ensuring libc correctness */
75                 arg->errlen = maxlen - 1;       /* Not counting termination */
76                 return;
77         } else if(vlen >= 0) {
78                 arg->errbuf[vlen] = '\0';       /* Ensuring libc correctness */
79                 arg->errlen = vlen;             /* Not counting termination */
80         } else {
81                 /*
82                  * The libc on this system is broken.
83                  */
84                 vlen = sizeof("<broken vsnprintf>") - 1;
85                 maxlen--;
86                 arg->errlen = vlen < maxlen ? vlen : maxlen;
87                 memcpy(arg->errbuf, "<broken vsnprintf>", arg->errlen);
88                 arg->errbuf[arg->errlen] = 0;
89         }
90
91         return;
92 }
93
94 int
95 asn_check_constraints(const asn_TYPE_descriptor_t *type_descriptor,
96                       const void *struct_ptr, char *errbuf, size_t *errlen) {
97     struct errbufDesc arg;
98     int ret;
99
100     arg.failed_type = 0;
101     arg.failed_struct_ptr = 0;
102     arg.errbuf = errbuf;
103     arg.errlen = errlen ? *errlen : 0;
104
105     ret = type_descriptor->encoding_constraints.general_constraints(
106         type_descriptor, struct_ptr, _asn_i_ctfailcb, &arg);
107     if(ret == -1 && errlen) *errlen = arg.errlen;
108
109     return ret;
110 }
111