mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
Incorporating new faster string->number converter functions
into MY_CHARSET_INFO structure.
This commit is contained in:
parent
c0bb6a3882
commit
1325786818
13 changed files with 208 additions and 2 deletions
|
|
@ -184,7 +184,8 @@ typedef struct my_charset_handler_st
|
|||
int base, char **e, int *err);
|
||||
double (*strntod)(struct charset_info_st *, char *s, uint l, char **e,
|
||||
int *err);
|
||||
|
||||
longlong (*my_strtoll10)(struct charset_info_st *cs,
|
||||
const char *nptr, char **endptr, int *error);
|
||||
ulong (*scan)(struct charset_info_st *, const char *b, const char *e,
|
||||
int sq);
|
||||
} MY_CHARSET_HANDLER;
|
||||
|
|
@ -303,6 +304,11 @@ int my_long10_to_str_8bit(CHARSET_INFO *, char *to, uint l, int radix,
|
|||
int my_longlong10_to_str_8bit(CHARSET_INFO *, char *to, uint l, int radix,
|
||||
longlong val);
|
||||
|
||||
longlong my_strtoll10_8bit(CHARSET_INFO *cs,
|
||||
const char *nptr, char **endptr, int *error);
|
||||
longlong my_strtoll10_ucs2(CHARSET_INFO *cs,
|
||||
const char *nptr, char **endptr, int *error);
|
||||
|
||||
void my_fill_8bit(CHARSET_INFO *cs, char* to, uint l, int fill);
|
||||
|
||||
my_bool my_like_range_simple(CHARSET_INFO *cs,
|
||||
|
|
|
|||
|
|
@ -6306,6 +6306,7 @@ static MY_CHARSET_HANDLER my_charset_big5_handler=
|
|||
my_strntoll_8bit,
|
||||
my_strntoull_8bit,
|
||||
my_strntod_8bit,
|
||||
my_strtoll10_8bit,
|
||||
my_scan_8bit
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -465,6 +465,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
|
|||
my_strntoll_8bit,
|
||||
my_strntoull_8bit,
|
||||
my_strntod_8bit,
|
||||
my_strtoll10_8bit,
|
||||
my_scan_8bit
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8673,6 +8673,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
|
|||
my_strntoll_8bit,
|
||||
my_strntoull_8bit,
|
||||
my_strntod_8bit,
|
||||
my_strtoll10_8bit,
|
||||
my_scan_8bit
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5724,6 +5724,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
|
|||
my_strntoll_8bit,
|
||||
my_strntoull_8bit,
|
||||
my_strntod_8bit,
|
||||
my_strtoll10_8bit,
|
||||
my_scan_8bit
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -9955,6 +9955,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
|
|||
my_strntoll_8bit,
|
||||
my_strntoull_8bit,
|
||||
my_strntod_8bit,
|
||||
my_strtoll10_8bit,
|
||||
my_scan_8bit
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -403,6 +403,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
|
|||
my_strntoll_8bit,
|
||||
my_strntoull_8bit,
|
||||
my_strntod_8bit,
|
||||
my_strtoll10_8bit,
|
||||
my_scan_8bit
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1283,6 +1283,12 @@ static my_bool my_coll_init_simple(CHARSET_INFO *cs,
|
|||
}
|
||||
|
||||
|
||||
longlong my_strtoll10_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const char *nptr, char **endptr, int *error)
|
||||
{
|
||||
return 0; /* my_strtoll10(nptr, endptr, error); */
|
||||
}
|
||||
|
||||
|
||||
MY_CHARSET_HANDLER my_charset_8bit_handler=
|
||||
{
|
||||
|
|
@ -1309,6 +1315,7 @@ MY_CHARSET_HANDLER my_charset_8bit_handler=
|
|||
my_strntoll_8bit,
|
||||
my_strntoull_8bit,
|
||||
my_strntod_8bit,
|
||||
my_strtoll10_8bit,
|
||||
my_scan_8bit
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4604,6 +4604,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
|
|||
my_strntoll_8bit,
|
||||
my_strntoull_8bit,
|
||||
my_strntod_8bit,
|
||||
my_strtoll10_8bit,
|
||||
my_scan_8bit
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -946,6 +946,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
|
|||
my_strntoll_8bit,
|
||||
my_strntoull_8bit,
|
||||
my_strntod_8bit,
|
||||
my_strtoll10_8bit,
|
||||
my_scan_8bit
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
/* UCS2 support. Written by Alexander Barkov <bar@mysql.com> */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include "m_string.h"
|
||||
#include "m_ctype.h"
|
||||
#include <errno.h>
|
||||
|
|
@ -852,7 +853,6 @@ bs:
|
|||
return (negative ? -((longlong) res) : (longlong) res);
|
||||
}
|
||||
|
||||
|
||||
double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
|
||||
char *nptr, uint length,
|
||||
char **endptr, int *err)
|
||||
|
|
@ -1000,6 +1000,188 @@ cnv:
|
|||
}
|
||||
|
||||
|
||||
#undef ULONGLONG_MAX
|
||||
#define ULONGLONG_MAX (~(ulonglong) 0)
|
||||
#define MAX_NEGATIVE_NUMBER ((ulonglong) LL(0x8000000000000000))
|
||||
#define INIT_CNT 9
|
||||
#define LFACTOR ULL(1000000000)
|
||||
#define LFACTOR1 ULL(10000000000)
|
||||
#define LFACTOR2 ULL(100000000000)
|
||||
|
||||
static unsigned long lfactor[9]=
|
||||
{
|
||||
1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L, 100000000L
|
||||
};
|
||||
|
||||
|
||||
longlong my_strtoll10_ucs2(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const char *nptr, char **endptr, int *error)
|
||||
{
|
||||
const char *s, *end, *start, *n_end, *true_end;
|
||||
unsigned char c;
|
||||
unsigned long i, j, k;
|
||||
ulonglong li;
|
||||
int negative;
|
||||
ulong cutoff, cutoff2, cutoff3;
|
||||
|
||||
s= nptr;
|
||||
/* If fixed length string */
|
||||
if (endptr)
|
||||
{
|
||||
/* Make sure string length is even */
|
||||
end= s + ((*endptr - s) / 2) * 2;
|
||||
while (s < end && !s[0] && (s[1] == ' ' || s[1] == '\t'))
|
||||
s+= 2;
|
||||
if (s == end)
|
||||
goto no_conv;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't support null terminated strings in UCS2 */
|
||||
goto no_conv;
|
||||
}
|
||||
|
||||
/* Check for a sign. */
|
||||
negative= 0;
|
||||
if (!s[0] && s[1] == '-')
|
||||
{
|
||||
*error= -1; /* Mark as negative number */
|
||||
negative= 1;
|
||||
s+= 2;
|
||||
if (s == end)
|
||||
goto no_conv;
|
||||
cutoff= MAX_NEGATIVE_NUMBER / LFACTOR2;
|
||||
cutoff2= (MAX_NEGATIVE_NUMBER % LFACTOR2) / 100;
|
||||
cutoff3= MAX_NEGATIVE_NUMBER % 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
*error= 0;
|
||||
if (!s[0] && s[1] == '+')
|
||||
{
|
||||
s+= 2;
|
||||
if (s == end)
|
||||
goto no_conv;
|
||||
}
|
||||
cutoff= ULONGLONG_MAX / LFACTOR2;
|
||||
cutoff2= ULONGLONG_MAX % LFACTOR2 / 100;
|
||||
cutoff3= ULONGLONG_MAX % 100;
|
||||
}
|
||||
|
||||
/* Handle case where we have a lot of pre-zero */
|
||||
if (!s[0] && s[1] == '0')
|
||||
{
|
||||
i= 0;
|
||||
do
|
||||
{
|
||||
s+= 2;
|
||||
if (s == end)
|
||||
goto end_i; /* Return 0 */
|
||||
}
|
||||
while (!s[0] && s[1] == '0');
|
||||
n_end= s + 2 * INIT_CNT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read first digit to check that it's a valid number */
|
||||
if (s[0] || (c= (s[1]-'0')) > 9)
|
||||
goto no_conv;
|
||||
i= c;
|
||||
s+= 2;
|
||||
n_end= s + 2 * (INIT_CNT-1);
|
||||
}
|
||||
|
||||
/* Handle first 9 digits and store them in i */
|
||||
if (n_end > end)
|
||||
n_end= end;
|
||||
for (; s != n_end ; s+= 2)
|
||||
{
|
||||
if (s[0] || (c= (s[1]-'0')) > 9)
|
||||
goto end_i;
|
||||
i= i*10+c;
|
||||
}
|
||||
if (s == end)
|
||||
goto end_i;
|
||||
|
||||
/* Handle next 9 digits and store them in j */
|
||||
j= 0;
|
||||
start= s; /* Used to know how much to shift i */
|
||||
n_end= true_end= s + 2 * INIT_CNT;
|
||||
if (n_end > end)
|
||||
n_end= end;
|
||||
do
|
||||
{
|
||||
if (s[0] || (c= (s[1]-'0')) > 9)
|
||||
goto end_i_and_j;
|
||||
j= j*10+c;
|
||||
s+= 2;
|
||||
} while (s != n_end);
|
||||
if (s == end)
|
||||
{
|
||||
if (s != true_end)
|
||||
goto end_i_and_j;
|
||||
goto end3;
|
||||
}
|
||||
if (s[0] || (c= (s[1]-'0')) > 9)
|
||||
goto end3;
|
||||
|
||||
/* Handle the next 1 or 2 digits and store them in k */
|
||||
k=c;
|
||||
s+= 2;
|
||||
if (s == end || s[0] || (c= (s[1]-'0')) > 9)
|
||||
goto end4;
|
||||
k= k*10+c;
|
||||
s+= 2;
|
||||
*endptr= (char*) s;
|
||||
|
||||
/* number string should have ended here */
|
||||
if (s != end && !s[0] && (c= (s[1]-'0')) <= 9)
|
||||
goto overflow;
|
||||
|
||||
/* Check that we didn't get an overflow with the last digit */
|
||||
if (i > cutoff || (i == cutoff && ((j > cutoff2 || j == cutoff2) &&
|
||||
k > cutoff3)))
|
||||
goto overflow;
|
||||
li=i*LFACTOR2+ (ulonglong) j*100 + k;
|
||||
return (longlong) li;
|
||||
|
||||
overflow: /* *endptr is set here */
|
||||
*error= MY_ERRNO_ERANGE;
|
||||
return negative ? LONGLONG_MIN : (longlong) ULONGLONG_MAX;
|
||||
|
||||
end_i:
|
||||
*endptr= (char*) s;
|
||||
return (negative ? ((longlong) -(long) i) : (longlong) i);
|
||||
|
||||
end_i_and_j:
|
||||
li= (ulonglong) i * lfactor[(uint) (s-start) / 2] + j;
|
||||
*endptr= (char*) s;
|
||||
return (negative ? -((longlong) li) : (longlong) li);
|
||||
|
||||
end3:
|
||||
li=(ulonglong) i*LFACTOR+ (ulonglong) j;
|
||||
*endptr= (char*) s;
|
||||
return (negative ? -((longlong) li) : (longlong) li);
|
||||
|
||||
end4:
|
||||
li=(ulonglong) i*LFACTOR1+ (ulonglong) j * 10 + k;
|
||||
*endptr= (char*) s;
|
||||
if (negative)
|
||||
{
|
||||
if (li > MAX_NEGATIVE_NUMBER)
|
||||
goto overflow;
|
||||
return -((longlong) li);
|
||||
}
|
||||
return (longlong) li;
|
||||
|
||||
no_conv:
|
||||
/* There was no number to convert. */
|
||||
*error= MY_ERRNO_EDOM;
|
||||
*endptr= (char *) nptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
uint my_numchars_ucs2(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const char *b, const char *e)
|
||||
|
|
@ -1439,6 +1621,7 @@ MY_CHARSET_HANDLER my_charset_ucs2_handler=
|
|||
my_strntoll_ucs2,
|
||||
my_strntoull_ucs2,
|
||||
my_strntod_ucs2,
|
||||
my_strtoll10_ucs2,
|
||||
my_scan_8bit
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8493,6 +8493,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
|
|||
my_strntoll_8bit,
|
||||
my_strntoull_8bit,
|
||||
my_strntod_8bit,
|
||||
my_strtoll10_8bit,
|
||||
my_scan_8bit
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2091,6 +2091,7 @@ MY_CHARSET_HANDLER my_charset_utf8_handler=
|
|||
my_strntoll_8bit,
|
||||
my_strntoull_8bit,
|
||||
my_strntod_8bit,
|
||||
my_strtoll10_8bit,
|
||||
my_scan_8bit
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue