mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-04 18:39:37 +00:00
[MINOR] added new str2i* functions
Those functions provide faster and more flexible alternatives to atoi(), some of which are able to work on sub-strings.
This commit is contained in:
parent
bb046ac8c5
commit
6911fa484c
@ -2,7 +2,7 @@
|
||||
include/common/standard.h
|
||||
This files contains some general purpose functions and macros.
|
||||
|
||||
Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu
|
||||
Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@ -101,4 +101,73 @@ char *encode_string(char *start, char *stop,
|
||||
const char escape, const fd_set *map,
|
||||
const char *string);
|
||||
|
||||
/* This one is 6 times faster than strtoul() on athlon, but does
|
||||
* no check at all.
|
||||
*/
|
||||
static inline unsigned int __str2ui(const char *s)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
while (*s) {
|
||||
i = i * 10 - '0';
|
||||
i += (unsigned char)*s++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/* This one is 5 times faster than strtoul() on athlon with checks.
|
||||
* It returns the value of the number composed of all valid digits read.
|
||||
*/
|
||||
static inline unsigned int __str2uic(const char *s)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int j;
|
||||
while (1) {
|
||||
j = (*s++) - '0';
|
||||
if (j > 9)
|
||||
break;
|
||||
i *= 10;
|
||||
i += j;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/* This one is 28 times faster than strtoul() on athlon, but does
|
||||
* no check at all!
|
||||
*/
|
||||
static inline unsigned int __strl2ui(const char *s, int len)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
while (len-- > 0) {
|
||||
i = i * 10 - '0';
|
||||
i += (unsigned char)*s++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/* This one is 7 times faster than strtoul() on athlon with checks.
|
||||
* It returns the value of the number composed of all valid digits read.
|
||||
*/
|
||||
static inline unsigned int __strl2uic(const char *s, int len)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int j;
|
||||
|
||||
while (len-- > 0) {
|
||||
j = (*s++) - '0';
|
||||
i = i * 10;
|
||||
if (j > 9)
|
||||
break;
|
||||
i += j;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
extern unsigned int str2ui(const char *s);
|
||||
extern unsigned int str2uic(const char *s);
|
||||
extern unsigned int strl2ui(const char *s, int len);
|
||||
extern unsigned int strl2uic(const char *s, int len);
|
||||
extern int strl2ic(const char *s, int len);
|
||||
extern int strl2irc(const char *s, int len, int *ret);
|
||||
extern int strl2llrc(const char *s, int len, long long *ret);
|
||||
|
||||
#endif /* _COMMON_STANDARD_H */
|
||||
|
150
src/standard.c
150
src/standard.c
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* General purpose functions.
|
||||
*
|
||||
* Copyright 2000-2006 Willy Tarreau <w@1wt.eu>
|
||||
* Copyright 2000-2007 Willy Tarreau <w@1wt.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -20,7 +20,7 @@
|
||||
#include <common/standard.h>
|
||||
#include <proto/log.h>
|
||||
|
||||
/* enough to store 2^63=18446744073709551615 */
|
||||
/* enough to store 2^64-1 = 18446744073709551615 */
|
||||
static char itoa_str[21];
|
||||
|
||||
/*
|
||||
@ -212,6 +212,152 @@ char *encode_string(char *start, char *stop,
|
||||
}
|
||||
|
||||
|
||||
unsigned int str2ui(const char *s)
|
||||
{
|
||||
return __str2ui(s);
|
||||
}
|
||||
|
||||
unsigned int str2uic(const char *s)
|
||||
{
|
||||
return __str2uic(s);
|
||||
}
|
||||
|
||||
unsigned int strl2ui(const char *s, int len)
|
||||
{
|
||||
return __strl2ui(s, len);
|
||||
}
|
||||
|
||||
unsigned int strl2uic(const char *s, int len)
|
||||
{
|
||||
return __strl2uic(s, len);
|
||||
}
|
||||
|
||||
/* This one is 7 times faster than strtol() on athlon with checks.
|
||||
* It returns the value of the number composed of all valid digits read,
|
||||
* and can process negative numbers too.
|
||||
*/
|
||||
int strl2ic(const char *s, int len)
|
||||
{
|
||||
int i = 0;
|
||||
int j;
|
||||
|
||||
if (len > 0) {
|
||||
if (*s != '-') {
|
||||
/* positive number */
|
||||
while (len-- > 0) {
|
||||
j = (*s++) - '0';
|
||||
i = i * 10;
|
||||
if (j > 9)
|
||||
break;
|
||||
i += j;
|
||||
}
|
||||
} else {
|
||||
/* negative number */
|
||||
s++;
|
||||
while (--len > 0) {
|
||||
j = (*s++) - '0';
|
||||
i = i * 10;
|
||||
if (j > 9)
|
||||
break;
|
||||
i -= j;
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/* This function reads exactly <len> chars from <s> and converts them to a
|
||||
* signed integer which it stores into <ret>. It accurately detects any error
|
||||
* (truncated string, invalid chars, overflows). It is meant to be used in
|
||||
* applications designed for hostile environments. It returns zero when the
|
||||
* number has successfully been converted, non-zero otherwise. When an error
|
||||
* is returned, the <ret> value is left untouched. It is yet 5 to 40 times
|
||||
* faster than strtol().
|
||||
*/
|
||||
int strl2irc(const char *s, int len, int *ret)
|
||||
{
|
||||
int i = 0;
|
||||
int j;
|
||||
|
||||
if (!len)
|
||||
return 1;
|
||||
|
||||
if (*s != '-') {
|
||||
/* positive number */
|
||||
while (len-- > 0) {
|
||||
j = (*s++) - '0';
|
||||
if (j > 9) return 1; /* invalid char */
|
||||
if (i > INT_MAX / 10) return 1; /* check for multiply overflow */
|
||||
i = i * 10;
|
||||
if (i + j < i) return 1; /* check for addition overflow */
|
||||
i = i + j;
|
||||
}
|
||||
} else {
|
||||
/* negative number */
|
||||
s++;
|
||||
while (--len > 0) {
|
||||
j = (*s++) - '0';
|
||||
if (j > 9) return 1; /* invalid char */
|
||||
if (i < INT_MIN / 10) return 1; /* check for multiply overflow */
|
||||
i = i * 10;
|
||||
if (i - j > i) return 1; /* check for subtract overflow */
|
||||
i = i - j;
|
||||
}
|
||||
}
|
||||
*ret = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* This function reads exactly <len> chars from <s> and converts them to a
|
||||
* signed integer which it stores into <ret>. It accurately detects any error
|
||||
* (truncated string, invalid chars, overflows). It is meant to be used in
|
||||
* applications designed for hostile environments. It returns zero when the
|
||||
* number has successfully been converted, non-zero otherwise. When an error
|
||||
* is returned, the <ret> value is left untouched. It is about 3 times slower
|
||||
* than str2irc().
|
||||
*/
|
||||
#ifndef LLONG_MAX
|
||||
#define LLONG_MAX 9223372036854775807LL
|
||||
#define LLONG_MIN (-LLONG_MAX - 1LL)
|
||||
#endif
|
||||
|
||||
int strl2llrc(const char *s, int len, long long *ret)
|
||||
{
|
||||
long long i = 0;
|
||||
int j;
|
||||
|
||||
if (!len)
|
||||
return 1;
|
||||
|
||||
if (*s != '-') {
|
||||
/* positive number */
|
||||
while (len-- > 0) {
|
||||
j = (*s++) - '0';
|
||||
if (j > 9) return 1; /* invalid char */
|
||||
if (i > LLONG_MAX / 10LL) return 1; /* check for multiply overflow */
|
||||
i = i * 10LL;
|
||||
if (i + j < i) return 1; /* check for addition overflow */
|
||||
i = i + j;
|
||||
}
|
||||
} else {
|
||||
/* negative number */
|
||||
s++;
|
||||
while (--len > 0) {
|
||||
j = (*s++) - '0';
|
||||
if (j > 9) return 1; /* invalid char */
|
||||
if (i < LLONG_MIN / 10LL) return 1; /* check for multiply overflow */
|
||||
i = i * 10LL;
|
||||
if (i - j > i) return 1; /* check for subtract overflow */
|
||||
i = i - j;
|
||||
}
|
||||
}
|
||||
*ret = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
|
Loading…
Reference in New Issue
Block a user