--- /dev/null
+#include <asn_internal.h>\r
+#include <constraints.h>\r
+\r
+int\r
+asn_generic_no_constraint(const asn_TYPE_descriptor_t *type_descriptor,\r
+ const void *struct_ptr,\r
+ asn_app_constraint_failed_f *cb, void *key) {\r
+ (void)type_descriptor; /* Unused argument */\r
+ (void)struct_ptr; /* Unused argument */\r
+ (void)cb; /* Unused argument */\r
+ (void)key; /* Unused argument */\r
+\r
+ /* Nothing to check */\r
+ return 0;\r
+}\r
+\r
+int\r
+asn_generic_unknown_constraint(const asn_TYPE_descriptor_t *type_descriptor,\r
+ const void *struct_ptr,\r
+ asn_app_constraint_failed_f *cb, void *key) {\r
+ (void)type_descriptor; /* Unused argument */\r
+ (void)struct_ptr; /* Unused argument */\r
+ (void)cb; /* Unused argument */\r
+ (void)key; /* Unused argument */\r
+\r
+ /* Unknown how to check */\r
+ return 0;\r
+}\r
+\r
+struct errbufDesc {\r
+ const asn_TYPE_descriptor_t *failed_type;\r
+ const void *failed_struct_ptr;\r
+ char *errbuf;\r
+ size_t errlen;\r
+};\r
+\r
+static void\r
+_asn_i_ctfailcb(void *key, const asn_TYPE_descriptor_t *td, const void *sptr,\r
+ const char *fmt, ...) {\r
+ struct errbufDesc *arg = key;\r
+ va_list ap;\r
+ ssize_t vlen;\r
+ ssize_t maxlen;\r
+\r
+ arg->failed_type = td;\r
+ arg->failed_struct_ptr = sptr;\r
+\r
+ maxlen = arg->errlen;\r
+ if(maxlen <= 0)\r
+ return;\r
+\r
+ va_start(ap, fmt);\r
+ vlen = vsnprintf(arg->errbuf, maxlen, fmt, ap);\r
+ va_end(ap);\r
+ if(vlen >= maxlen) {\r
+ arg->errbuf[maxlen-1] = '\0'; /* Ensuring libc correctness */\r
+ arg->errlen = maxlen - 1; /* Not counting termination */\r
+ return;\r
+ } else if(vlen >= 0) {\r
+ arg->errbuf[vlen] = '\0'; /* Ensuring libc correctness */\r
+ arg->errlen = vlen; /* Not counting termination */\r
+ } else {\r
+ /*\r
+ * The libc on this system is broken.\r
+ */\r
+ vlen = sizeof("<broken vsnprintf>") - 1;\r
+ maxlen--;\r
+ arg->errlen = vlen < maxlen ? vlen : maxlen;\r
+ memcpy(arg->errbuf, "<broken vsnprintf>", arg->errlen);\r
+ arg->errbuf[arg->errlen] = 0;\r
+ }\r
+\r
+ return;\r
+}\r
+\r
+int\r
+asn_check_constraints(const asn_TYPE_descriptor_t *type_descriptor,\r
+ const void *struct_ptr, char *errbuf, size_t *errlen) {\r
+ struct errbufDesc arg;\r
+ int ret;\r
+\r
+ arg.failed_type = 0;\r
+ arg.failed_struct_ptr = 0;\r
+ arg.errbuf = errbuf;\r
+ arg.errlen = errlen ? *errlen : 0;\r
+\r
+ ret = type_descriptor->encoding_constraints.general_constraints(\r
+ type_descriptor, struct_ptr, _asn_i_ctfailcb, &arg);\r
+ if(ret == -1 && errlen) *errlen = arg.errlen;\r
+\r
+ return ret;\r
+}\r
+\r