blob: a7dce959aca58b830fe4d5ea2b80d86a6cd57244 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include <constraints.h>
2#include <constr_TYPE.h>
3
4int
5asn_generic_no_constraint(asn1_TYPE_descriptor_t *type_descriptor,
6 const void *struct_ptr, asn_app_consume_bytes_f *cb, void *key) {
Lev Walkind9bd7752004-06-05 08:17:50 +00007
8 (void)type_descriptor; /* Unused argument */
9 (void)struct_ptr; /* Unused argument */
10 (void)cb; /* Unused argument */
11 (void)key; /* Unused argument */
12
Lev Walkinf15320b2004-06-03 03:38:44 +000013 /* Nothing to check */
14 return 0;
15}
16
17int
18asn_generic_unknown_constraint(asn1_TYPE_descriptor_t *type_descriptor,
19 const void *struct_ptr, asn_app_consume_bytes_f *cb, void *key) {
Lev Walkind9bd7752004-06-05 08:17:50 +000020
21 (void)type_descriptor; /* Unused argument */
22 (void)struct_ptr; /* Unused argument */
23 (void)cb; /* Unused argument */
24 (void)key; /* Unused argument */
25
Lev Walkinf15320b2004-06-03 03:38:44 +000026 /* Unknown how to check */
27 return 0;
28}
29
30struct __fill_errbuf_arg {
31 char *errbuf;
32 size_t errlen;
33 size_t erroff;
34};
35
36static int
37__fill_errbuf(const void *buffer, size_t size, void *app_key) {
Lev Walkinc2346572004-08-11 09:07:36 +000038 struct __fill_errbuf_arg *arg = (struct __fill_errbuf_arg *)app_key;
Lev Walkinf15320b2004-06-03 03:38:44 +000039 size_t avail = arg->errlen - arg->erroff;
40
41 if(avail > size)
42 avail = size + 1;
43
44 switch(avail) {
45 default:
46 memcpy(arg->errbuf + arg->erroff, buffer, avail - 1);
47 arg->erroff += avail - 1;
48 case 1:
49 arg->errbuf[arg->erroff] = '\0';
50 case 0:
51 return 0;
52 }
53
54}
55
56int
57asn_check_constraints(asn1_TYPE_descriptor_t *type_descriptor,
58 const void *struct_ptr, char *errbuf, size_t *errlen) {
59
60 if(errlen) {
61 struct __fill_errbuf_arg arg;
62 int ret;
63
64 arg.errbuf = errbuf;
65 arg.errlen = *errlen;
66 arg.erroff = 0;
67
68 ret = type_descriptor->check_constraints(type_descriptor,
69 struct_ptr, __fill_errbuf, &arg);
70
71 if(ret == -1)
72 *errlen = arg.erroff;
73
74 return ret;
75 } else {
76 return type_descriptor->check_constraints(type_descriptor,
77 struct_ptr, 0, 0);
78 }
79}
80
81void
82_asn_i_log_error(asn_app_consume_bytes_f *cb, void *key, const char *fmt, ...) {
83 char buf[64];
84 char *p;
85 va_list ap;
86 ssize_t ret;
87 size_t len;
88
89 va_start(ap, fmt);
90 ret = vsnprintf(buf, sizeof(buf), fmt, ap);
91 va_end(ap);
92 if(ret < 0) {
93 /*
94 * The libc on this system is broken.
95 */
96 ret = sizeof("<broken vsnprintf>") - 1;
97 memcpy(buf, "<broken vsnprintf>", ret + 1);
98 /* Fall through */
99 }
100
Lev Walkind9bd7752004-06-05 08:17:50 +0000101 if(ret < (ssize_t)sizeof(buf)) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000102 cb(buf, ret, key);
103 return;
104 }
105
106 /*
107 * More space required to hold the message.
108 */
109 len = ret + 1;
Lev Walkinc2346572004-08-11 09:07:36 +0000110 p = (char *)alloca(len);
Lev Walkin7e0d2cb2004-08-11 07:41:45 +0000111 if(!p) return; /* Can fail on !x86. */
Lev Walkinf15320b2004-06-03 03:38:44 +0000112
113
114 va_start(ap, fmt);
115 ret = vsnprintf(buf, len, fmt, ap);
116 va_end(ap);
Lev Walkind9bd7752004-06-05 08:17:50 +0000117 if(ret < 0 || ret >= (ssize_t)len) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000118 ret = sizeof("<broken vsnprintf>") - 1;
119 memcpy(buf, "<broken vsnprintf>", ret + 1);
120 }
121
122 cb(buf, ret, key);
123}