OBJECT IDENTIFIER and RELATIVE-OID API simplified
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index 5650368..3257cf7 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -1028,9 +1028,9 @@
intmax_t value;
#define ASN1_INTMAX_MAX ((~(uintmax_t)0) >> 1)
-
const intmax_t upper_boundary = ASN1_INTMAX_MAX / 10;
intmax_t last_digit_max = ASN1_INTMAX_MAX % 10;
+#undef ASN1_INTMAX_MAX
if(str >= *end) return ASN_STRTOX_ERROR_INVAL;
@@ -1084,6 +1084,66 @@
return ASN_STRTOX_OK;
}
+/*
+ * Parse the number in the given string until the given *end position,
+ * returning the position after the last parsed character back using the
+ * same (*end) pointer.
+ * WARNING: This behavior is different from the standard strtoul/strtoumax(3).
+ */
+enum asn_strtox_result_e
+asn_strtoumax_lim(const char *str, const char **end, uintmax_t *uintp) {
+ uintmax_t value;
+
+#define ASN1_UINTMAX_MAX ((~(uintmax_t)0))
+ const uintmax_t upper_boundary = ASN1_UINTMAX_MAX / 10;
+ uintmax_t last_digit_max = ASN1_UINTMAX_MAX % 10;
+#undef ASN1_UINTMAX_MAX
+
+ if(str >= *end) return ASN_STRTOX_ERROR_INVAL;
+
+ switch(*str) {
+ case '-':
+ return ASN_STRTOX_ERROR_INVAL;
+ case '+':
+ str++;
+ if(str >= *end) {
+ *end = str;
+ return ASN_STRTOX_EXPECT_MORE;
+ }
+ }
+
+ for(value = 0; str < (*end); str++) {
+ switch(*str) {
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
+ case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: {
+ unsigned int d = *str - '0';
+ if(value < upper_boundary) {
+ value = value * 10 + d;
+ } else if(value == upper_boundary) {
+ if(d <= last_digit_max) {
+ value = value * 10 + d;
+ } else {
+ *end = str;
+ return ASN_STRTOX_ERROR_RANGE;
+ }
+ } else {
+ *end = str;
+ return ASN_STRTOX_ERROR_RANGE;
+ }
+ }
+ continue;
+ default:
+ *end = str;
+ *uintp = value;
+ return ASN_STRTOX_EXTRA_DATA;
+ }
+ }
+
+ *end = str;
+ *uintp = value;
+ return ASN_STRTOX_OK;
+}
+
enum asn_strtox_result_e
asn_strtol_lim(const char *str, const char **end, long *lp) {
intmax_t value;
@@ -1114,6 +1174,36 @@
return ASN_STRTOX_ERROR_INVAL;
}
+enum asn_strtox_result_e
+asn_strtoul_lim(const char *str, const char **end, unsigned long *ulp) {
+ uintmax_t value;
+ switch(asn_strtoumax_lim(str, end, &value)) {
+ case ASN_STRTOX_ERROR_RANGE:
+ return ASN_STRTOX_ERROR_RANGE;
+ case ASN_STRTOX_ERROR_INVAL:
+ return ASN_STRTOX_ERROR_INVAL;
+ case ASN_STRTOX_EXPECT_MORE:
+ return ASN_STRTOX_EXPECT_MORE;
+ case ASN_STRTOX_OK:
+ if(value <= ULONG_MAX) {
+ *ulp = value;
+ return ASN_STRTOX_OK;
+ } else {
+ return ASN_STRTOX_ERROR_RANGE;
+ }
+ case ASN_STRTOX_EXTRA_DATA:
+ if(value <= ULONG_MAX) {
+ *ulp = value;
+ return ASN_STRTOX_EXTRA_DATA;
+ } else {
+ return ASN_STRTOX_ERROR_RANGE;
+ }
+ }
+
+ assert(!"Unreachable");
+ return ASN_STRTOX_ERROR_INVAL;
+}
+
int
INTEGER_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
const void *bptr) {