mirror of
https://github.com/MariaDB/server.git
synced 2025-07-04 01:23:45 +03:00
MDEV-17905 Add class Charset
This commit is contained in:
@ -126,7 +126,7 @@ bool String::set_int(longlong num, bool unsigned_flag, CHARSET_INFO *cs)
|
|||||||
if (alloc(l))
|
if (alloc(l))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
str_length=(uint32) (cs->cset->longlong10_to_str)(cs,Ptr,l,base,num);
|
str_length=(uint32) (cs->cset->longlong10_to_str)(cs,Ptr,l,base,num);
|
||||||
str_charset=cs;
|
set_charset(cs);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ bool String::set_real(double num,uint decimals, CHARSET_INFO *cs)
|
|||||||
uint dummy_errors;
|
uint dummy_errors;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
str_charset=cs;
|
set_charset(cs);
|
||||||
if (decimals >= FLOATING_POINT_DECIMALS)
|
if (decimals >= FLOATING_POINT_DECIMALS)
|
||||||
{
|
{
|
||||||
len= my_gcvt(num, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
|
len= my_gcvt(num, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
|
||||||
@ -231,7 +231,7 @@ bool String::copy(const String &str)
|
|||||||
str_length=str.str_length;
|
str_length=str.str_length;
|
||||||
bmove(Ptr,str.Ptr,str_length); // May be overlapping
|
bmove(Ptr,str.Ptr,str_length); // May be overlapping
|
||||||
Ptr[str_length]=0;
|
Ptr[str_length]=0;
|
||||||
str_charset=str.str_charset;
|
set_charset(str);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,7 +252,7 @@ bool String::copy(const char *str,size_t arg_length, CHARSET_INFO *cs)
|
|||||||
else if ((str_length=uint32(arg_length)))
|
else if ((str_length=uint32(arg_length)))
|
||||||
memcpy(Ptr,str,arg_length);
|
memcpy(Ptr,str,arg_length);
|
||||||
Ptr[arg_length]=0;
|
Ptr[arg_length]=0;
|
||||||
str_charset=cs;
|
set_charset(cs);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +270,7 @@ bool String::copy_or_move(const char *str,size_t arg_length, CHARSET_INFO *cs)
|
|||||||
if ((str_length=uint32(arg_length)))
|
if ((str_length=uint32(arg_length)))
|
||||||
memmove(Ptr,str,arg_length);
|
memmove(Ptr,str,arg_length);
|
||||||
Ptr[arg_length]=0;
|
Ptr[arg_length]=0;
|
||||||
str_charset=cs;
|
set_charset(cs);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,7 +396,7 @@ bool String::copy_aligned(const char *str, size_t arg_length, size_t offset,
|
|||||||
Ptr[aligned_length]=0;
|
Ptr[aligned_length]=0;
|
||||||
/* str_length is always >= 0 as arg_length is != 0 */
|
/* str_length is always >= 0 as arg_length is != 0 */
|
||||||
str_length= (uint32)aligned_length;
|
str_length= (uint32)aligned_length;
|
||||||
str_charset= cs;
|
set_charset(cs);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,7 +449,7 @@ bool String::copy(const char *str, size_t arg_length,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
|
str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
|
||||||
str, arg_length, from_cs, errors);
|
str, arg_length, from_cs, errors);
|
||||||
str_charset=to_cs;
|
set_charset(to_cs);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,13 +475,14 @@ bool String::copy(const char *str, size_t arg_length,
|
|||||||
|
|
||||||
bool String::set_ascii(const char *str, size_t arg_length)
|
bool String::set_ascii(const char *str, size_t arg_length)
|
||||||
{
|
{
|
||||||
if (str_charset->mbminlen == 1)
|
if (mbminlen() == 1)
|
||||||
{
|
{
|
||||||
set(str, arg_length, str_charset);
|
set(str, arg_length, charset());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uint dummy_errors;
|
uint dummy_errors;
|
||||||
return copy(str, (uint32)arg_length, &my_charset_latin1, str_charset, &dummy_errors);
|
return copy(str, (uint32) arg_length, &my_charset_latin1,
|
||||||
|
charset(), &dummy_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -503,7 +504,7 @@ bool String::fill(uint32 max_length,char fill_char)
|
|||||||
|
|
||||||
void String::strip_sp()
|
void String::strip_sp()
|
||||||
{
|
{
|
||||||
while (str_length && my_isspace(str_charset,Ptr[str_length-1]))
|
while (str_length && my_isspace(charset(), Ptr[str_length-1]))
|
||||||
str_length--;
|
str_length--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,13 +535,13 @@ bool String::append(const char *s,size_t size)
|
|||||||
/*
|
/*
|
||||||
For an ASCII incompatible string, e.g. UCS-2, we need to convert
|
For an ASCII incompatible string, e.g. UCS-2, we need to convert
|
||||||
*/
|
*/
|
||||||
if (str_charset->mbminlen > 1)
|
if (mbminlen() > 1)
|
||||||
{
|
{
|
||||||
uint32 add_length=arg_length * str_charset->mbmaxlen;
|
uint32 add_length= arg_length * mbmaxlen();
|
||||||
uint dummy_errors;
|
uint dummy_errors;
|
||||||
if (realloc_with_extra_if_needed(str_length+ add_length))
|
if (realloc_with_extra_if_needed(str_length+ add_length))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
|
str_length+= copy_and_convert(Ptr + str_length, add_length, charset(),
|
||||||
s, arg_length, &my_charset_latin1,
|
s, arg_length, &my_charset_latin1,
|
||||||
&dummy_errors);
|
&dummy_errors);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -594,13 +595,13 @@ bool String::append(const char *s, size_t arg_length, CHARSET_INFO *cs)
|
|||||||
{
|
{
|
||||||
uint32 offset;
|
uint32 offset;
|
||||||
|
|
||||||
if (needs_conversion((uint32)arg_length, cs, str_charset, &offset))
|
if (needs_conversion((uint32)arg_length, cs, charset(), &offset))
|
||||||
{
|
{
|
||||||
size_t add_length;
|
size_t add_length;
|
||||||
if ((cs == &my_charset_bin) && offset)
|
if ((cs == &my_charset_bin) && offset)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(str_charset->mbminlen > offset);
|
DBUG_ASSERT(mbminlen() > offset);
|
||||||
offset= str_charset->mbminlen - offset; // How many characters to pad
|
offset= mbminlen() - offset; // How many characters to pad
|
||||||
add_length= arg_length + offset;
|
add_length= arg_length + offset;
|
||||||
if (realloc(str_length + add_length))
|
if (realloc(str_length + add_length))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -610,12 +611,12 @@ bool String::append(const char *s, size_t arg_length, CHARSET_INFO *cs)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
|
add_length= arg_length / cs->mbminlen * mbmaxlen();
|
||||||
uint dummy_errors;
|
uint dummy_errors;
|
||||||
if (realloc_with_extra_if_needed(str_length + add_length))
|
if (realloc_with_extra_if_needed(str_length + add_length))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
str_length+= copy_and_convert(Ptr+str_length, (uint32)add_length, str_charset,
|
str_length+= copy_and_convert(Ptr + str_length, (uint32)add_length, charset(),
|
||||||
s, (uint32)arg_length, cs, &dummy_errors);
|
s, (uint32)arg_length, cs, &dummy_errors);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -675,17 +676,6 @@ bool String::append_with_prefill(const char *s,uint32 arg_length,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 String::numchars() const
|
|
||||||
{
|
|
||||||
return (uint32) str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
int String::charpos(longlong i,uint32 offset)
|
|
||||||
{
|
|
||||||
if (i <= 0)
|
|
||||||
return (int)i;
|
|
||||||
return (int)str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,(size_t)i);
|
|
||||||
}
|
|
||||||
|
|
||||||
int String::strstr(const String &s,uint32 offset)
|
int String::strstr(const String &s,uint32 offset)
|
||||||
{
|
{
|
||||||
@ -999,7 +989,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
|
|||||||
return from; // Actually an error
|
return from; // Actually an error
|
||||||
if ((to->str_length=MY_MIN(from->str_length,from_length)))
|
if ((to->str_length=MY_MIN(from->str_length,from_length)))
|
||||||
memcpy(to->Ptr,from->Ptr,to->str_length);
|
memcpy(to->Ptr,from->Ptr,to->str_length);
|
||||||
to->str_charset=from->str_charset;
|
to->set_charset(*from);
|
||||||
return to; // "from" was of types #a, #b, #e, or small #c.
|
return to; // "from" was of types #a, #b, #e, or small #c.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1175,7 +1165,7 @@ void String::swap(String &s)
|
|||||||
swap_variables(uint32, str_length, s.str_length);
|
swap_variables(uint32, str_length, s.str_length);
|
||||||
swap_variables(uint32, Alloced_length, s.Alloced_length);
|
swap_variables(uint32, Alloced_length, s.Alloced_length);
|
||||||
swap_variables(bool, alloced, s.alloced);
|
swap_variables(bool, alloced, s.alloced);
|
||||||
swap_variables(CHARSET_INFO*, str_charset, s.str_charset);
|
Charset::swap(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,31 +126,64 @@ uint convert_to_printable(char *to, size_t to_len,
|
|||||||
const char *from, size_t from_len,
|
const char *from, size_t from_len,
|
||||||
CHARSET_INFO *from_cs, size_t nbytes= 0);
|
CHARSET_INFO *from_cs, size_t nbytes= 0);
|
||||||
|
|
||||||
class String
|
|
||||||
|
class Charset
|
||||||
|
{
|
||||||
|
CHARSET_INFO *m_charset;
|
||||||
|
public:
|
||||||
|
Charset() :m_charset(&my_charset_bin) { }
|
||||||
|
Charset(CHARSET_INFO *cs) :m_charset(cs) { }
|
||||||
|
|
||||||
|
CHARSET_INFO *charset() const { return m_charset; }
|
||||||
|
uint mbminlen() const { return m_charset->mbminlen; }
|
||||||
|
uint mbmaxlen() const { return m_charset->mbmaxlen; }
|
||||||
|
|
||||||
|
size_t numchars(const char *str, const char *end) const
|
||||||
|
{
|
||||||
|
return m_charset->cset->numchars(m_charset, str, end);
|
||||||
|
}
|
||||||
|
size_t charpos(const char *str, const char *end, size_t pos) const
|
||||||
|
{
|
||||||
|
return m_charset->cset->charpos(m_charset, str, end, pos);
|
||||||
|
}
|
||||||
|
void set_charset(CHARSET_INFO *charset_arg)
|
||||||
|
{
|
||||||
|
m_charset= charset_arg;
|
||||||
|
}
|
||||||
|
void set_charset(const Charset &other)
|
||||||
|
{
|
||||||
|
m_charset= other.m_charset;
|
||||||
|
}
|
||||||
|
void swap(Charset &other)
|
||||||
|
{
|
||||||
|
swap_variables(CHARSET_INFO*, m_charset, other.m_charset);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class String: public Charset
|
||||||
{
|
{
|
||||||
char *Ptr;
|
char *Ptr;
|
||||||
uint32 str_length,Alloced_length, extra_alloc;
|
uint32 str_length,Alloced_length, extra_alloc;
|
||||||
bool alloced,thread_specific;
|
bool alloced,thread_specific;
|
||||||
CHARSET_INFO *str_charset;
|
|
||||||
public:
|
public:
|
||||||
String()
|
String()
|
||||||
{
|
{
|
||||||
Ptr=0; str_length=Alloced_length=extra_alloc=0;
|
Ptr=0; str_length=Alloced_length=extra_alloc=0;
|
||||||
alloced= thread_specific= 0;
|
alloced= thread_specific= 0;
|
||||||
str_charset= &my_charset_bin;
|
|
||||||
}
|
}
|
||||||
String(size_t length_arg)
|
String(size_t length_arg)
|
||||||
{
|
{
|
||||||
alloced= thread_specific= 0;
|
alloced= thread_specific= 0;
|
||||||
Alloced_length= extra_alloc= 0; (void) real_alloc(length_arg);
|
Alloced_length= extra_alloc= 0; (void) real_alloc(length_arg);
|
||||||
str_charset= &my_charset_bin;
|
|
||||||
}
|
}
|
||||||
String(const char *str, CHARSET_INFO *cs)
|
String(const char *str, CHARSET_INFO *cs)
|
||||||
|
:Charset(cs)
|
||||||
{
|
{
|
||||||
Ptr=(char*) str; str_length= (uint32) strlen(str);
|
Ptr=(char*) str; str_length= (uint32) strlen(str);
|
||||||
Alloced_length= extra_alloc= 0;
|
Alloced_length= extra_alloc= 0;
|
||||||
alloced= thread_specific= 0;
|
alloced= thread_specific= 0;
|
||||||
str_charset=cs;
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
NOTE: If one intend to use the c_ptr() method, the following two
|
NOTE: If one intend to use the c_ptr() method, the following two
|
||||||
@ -158,23 +191,23 @@ public:
|
|||||||
room for zero termination).
|
room for zero termination).
|
||||||
*/
|
*/
|
||||||
String(const char *str,size_t len, CHARSET_INFO *cs)
|
String(const char *str,size_t len, CHARSET_INFO *cs)
|
||||||
|
:Charset(cs)
|
||||||
{
|
{
|
||||||
Ptr=(char*) str; str_length=(uint32)len; Alloced_length= extra_alloc=0;
|
Ptr=(char*) str; str_length=(uint32)len; Alloced_length= extra_alloc=0;
|
||||||
alloced= thread_specific= 0;
|
alloced= thread_specific= 0;
|
||||||
str_charset=cs;
|
|
||||||
}
|
}
|
||||||
String(char *str,size_t len, CHARSET_INFO *cs)
|
String(char *str,size_t len, CHARSET_INFO *cs)
|
||||||
|
:Charset(cs)
|
||||||
{
|
{
|
||||||
Ptr=(char*) str; Alloced_length=str_length=(uint32)len; extra_alloc= 0;
|
Ptr=(char*) str; Alloced_length=str_length=(uint32)len; extra_alloc= 0;
|
||||||
alloced= thread_specific= 0;
|
alloced= thread_specific= 0;
|
||||||
str_charset=cs;
|
|
||||||
}
|
}
|
||||||
String(const String &str)
|
String(const String &str)
|
||||||
|
:Charset(str)
|
||||||
{
|
{
|
||||||
Ptr=str.Ptr ; str_length=str.str_length ;
|
Ptr=str.Ptr ; str_length=str.str_length ;
|
||||||
Alloced_length=str.Alloced_length; extra_alloc= 0;
|
Alloced_length=str.Alloced_length; extra_alloc= 0;
|
||||||
alloced= thread_specific= 0;
|
alloced= thread_specific= 0;
|
||||||
str_charset=str.str_charset;
|
|
||||||
}
|
}
|
||||||
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
|
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
|
||||||
{ return (void*) alloc_root(mem_root, size); }
|
{ return (void*) alloc_root(mem_root, size); }
|
||||||
@ -201,9 +234,6 @@ public:
|
|||||||
if (!alloced)
|
if (!alloced)
|
||||||
thread_specific= 1;
|
thread_specific= 1;
|
||||||
}
|
}
|
||||||
inline void set_charset(CHARSET_INFO *charset_arg)
|
|
||||||
{ str_charset= charset_arg; }
|
|
||||||
inline CHARSET_INFO *charset() const { return str_charset; }
|
|
||||||
inline uint32 length() const { return str_length;}
|
inline uint32 length() const { return str_length;}
|
||||||
inline uint32 alloced_length() const { return Alloced_length;}
|
inline uint32 alloced_length() const { return Alloced_length;}
|
||||||
inline uint32 extra_allocation() const { return extra_alloc;}
|
inline uint32 extra_allocation() const { return extra_alloc;}
|
||||||
@ -255,7 +285,7 @@ public:
|
|||||||
Ptr=(char*) str.ptr()+offset; str_length=(uint32)arg_length;
|
Ptr=(char*) str.ptr()+offset; str_length=(uint32)arg_length;
|
||||||
if (str.Alloced_length)
|
if (str.Alloced_length)
|
||||||
Alloced_length=(uint32)(str.Alloced_length-offset);
|
Alloced_length=(uint32)(str.Alloced_length-offset);
|
||||||
str_charset=str.str_charset;
|
set_charset(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -271,13 +301,13 @@ public:
|
|||||||
{
|
{
|
||||||
free();
|
free();
|
||||||
Ptr=(char*) str; str_length=Alloced_length=(uint32)arg_length;
|
Ptr=(char*) str; str_length=Alloced_length=(uint32)arg_length;
|
||||||
str_charset=cs;
|
set_charset(cs);
|
||||||
}
|
}
|
||||||
inline void set(const char *str,size_t arg_length, CHARSET_INFO *cs)
|
inline void set(const char *str,size_t arg_length, CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
free();
|
free();
|
||||||
Ptr=(char*) str; str_length=(uint32)arg_length;
|
Ptr=(char*) str; str_length=(uint32)arg_length;
|
||||||
str_charset=cs;
|
set_charset(cs);
|
||||||
}
|
}
|
||||||
bool set_ascii(const char *str, size_t arg_length);
|
bool set_ascii(const char *str, size_t arg_length);
|
||||||
inline void set_quick(char *str,size_t arg_length, CHARSET_INFO *cs)
|
inline void set_quick(char *str,size_t arg_length, CHARSET_INFO *cs)
|
||||||
@ -286,7 +316,7 @@ public:
|
|||||||
{
|
{
|
||||||
Ptr=(char*) str; str_length=Alloced_length=(uint32)arg_length;
|
Ptr=(char*) str; str_length=Alloced_length=(uint32)arg_length;
|
||||||
}
|
}
|
||||||
str_charset=cs;
|
set_charset(cs);
|
||||||
}
|
}
|
||||||
bool set_int(longlong num, bool unsigned_flag, CHARSET_INFO *cs);
|
bool set_int(longlong num, bool unsigned_flag, CHARSET_INFO *cs);
|
||||||
bool set(int num, CHARSET_INFO *cs) { return set_int(num, false, cs); }
|
bool set(int num, CHARSET_INFO *cs) { return set_int(num, false, cs); }
|
||||||
@ -308,7 +338,7 @@ public:
|
|||||||
Ptr= ptr_arg;
|
Ptr= ptr_arg;
|
||||||
str_length= (uint32)length_arg;
|
str_length= (uint32)length_arg;
|
||||||
Alloced_length= (uint32)alloced_length_arg;
|
Alloced_length= (uint32)alloced_length_arg;
|
||||||
str_charset= cs;
|
set_charset(cs);
|
||||||
alloced= ptr_arg != 0;
|
alloced= ptr_arg != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,7 +459,7 @@ public:
|
|||||||
DBUG_ASSERT(!s.uses_buffer_owned_by(this));
|
DBUG_ASSERT(!s.uses_buffer_owned_by(this));
|
||||||
free();
|
free();
|
||||||
Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
|
Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
|
||||||
str_charset=s.str_charset;
|
set_charset(s);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -461,7 +491,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
str_length= copier->well_formed_copy(tocs, Ptr, Alloced_length,
|
str_length= copier->well_formed_copy(tocs, Ptr, Alloced_length,
|
||||||
fromcs, src, (uint)src_length, (uint)nchars);
|
fromcs, src, (uint)src_length, (uint)nchars);
|
||||||
str_charset= tocs;
|
set_charset(tocs);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void move(String &s)
|
void move(String &s)
|
||||||
@ -539,8 +569,16 @@ public:
|
|||||||
friend int stringcmp(const String *a,const String *b);
|
friend int stringcmp(const String *a,const String *b);
|
||||||
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
|
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
|
||||||
friend class Field;
|
friend class Field;
|
||||||
uint32 numchars() const;
|
uint32 numchars() const
|
||||||
int charpos(longlong i,uint32 offset=0);
|
{
|
||||||
|
return (uint32) Charset::numchars(ptr(), end());
|
||||||
|
}
|
||||||
|
int charpos(longlong i, uint32 offset=0)
|
||||||
|
{
|
||||||
|
if (i <= 0)
|
||||||
|
return (int) i;
|
||||||
|
return (int) Charset::charpos(ptr() + offset, end(), (size_t) i);
|
||||||
|
}
|
||||||
|
|
||||||
int reserve(size_t space_needed)
|
int reserve(size_t space_needed)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user