Просмотр исходного кода

misc: parse_number: add parse_unsigned_hex_integer()

ambrop7 14 лет назад
Родитель
Сommit
303bb4f8d8
1 измененных файлов с 63 добавлено и 0 удалено
  1. 63 0
      misc/parse_number.h

+ 63 - 0
misc/parse_number.h

@@ -35,6 +35,32 @@
 
 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_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 decode_hex_digit (char c)
+{
+    switch (c) {
+        case '0': return 0;
+        case '1': return 1;
+        case '2': return 2;
+        case '3': return 3;
+        case '4': return 4;
+        case '5': return 5;
+        case '6': return 6;
+        case '7': return 7;
+        case '8': return 8;
+        case '9': return 9;
+        case 'A': case 'a': return 10;
+        case 'B': case 'b': return 11;
+        case 'C': case 'c': return 12;
+        case 'D': case 'd': return 13;
+        case 'E': case 'e': return 14;
+        case 'F': case 'f': return 15;
+    }
+    
+    return -1;
+}
 
 int parse_unsigned_integer_bin (const char *str, size_t str_len, uintmax_t *out)
 {
@@ -73,4 +99,41 @@ int parse_unsigned_integer (const char *str, uintmax_t *out)
     return parse_unsigned_integer_bin(str, strlen(str), out);
 }
 
+int parse_unsigned_hex_integer_bin (const char *str, size_t str_len, uintmax_t *out)
+{
+    uintmax_t n = 0;
+    
+    if (str_len == 0) {
+        return 0;
+    }
+    
+    while (str_len > 0) {
+        int digit = decode_hex_digit(*str);
+        if (digit < 0) {
+            return 0;
+        }
+        
+        if (n > UINTMAX_MAX / 16) {
+            return 0;
+        }
+        n *= 16;
+        
+        if (digit > UINTMAX_MAX - n) {
+            return 0;
+        }
+        n += digit;
+        
+        str++;
+        str_len--;
+    }
+    
+    *out = n;
+    return 1;
+}
+
+int parse_unsigned_hex_integer (const char *str, uintmax_t *out)
+{
+    return parse_unsigned_hex_integer_bin(str, strlen(str), out);
+}
+
 #endif