From d4e07f171472a99a63c47b1fb6ab8a0a071ae945 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Thu, 10 Mar 2011 16:16:27 +0100 Subject: [PATCH] Add new string to long long function --- src/redis.h | 1 + src/util.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/redis.h b/src/redis.h index 9f53583e..e32c1807 100644 --- a/src/redis.h +++ b/src/redis.h @@ -894,6 +894,7 @@ int stringmatchlen(const char *pattern, int patternLen, int stringmatch(const char *pattern, const char *string, int nocase); long long memtoll(const char *p, int *err); int ll2string(char *s, size_t len, long long value); +int string2ll(char *s, size_t len, long long *value); int d2string(char *s, size_t len, double value); int isStringRepresentableAsLong(sds s, long *longval); int isStringRepresentableAsLongLong(sds s, long long *longval); diff --git a/src/util.c b/src/util.c index 5cffa072..599dc690 100644 --- a/src/util.c +++ b/src/util.c @@ -201,6 +201,63 @@ int ll2string(char *s, size_t len, long long value) { return l; } +/* Convert a string into a long long. Returns 1 if the string could be parsed + * into a (non-overflowing) long long, 0 otherwise. The value will be set to + * the parsed value when appropriate. */ +int string2ll(char *s, size_t slen, long long *value) { + char *p = s; + size_t plen = 0; + int negative = 0; + unsigned long long v; + + if (plen == slen) + return 0; + + if (p[0] == '-') { + negative = 1; + p++; plen++; + + /* Abort on only a negative sign. */ + if (plen == slen) + return 0; + } + + /* First digit should be 1-9. */ + if (p[0] >= '1' && p[0] <= '9') { + v = p[0]-'0'; + p++; plen++; + } else { + return 0; + } + + while (plen < slen && p[0] >= '0' && p[0] <= '9') { + if (v > (ULLONG_MAX / 10)) /* Overflow. */ + return 0; + v *= 10; + + if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */ + return 0; + v += p[0]-'0'; + + p++; plen++; + } + + /* Return if not all bytes were used. */ + if (plen < slen) + return 0; + + if (negative) { + if (v > (-(unsigned long long)LLONG_MIN)) /* Overflow. */ + return 0; + if (value != NULL) *value = -v; + } else { + if (v > LLONG_MAX) /* Overflow. */ + return 0; + if (value != NULL) *value = v; + } + return 1; +} + /* Convert a double to a string representation. Returns the number of bytes * required. The representation should always be parsable by stdtod(3). */ int d2string(char *buf, size_t len, double value) {