Explorar o código

misc/parse_number.h: add parse_unsigned_integer_cstr() for parsing a cstring

ambrop7 %!s(int64=13) %!d(string=hai) anos
pai
achega
f2163fbf41
Modificáronse 1 ficheiros con 33 adicións e 0 borrados
  1. 33 0
      misc/parse_number.h

+ 33 - 0
misc/parse_number.h

@@ -40,12 +40,14 @@
 #include <limits.h>
 
 #include <misc/debug.h>
+#include <misc/cstring.h>
 
 // public parsing functions
 static int decode_decimal_digit (char c);
 static int decode_hex_digit (char c);
 static int parse_unsigned_integer_bin (const char *str, size_t str_len, uintmax_t *out) WARN_UNUSED;
 static int parse_unsigned_integer (const char *str, uintmax_t *out) WARN_UNUSED;
+static int parse_unsigned_integer_cstr (b_cstring cstr, size_t offset, size_t length, uintmax_t *out) WARN_UNUSED;
 static int parse_unsigned_hex_integer_bin (const char *str, size_t str_len, uintmax_t *out) WARN_UNUSED;
 static int parse_unsigned_hex_integer (const char *str, uintmax_t *out) WARN_UNUSED;
 static int parse_signmag_integer_bin (const char *str, size_t str_len, int *out_sign, uintmax_t *out_mag) WARN_UNUSED;
@@ -153,6 +155,37 @@ int parse_unsigned_integer (const char *str, uintmax_t *out)
     return parse_unsigned_integer_bin(str, strlen(str), out);
 }
 
+int parse_unsigned_integer_cstr (b_cstring cstr, size_t offset, size_t length, uintmax_t *out)
+{
+    b_cstring_assert_range(cstr, offset, length);
+    
+    if (length == 0) {
+        return 0;
+    }
+    
+    uintmax_t n = 0;
+    
+    B_CSTRING_LOOP_RANGE(cstr, offset, length, pos, chunk_data, chunk_length, {
+        for (size_t i = 0; i < chunk_length; i++) {
+            int digit = decode_decimal_digit(chunk_data[i]);
+            if (digit < 0) {
+                return 0;
+            }
+            if (n > UINTMAX_MAX / 10) {
+                return 0;
+            }
+            n *= 10;
+            if (digit > UINTMAX_MAX - n) {
+                return 0;
+            }
+            n += digit;
+        }
+    })
+    
+    *out = n;
+    return 1;
+}
+
 int parse_unsigned_hex_integer_bin (const char *str, size_t str_len, uintmax_t *out)
 {
     uintmax_t n = 0;