12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
17
#include "drizzled/internal/m_string.h"
25
#define MAX_NEGATIVE_NUMBER ((uint64_t) 0x8000000000000000LL)
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include <my_global.h>
17
#include <my_sys.h> /* Needed for MY_ERRNO_ERANGE */
22
Needed under MetroWerks Compiler, since MetroWerks compiler does not
23
properly handle a constant expression containing a mod operator
25
#if defined(__NETWARE__) && defined(__MWERKS__)
26
static ulonglong ulonglong_max= ~(ulonglong) 0;
27
#define ULONGLONG_MAX ulonglong_max
29
#define ULONGLONG_MAX (~(ulonglong) 0)
30
#endif /* __NETWARE__ && __MWERKS__ */
31
#define MAX_NEGATIVE_NUMBER ((ulonglong) LL(0x8000000000000000))
27
#define LFACTOR 1000000000ULL
28
#define LFACTOR1 10000000000ULL
29
#define LFACTOR2 100000000000ULL
33
#define LFACTOR ULL(1000000000)
34
#define LFACTOR1 ULL(10000000000)
35
#define LFACTOR2 ULL(100000000000)
31
static uint64_t lfactor[9]=
37
static unsigned long lfactor[9]=
33
39
1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L, 100000000L
37
Convert a string to an to uint64_t integer value
43
Convert a string to an to unsigned long long integer value
41
47
nptr in pointer to the string to be converted
42
48
endptr in/out pointer to the end of the string/
43
49
pointer to the stop character
44
50
error out returned error code
47
53
This function takes the decimal representation of integer number
48
54
from string nptr and converts it to an signed or unsigned
55
long long integer value.
50
56
Space characters and tab are ignored.
51
57
A sign character might precede the digit characters. The number
52
58
may have any number of pre-zero digits.
54
60
The function stops reading the string nptr at the first character
55
61
that is not a decimal digit. If endptr is not NULL then the function
56
62
will not read characters after *endptr.
59
Value of string as a signed/unsigned int64_t integer
65
Value of string as a signed/unsigned longlong integer
61
67
if no error and endptr != NULL, it will be set to point at the character
65
71
-1 Number was an ok negative number
67
73
ERANGE If the the value of the converted number exceeded the
68
maximum negative/uint64_t integer.
69
In this case the return value is UINT64_MAX if value was
70
positive and UINT64_MIN if value was negative.
74
maximum negative/unsigned long long integer.
75
In this case the return value is ~0 if value was
76
positive and LONGLONG_MIN if value was negative.
71
77
EDOM If the string didn't contain any digits. In this case
72
78
the return value is 0.
79
int64_t my_strtoll10(const char *nptr, char **endptr, int *error)
85
longlong my_strtoll10(const char *nptr, char **endptr, int *error)
81
87
const char *s, *end, *start, *n_end, *true_end;
84
90
unsigned long i, j, k;
87
uint64_t cutoff, cutoff2, cutoff3;
93
ulong cutoff, cutoff2, cutoff3;
90
96
/* If fixed length string */
130
cutoff= UINT64_MAX / LFACTOR2;
131
cutoff2= UINT64_MAX % LFACTOR2 / 100;
132
cutoff3= UINT64_MAX % 100;
136
cutoff= ULONGLONG_MAX / LFACTOR2;
137
cutoff2= ULONGLONG_MAX % LFACTOR2 / 100;
138
cutoff3= ULONGLONG_MAX % 100;
135
141
/* Handle case where we have a lot of pre-zero */
201
207
if (i > cutoff || (i == cutoff && ((j > cutoff2 || j == cutoff2) &&
204
li=i*LFACTOR2+ (uint64_t) j*100 + k;
210
li=i*LFACTOR2+ (ulonglong) j*100 + k;
211
return (longlong) li;
207
213
overflow: /* *endptr is set here */
209
return negative ? INT64_MIN: INT64_MAX;
214
*error= MY_ERRNO_ERANGE;
215
return negative ? LONGLONG_MIN : (longlong) ULONGLONG_MAX;
212
218
*endptr= (char*) s;
213
return (negative ? ((int64_t) -(long) i) : (int64_t) i);
219
return (negative ? ((longlong) -(long) i) : (longlong) i);
216
li= (uint64_t) i * lfactor[(unsigned int) (s-start)] + j;
222
li= (ulonglong) i * lfactor[(uint) (s-start)] + j;
217
223
*endptr= (char*) s;
218
return (negative ? -((int64_t) li) : (int64_t) li);
224
return (negative ? -((longlong) li) : (longlong) li);
221
li=(uint64_t) i*LFACTOR+ (uint64_t) j;
227
li=(ulonglong) i*LFACTOR+ (ulonglong) j;
222
228
*endptr= (char*) s;
223
return (negative ? -((int64_t) li) : (int64_t) li);
229
return (negative ? -((longlong) li) : (longlong) li);
226
li=(uint64_t) i*LFACTOR1+ (uint64_t) j * 10 + k;
232
li=(ulonglong) i*LFACTOR1+ (ulonglong) j * 10 + k;
227
233
*endptr= (char*) s;
230
236
if (li > MAX_NEGATIVE_NUMBER)
232
return -((int64_t) li);
238
return -((longlong) li);
240
return (longlong) li;
237
243
/* There was no number to convert. */
244
*error= MY_ERRNO_EDOM;
239
245
*endptr= (char *) nptr;
243
} /* namespace internal */
244
} /* namespace drizzled */