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