diff --git a/docs/README.md b/docs/README.md index a92790b0..60582f66 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2442,6 +2442,7 @@ mg_snprintf(buf, sizeof(buf), "%%-%3s", "a"); // %- a ```c int64_t mg_to64(struct mg_str str); +uint64_t mg_tou64(struct mg_str str); ``` Parse 64-bit integer value held by string `s`. diff --git a/mongoose.c b/mongoose.c index 6b387925..870fc3ef 100644 --- a/mongoose.c +++ b/mongoose.c @@ -4049,6 +4049,19 @@ size_t mg_asprintf(char **buf, size_t size, const char *fmt, ...) { return ret; } +uint64_t mg_tou64(struct mg_str str) { + uint64_t result = 0; + size_t i = 0; + while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++; + while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') { + result *= 10; + result += (unsigned) (str.ptr[i] - '0'); + MG_INFO(("[%.*s] %llu", (int) str.len, str.ptr, result)); + i++; + } + return result; +} + int64_t mg_to64(struct mg_str str) { int64_t result = 0, neg = 1, max = 922337203685477570 /* INT64_MAX/10-10 */; size_t i = 0; diff --git a/mongoose.h b/mongoose.h index 459c1563..792497fe 100644 --- a/mongoose.h +++ b/mongoose.h @@ -632,6 +632,7 @@ size_t mg_asprintf(char **, size_t, const char *fmt, ...) PRINTF_LIKE(3, 4); size_t mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap); int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip); int64_t mg_to64(struct mg_str str); +uint64_t mg_tou64(struct mg_str str); size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex); diff --git a/src/str.c b/src/str.c index a699b69a..82cacba2 100644 --- a/src/str.c +++ b/src/str.c @@ -254,6 +254,19 @@ size_t mg_asprintf(char **buf, size_t size, const char *fmt, ...) { return ret; } +uint64_t mg_tou64(struct mg_str str) { + uint64_t result = 0; + size_t i = 0; + while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++; + while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') { + result *= 10; + result += (unsigned) (str.ptr[i] - '0'); + MG_INFO(("[%.*s] %llu", (int) str.len, str.ptr, result)); + i++; + } + return result; +} + int64_t mg_to64(struct mg_str str) { int64_t result = 0, neg = 1, max = 922337203685477570 /* INT64_MAX/10-10 */; size_t i = 0; diff --git a/src/str.h b/src/str.h index 2dc752ed..d702ae42 100644 --- a/src/str.h +++ b/src/str.h @@ -41,4 +41,5 @@ size_t mg_asprintf(char **, size_t, const char *fmt, ...) PRINTF_LIKE(3, 4); size_t mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap); int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip); int64_t mg_to64(struct mg_str str); +uint64_t mg_tou64(struct mg_str str); size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex); diff --git a/test/unit_test.c b/test/unit_test.c index bebe812b..e54c3b94 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -1499,6 +1499,11 @@ static void test_util(void) { ASSERT(mg_to64(mg_str("-9223372036854775809")) == 0); ASSERT(mg_to64(mg_str("9223372036854775800")) == 0); ASSERT(mg_to64(mg_str("9223372036854775700")) > 0); + ASSERT(mg_tou64(mg_str("0")) == 0); + ASSERT(mg_tou64(mg_str("123")) == 123); + ASSERT(mg_tou64(mg_str("")) == 0); + ASSERT(mg_tou64(mg_str("-")) == 0); + ASSERT(mg_tou64(mg_str("18446744073709551615")) == 18446744073709551615U); } static void test_crc32(void) {