diff --git a/pjlib/include/pj/string.h b/pjlib/include/pj/string.h index 1a75a402d..26e7fa6c5 100644 --- a/pjlib/include/pj/string.h +++ b/pjlib/include/pj/string.h @@ -517,6 +517,23 @@ PJ_DECL(char*) pj_create_random_string(char *str, pj_size_t length); */ PJ_DECL(unsigned long) pj_strtoul(const pj_str_t *str); +/** + * Convert strings to an unsigned long-integer value. + * This function stops reading the string input either when the number + * of characters has exceeded the length of the input or it has read + * the first character it cannot recognize as part of a number, that is + * a character greater than or equal to base. + * + * @param str The input string. + * @param endptr Optional pointer to receive the remainder/unparsed + * portion of the input. + * @param base Number base to use. + * + * @return the unsigned integer number. + */ +PJ_DECL(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr, + unsigned base); + /** * Utility to convert unsigned integer to string. Note that the * string will be NULL terminated. diff --git a/pjlib/src/pj/string.c b/pjlib/src/pj/string.c index 62da6a0fc..9a2ca0f2d 100644 --- a/pjlib/src/pj/string.c +++ b/pjlib/src/pj/string.c @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include #include #include @@ -83,6 +84,42 @@ PJ_DEF(unsigned long) pj_strtoul(const pj_str_t *str) return value; } +PJ_DEF(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr, + unsigned base) +{ + unsigned long value; + unsigned i; + + PJ_CHECK_STACK(); + + value = 0; + if (base <= 10) { + for (i=0; i<(unsigned)str->slen; ++i) { + unsigned c = (str->ptr[i] - '0'); + if (c >= base) + break; + value = value * base + c; + } + } else if (base == 16) { + for (i=0; i<(unsigned)str->slen; ++i) { + if (!pj_isxdigit(str->ptr[i])) + break; + value = value * 16 + pj_hex_digit_to_val(str->ptr[i]); + } + } else { + pj_assert(!"Unsupported base"); + i = 0; + value = 0xFFFFFFFFUL; + } + + if (endptr) { + endptr->ptr = str->ptr + i; + endptr->slen = str->slen - i; + } + + return value; +} + PJ_DEF(int) pj_utoa(unsigned long val, char *buf) { return pj_utoa_pad(val, buf, 0, 0); diff --git a/pjlib/src/pjlib-test/string.c b/pjlib/src/pjlib-test/string.c index c8bee0bc6..dd3649cc4 100644 --- a/pjlib/src/pjlib-test/string.c +++ b/pjlib/src/pjlib-test/string.c @@ -48,6 +48,7 @@ * - pj_strtrim() * - pj_utoa() * - pj_strtoul() + * - pj_strtoul2() * - pj_create_random_string() * - ... and mode.. * @@ -358,6 +359,32 @@ int string_test(void) if (pj_strtoul(&s5) != UL_VALUE) return -280; + /* + * pj_strtoul2() + */ + s5 = pj_str("123456"); + + pj_strtoul2(&s5, NULL, 10); /* Crash test */ + + if (pj_strtoul2(&s5, &s4, 10) != 123456UL) + return -290; + if (s4.slen != 0) + return -291; + if (pj_strtoul2(&s5, &s4, 16) != 0x123456UL) + return -292; + + s5 = pj_str("0123ABCD"); + if (pj_strtoul2(&s5, &s4, 10) != 123) + return -293; + if (s4.slen != 4) + return -294; + if (s4.ptr == NULL || *s4.ptr != 'A') + return -295; + if (pj_strtoul2(&s5, &s4, 16) != 0x123ABCDUL) + return -296; + if (s4.slen != 0) + return -297; + /* * pj_create_random_string() * Check that no duplicate strings are returned.