Commit 24d6ec8d authored by Alexander Barkov's avatar Alexander Barkov

MDEV-17907 Class Static_binary_string

parent d6a00d9b
...@@ -156,7 +156,7 @@ static inline void APPEND_HEX(char *&to, uchar value) ...@@ -156,7 +156,7 @@ static inline void APPEND_HEX(char *&to, uchar value)
} }
void String::qs_append_hex(const char *str, uint32 len) void Static_binary_string::qs_append_hex(const char *str, uint32 len)
{ {
const char *str_end= str + len; const char *str_end= str + len;
for (char *to= Ptr + str_length ; str < str_end; str++) for (char *to= Ptr + str_length ; str < str_end; str++)
...@@ -677,7 +677,7 @@ bool String::append_with_prefill(const char *s,uint32 arg_length, ...@@ -677,7 +677,7 @@ bool String::append_with_prefill(const char *s,uint32 arg_length,
} }
int String::strstr(const String &s,uint32 offset) int Static_binary_string::strstr(const Static_binary_string &s, uint32 offset)
{ {
if (s.length()+offset <= str_length) if (s.length()+offset <= str_length)
{ {
...@@ -708,7 +708,7 @@ int String::strstr(const String &s,uint32 offset) ...@@ -708,7 +708,7 @@ int String::strstr(const String &s,uint32 offset)
** Search string from end. Offset is offset to the end of string ** Search string from end. Offset is offset to the end of string
*/ */
int String::strrstr(const String &s,uint32 offset) int Static_binary_string::strrstr(const Static_binary_string &s, uint32 offset)
{ {
if (s.length() <= offset && offset <= str_length) if (s.length() <= offset && offset <= str_length)
{ {
...@@ -787,34 +787,34 @@ int String::reserve(size_t space_needed, size_t grow_by) ...@@ -787,34 +787,34 @@ int String::reserve(size_t space_needed, size_t grow_by)
return FALSE; return FALSE;
} }
void String::qs_append(const char *str, size_t len) void Static_binary_string::qs_append(const char *str, size_t len)
{ {
memcpy(Ptr + str_length, str, len + 1); memcpy(Ptr + str_length, str, len + 1);
str_length += (uint32)len; str_length += (uint32)len;
} }
void String::qs_append(double d) void Static_binary_string::qs_append(double d)
{ {
char *buff = Ptr + str_length; char *buff = Ptr + str_length;
str_length+= (uint32) my_gcvt(d, MY_GCVT_ARG_DOUBLE, FLOATING_POINT_BUFFER - 1, buff, str_length+= (uint32) my_gcvt(d, MY_GCVT_ARG_DOUBLE, FLOATING_POINT_BUFFER - 1, buff,
NULL); NULL);
} }
void String::qs_append(double *d) void Static_binary_string::qs_append(double *d)
{ {
double ld; double ld;
float8get(ld, (char*) d); float8get(ld, (char*) d);
qs_append(ld); qs_append(ld);
} }
void String::qs_append(int i) void Static_binary_string::qs_append(int i)
{ {
char *buff= Ptr + str_length; char *buff= Ptr + str_length;
char *end= int10_to_str(i, buff, -10); char *end= int10_to_str(i, buff, -10);
str_length+= (int) (end-buff); str_length+= (int) (end-buff);
} }
void String::qs_append(ulonglong i) void Static_binary_string::qs_append(ulonglong i)
{ {
char *buff= Ptr + str_length; char *buff= Ptr + str_length;
char *end= longlong10_to_str(i, buff, 10); char *end= longlong10_to_str(i, buff, 10);
...@@ -1149,26 +1149,6 @@ void String::print_with_conversion(String *print, CHARSET_INFO *cs) const ...@@ -1149,26 +1149,6 @@ void String::print_with_conversion(String *print, CHARSET_INFO *cs) const
} }
/*
Exchange state of this object and argument.
SYNOPSIS
String::swap()
RETURN
Target string will contain state of this object and vice versa.
*/
void String::swap(String &s)
{
swap_variables(char *, Ptr, s.Ptr);
swap_variables(uint32, str_length, s.str_length);
swap_variables(uint32, Alloced_length, s.Alloced_length);
swap_variables(bool, alloced, s.alloced);
Charset::swap(s);
}
/** /**
Convert string to printable ASCII string Convert string to printable ASCII string
......
...@@ -161,70 +161,251 @@ class Charset ...@@ -161,70 +161,251 @@ class Charset
}; };
/*
class String: public Charset A storage for String.
Should be eventually derived from LEX_STRING.
*/
class Static_binary_string
{ {
protected:
char *Ptr; char *Ptr;
uint32 str_length,Alloced_length, extra_alloc; uint32 str_length;
public:
Static_binary_string()
:Ptr(NULL),
str_length(0)
{ }
Static_binary_string(char *str, size_t length_arg)
:Ptr(str),
str_length((uint32) length_arg)
{
DBUG_ASSERT(length_arg < UINT_MAX32);
}
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return (void*) alloc_root(mem_root, size); }
static void *operator new[](size_t size, MEM_ROOT *mem_root) throw ()
{ return alloc_root(mem_root, size); }
static void operator delete(void *ptr_arg, size_t size)
{
(void) ptr_arg;
(void) size;
TRASH_FREE(ptr_arg, size);
}
static void operator delete(void *, MEM_ROOT *)
{ /* never called */ }
static void operator delete[](void *ptr, size_t size)
{ TRASH_FREE(ptr, size); }
static void operator delete[](void *, MEM_ROOT *)
{ /* never called */ }
inline uint32 length() const { return str_length;}
inline char& operator [] (size_t i) const { return Ptr[i]; }
inline void length(size_t len) { str_length=(uint32)len ; }
inline bool is_empty() const { return (str_length == 0); }
inline const char *ptr() const { return Ptr; }
inline const char *end() const { return Ptr + str_length; }
LEX_STRING lex_string() const
{
LEX_STRING str = { (char*) ptr(), length() };
return str;
}
LEX_CSTRING lex_cstring() const
{
LEX_CSTRING skr = { ptr(), length() };
return skr;
}
bool has_8bit_bytes() const
{
for (const char *c= ptr(), *c_end= end(); c < c_end; c++)
{
if (!my_isascii(*c))
return true;
}
return false;
}
bool bin_eq(const Static_binary_string *other) const
{
return length() == other->length() &&
!memcmp(ptr(), other->ptr(), length());
}
void swap(Static_binary_string &s)
{
swap_variables(char *, Ptr, s.Ptr);
swap_variables(uint32, str_length, s.str_length);
}
/*
PMG 2004.11.12
This is a method that works the same as perl's "chop". It simply
drops the last character of a string. This is useful in the case
of the federated storage handler where I'm building a unknown
number, list of values and fields to be used in a sql insert
statement to be run on the remote server, and have a comma after each.
When the list is complete, I "chop" off the trailing comma
ex.
String stringobj;
stringobj.append("VALUES ('foo', 'fi', 'fo',");
stringobj.chop();
stringobj.append(")");
In this case, the value of string was:
VALUES ('foo', 'fi', 'fo',
VALUES ('foo', 'fi', 'fo'
VALUES ('foo', 'fi', 'fo')
*/
inline void chop()
{
str_length--;
Ptr[str_length]= '\0';
DBUG_ASSERT(strlen(Ptr) == str_length);
}
// Returns offset to substring or -1
int strstr(const Static_binary_string &search, uint32 offset=0);
// Returns offset to substring or -1
int strrstr(const Static_binary_string &search, uint32 offset=0);
/*
The following append operations do NOT check alloced memory
q_*** methods writes values of parameters itself
qs_*** methods writes string representation of value
*/
void q_append(const char c)
{
Ptr[str_length++] = c;
}
void q_append2b(const uint32 n)
{
int2store(Ptr + str_length, n);
str_length += 2;
}
void q_append(const uint32 n)
{
int4store(Ptr + str_length, n);
str_length += 4;
}
void q_append(double d)
{
float8store(Ptr + str_length, d);
str_length += 8;
}
void q_append(double *d)
{
float8store(Ptr + str_length, *d);
str_length += 8;
}
void q_append(const char *data, size_t data_len)
{
memcpy(Ptr + str_length, data, data_len);
DBUG_ASSERT(str_length <= UINT_MAX32 - data_len);
str_length += (uint)data_len;
}
void q_append(const LEX_CSTRING *ls)
{
DBUG_ASSERT(ls->length < UINT_MAX32 &&
((ls->length == 0 && !ls->str) ||
ls->length == strlen(ls->str)));
q_append(ls->str, (uint32) ls->length);
}
void write_at_position(int position, uint32 value)
{
int4store(Ptr + position,value);
}
void qs_append(const char *str)
{
qs_append(str, (uint32)strlen(str));
}
void qs_append(const LEX_CSTRING *ls)
{
DBUG_ASSERT(ls->length < UINT_MAX32 &&
((ls->length == 0 && !ls->str) ||
ls->length == strlen(ls->str)));
qs_append(ls->str, (uint32)ls->length);
}
void qs_append(const char *str, size_t len);
void qs_append_hex(const char *str, uint32 len);
void qs_append(double d);
void qs_append(double *d);
inline void qs_append(const char c)
{
Ptr[str_length]= c;
str_length++;
}
void qs_append(int i);
void qs_append(uint i)
{
qs_append((ulonglong)i);
}
void qs_append(ulong i)
{
qs_append((ulonglong)i);
}
void qs_append(ulonglong i);
void qs_append(longlong i, int radix)
{
char *buff= Ptr + str_length;
char *end= ll2str(i, buff, radix, 0);
str_length+= uint32(end-buff);
}
};
class String: public Charset, public Static_binary_string
{
uint32 Alloced_length, extra_alloc;
bool alloced,thread_specific; bool alloced,thread_specific;
public: public:
String() String()
{ {
Ptr=0; str_length=Alloced_length=extra_alloc=0; Alloced_length= extra_alloc= 0;
alloced= thread_specific= 0; alloced= thread_specific= 0;
} }
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);
}
String(const char *str, CHARSET_INFO *cs)
:Charset(cs)
{
Ptr=(char*) str; str_length= (uint32) strlen(str);
Alloced_length= extra_alloc= 0; Alloced_length= extra_alloc= 0;
alloced= thread_specific= 0; (void) real_alloc(length_arg);
} }
String(const char *str, CHARSET_INFO *cs)
:String(str, strlen(str), 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
contructors need the size of memory for STR to be at least LEN+1 (to make contructors need the size of memory for STR to be at least LEN+1 (to make
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) :Charset(cs),
Static_binary_string((char *) str, len)
{ {
Ptr=(char*) str; str_length=(uint32)len; Alloced_length= extra_alloc=0; Alloced_length= extra_alloc=0;
alloced= thread_specific= 0; alloced= thread_specific= 0;
} }
String(char *str,size_t len, CHARSET_INFO *cs) String(char *str, size_t len, CHARSET_INFO *cs)
:Charset(cs) :Charset(cs),
Static_binary_string(str, len)
{ {
Ptr=(char*) str; Alloced_length=str_length=(uint32)len; extra_alloc= 0; Alloced_length= (uint32) len;
extra_alloc= 0;
alloced= thread_specific= 0; alloced= thread_specific= 0;
} }
String(const String &str) String(const String &str)
:Charset(str) :Charset(str),
Static_binary_string(str)
{ {
Ptr=str.Ptr ; str_length=str.str_length ; Alloced_length= str.Alloced_length;
Alloced_length=str.Alloced_length; extra_alloc= 0; extra_alloc= 0;
alloced= thread_specific= 0; alloced= thread_specific= 0;
} }
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return (void*) alloc_root(mem_root, size); }
static void *operator new[](size_t size, MEM_ROOT *mem_root) throw ()
{ return alloc_root(mem_root, size); }
static void operator delete(void *ptr_arg, size_t size)
{
(void) ptr_arg;
(void) size;
TRASH_FREE(ptr_arg, size);
}
static void operator delete(void *, MEM_ROOT *)
{ /* never called */ }
static void operator delete[](void *ptr, size_t size)
{ TRASH_FREE(ptr, size); }
static void operator delete[](void *, MEM_ROOT *)
{ /* never called */ }
~String() { free(); } ~String() { free(); }
...@@ -234,16 +415,10 @@ class String: public Charset ...@@ -234,16 +415,10 @@ class String: public Charset
if (!alloced) if (!alloced)
thread_specific= 1; thread_specific= 1;
} }
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;}
inline char& operator [] (size_t i) const { return Ptr[i]; }
inline void length(size_t len) { str_length=(uint32)len ; }
inline void extra_allocation(size_t len) { extra_alloc= (uint32)len; } inline void extra_allocation(size_t len) { extra_alloc= (uint32)len; }
inline bool is_empty() const { return (str_length == 0); }
inline void mark_as_const() { Alloced_length= 0;} inline void mark_as_const() { Alloced_length= 0;}
inline const char *ptr() const { return Ptr; }
inline const char *end() const { return Ptr + str_length; }
inline char *c_ptr() inline char *c_ptr()
{ {
DBUG_ASSERT(!alloced || !Ptr || !Alloced_length || DBUG_ASSERT(!alloced || !Ptr || !Alloced_length ||
...@@ -267,16 +442,6 @@ class String: public Charset ...@@ -267,16 +442,6 @@ class String: public Charset
(void) realloc(str_length); (void) realloc(str_length);
return Ptr; return Ptr;
} }
LEX_STRING lex_string() const
{
LEX_STRING str = { (char*) ptr(), length() };
return str;
}
LEX_CSTRING lex_cstring() const
{
LEX_CSTRING skr = { ptr(), length() };
return skr;
}
void set(String &str,size_t offset,size_t arg_length) void set(String &str,size_t offset,size_t arg_length)
{ {
...@@ -288,7 +453,6 @@ class String: public Charset ...@@ -288,7 +453,6 @@ class String: public Charset
set_charset(str); set_charset(str);
} }
/** /**
Points the internal buffer to the supplied one. The old buffer is freed. Points the internal buffer to the supplied one. The old buffer is freed.
@param str Pointer to the new buffer. @param str Pointer to the new buffer.
...@@ -351,35 +515,6 @@ class String: public Charset ...@@ -351,35 +515,6 @@ class String: public Charset
return old; return old;
} }
/*
PMG 2004.11.12
This is a method that works the same as perl's "chop". It simply
drops the last character of a string. This is useful in the case
of the federated storage handler where I'm building a unknown
number, list of values and fields to be used in a sql insert
statement to be run on the remote server, and have a comma after each.
When the list is complete, I "chop" off the trailing comma
ex.
String stringobj;
stringobj.append("VALUES ('foo', 'fi', 'fo',");
stringobj.chop();
stringobj.append(")");
In this case, the value of string was:
VALUES ('foo', 'fi', 'fo',
VALUES ('foo', 'fi', 'fo'
VALUES ('foo', 'fi', 'fo')
*/
inline void chop()
{
str_length--;
Ptr[str_length]= '\0';
DBUG_ASSERT(strlen(Ptr) == str_length);
}
inline void free() inline void free()
{ {
if (alloced) if (alloced)
...@@ -531,8 +666,6 @@ class String: public Charset ...@@ -531,8 +666,6 @@ class String: public Charset
bool append_with_prefill(const char *s, uint32 arg_length, bool append_with_prefill(const char *s, uint32 arg_length,
uint32 full_length, char fill_char); uint32 full_length, char fill_char);
bool append_parenthesized(long nr, int radix= 10); bool append_parenthesized(long nr, int radix= 10);
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
bool replace(uint32 offset,uint32 arg_length,const char *to,uint32 length); bool replace(uint32 offset,uint32 arg_length,const char *to,uint32 length);
bool replace(uint32 offset,uint32 arg_length,const String &to); bool replace(uint32 offset,uint32 arg_length,const String &to);
inline bool append(char chr) inline bool append(char chr)
...@@ -586,91 +719,6 @@ class String: public Charset ...@@ -586,91 +719,6 @@ class String: public Charset
} }
int reserve(size_t space_needed, size_t grow_by); int reserve(size_t space_needed, size_t grow_by);
/*
The following append operations do NOT check alloced memory
q_*** methods writes values of parameters itself
qs_*** methods writes string representation of value
*/
void q_append(const char c)
{
Ptr[str_length++] = c;
}
void q_append2b(const uint32 n)
{
int2store(Ptr + str_length, n);
str_length += 2;
}
void q_append(const uint32 n)
{
int4store(Ptr + str_length, n);
str_length += 4;
}
void q_append(double d)
{
float8store(Ptr + str_length, d);
str_length += 8;
}
void q_append(double *d)
{
float8store(Ptr + str_length, *d);
str_length += 8;
}
void q_append(const char *data, size_t data_len)
{
memcpy(Ptr + str_length, data, data_len);
DBUG_ASSERT(str_length <= UINT_MAX32 - data_len);
str_length += (uint)data_len;
}
void q_append(const LEX_CSTRING *ls)
{
DBUG_ASSERT(ls->length < UINT_MAX32 &&
((ls->length == 0 && !ls->str) ||
ls->length == strlen(ls->str)));
q_append(ls->str, (uint32) ls->length);
}
void write_at_position(int position, uint32 value)
{
int4store(Ptr + position,value);
}
void qs_append(const char *str)
{
qs_append(str, (uint32)strlen(str));
}
void qs_append(const LEX_CSTRING *ls)
{
DBUG_ASSERT(ls->length < UINT_MAX32 &&
((ls->length == 0 && !ls->str) ||
ls->length == strlen(ls->str)));
qs_append(ls->str, (uint32)ls->length);
}
void qs_append(const char *str, size_t len);
void qs_append_hex(const char *str, uint32 len);
void qs_append(double d);
void qs_append(double *d);
inline void qs_append(const char c)
{
Ptr[str_length]= c;
str_length++;
}
void qs_append(int i);
void qs_append(uint i)
{
qs_append((ulonglong)i);
}
void qs_append(ulong i)
{
qs_append((ulonglong)i);
}
void qs_append(ulonglong i);
void qs_append(longlong i, int radix)
{
char *buff= Ptr + str_length;
char *end= ll2str(i, buff, radix, 0);
str_length+= uint32(end-buff);
}
/* Inline (general) functions used by the protocol functions */ /* Inline (general) functions used by the protocol functions */
inline char *prep_append(uint32 arg_length, uint32 step_alloc) inline char *prep_append(uint32 arg_length, uint32 step_alloc)
...@@ -686,7 +734,6 @@ class String: public Charset ...@@ -686,7 +734,6 @@ class String: public Charset
return Ptr+ old_length; /* Area to use */ return Ptr+ old_length; /* Area to use */
} }
inline bool append(const char *s, uint32 arg_length, uint32 step_alloc) inline bool append(const char *s, uint32 arg_length, uint32 step_alloc)
{ {
uint32 new_length= arg_length + str_length; uint32 new_length= arg_length + str_length;
...@@ -720,7 +767,13 @@ class String: public Charset ...@@ -720,7 +767,13 @@ class String: public Charset
} }
/* Swap two string objects. Efficient way to exchange data without memcpy. */ /* Swap two string objects. Efficient way to exchange data without memcpy. */
void swap(String &s); void swap(String &s)
{
Charset::swap(s);
Static_binary_string::swap(s);
swap_variables(uint32, Alloced_length, s.Alloced_length);
swap_variables(bool, alloced, s.alloced);
}
inline bool uses_buffer_owned_by(const String *s) const inline bool uses_buffer_owned_by(const String *s) const
{ {
...@@ -736,17 +789,7 @@ class String: public Charset ...@@ -736,17 +789,7 @@ class String: public Charset
return TRUE; return TRUE;
if (charset()->mbminlen > 1) if (charset()->mbminlen > 1)
return FALSE; return FALSE;
for (const char *c= ptr(), *c_end= c + length(); c < c_end; c++) return !has_8bit_bytes();
{
if (!my_isascii(*c))
return FALSE;
}
return TRUE;
}
bool bin_eq(const String *other) const
{
return length() == other->length() &&
!memcmp(ptr(), other->ptr(), length());
} }
bool eq(const String *other, CHARSET_INFO *cs) const bool eq(const String *other, CHARSET_INFO *cs) const
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment