Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
bb9b4182
Commit
bb9b4182
authored
Dec 05, 2018
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-17906 Class Binary_string
parent
24d6ec8d
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
388 additions
and
273 deletions
+388
-273
sql/sql_insert.cc
sql/sql_insert.cc
+1
-1
sql/sql_string.cc
sql/sql_string.cc
+23
-67
sql/sql_string.h
sql/sql_string.h
+364
-205
No files found.
sql/sql_insert.cc
View file @
bb9b4182
...
...
@@ -640,7 +640,7 @@ create_insert_stmt_from_insert_delayed(THD *thd, String *buf)
if
(
buf
->
append
(
thd
->
query
())
||
buf
->
replace
(
thd
->
lex
->
keyword_delayed_begin_offset
,
thd
->
lex
->
keyword_delayed_end_offset
-
thd
->
lex
->
keyword_delayed_begin_offset
,
0
))
thd
->
lex
->
keyword_delayed_begin_offset
,
NULL
,
0
))
return
1
;
return
0
;
}
...
...
sql/sql_string.cc
View file @
bb9b4182
...
...
@@ -31,7 +31,7 @@
** String functions
*****************************************************************************/
bool
S
tring
::
real_alloc
(
size_t
length
)
bool
Binary_s
tring
::
real_alloc
(
size_t
length
)
{
size_t
arg_length
=
ALIGN_SIZE
(
length
+
1
);
DBUG_ASSERT
(
arg_length
>
length
);
...
...
@@ -81,7 +81,7 @@ bool String::real_alloc(size_t length)
@retval true An error occurred when attempting to allocate memory.
*/
bool
S
tring
::
realloc_raw
(
size_t
alloc_length
)
bool
Binary_s
tring
::
realloc_raw
(
size_t
alloc_length
)
{
if
(
Alloced_length
<=
alloc_length
)
{
...
...
@@ -132,13 +132,12 @@ bool String::set_int(longlong num, bool unsigned_flag, CHARSET_INFO *cs)
// Convert a number into its HEX representation
bool
S
tring
::
set_hex
(
ulonglong
num
)
bool
Binary_s
tring
::
set_hex
(
ulonglong
num
)
{
char
*
n_end
;
if
(
alloc
(
65
)
||
!
(
n_end
=
longlong2str
(
num
,
Ptr
,
16
)))
return
true
;
length
((
uint32
)
(
n_end
-
Ptr
));
set_charset
(
&
my_charset_latin1
);
return
false
;
}
...
...
@@ -166,7 +165,7 @@ void Static_binary_string::qs_append_hex(const char *str, uint32 len)
// Convert a string to its HEX representation
bool
S
tring
::
set_hex
(
const
char
*
str
,
uint32
len
)
bool
Binary_s
tring
::
set_hex
(
const
char
*
str
,
uint32
len
)
{
/*
Safety: cut the source string if "len" is too large.
...
...
@@ -180,7 +179,6 @@ bool String::set_hex(const char *str, uint32 len)
return
true
;
length
(
0
);
qs_append_hex
(
str
,
len
);
set_charset
(
&
my_charset_latin1
);
return
false
;
}
...
...
@@ -203,7 +201,7 @@ bool String::set_real(double num,uint decimals, CHARSET_INFO *cs)
}
bool
S
tring
::
copy
()
bool
Binary_s
tring
::
copy
()
{
if
(
!
alloced
)
{
...
...
@@ -224,18 +222,17 @@ bool String::copy()
@retval false Success.
@retval true Memory allocation failed.
*/
bool
String
::
copy
(
const
S
tring
&
str
)
bool
Binary_string
::
copy
(
const
Binary_s
tring
&
str
)
{
if
(
alloc
(
str
.
str_length
))
return
TRUE
;
str_length
=
str
.
str_length
;
bmove
(
Ptr
,
str
.
Ptr
,
str_length
);
// May be overlapping
Ptr
[
str_length
]
=
0
;
set_charset
(
str
);
return
FALSE
;
}
bool
String
::
copy
(
const
char
*
str
,
size_t
arg_length
,
CHARSET_INFO
*
cs
)
bool
Binary_string
::
copy
(
const
char
*
str
,
size_t
arg_length
)
{
DBUG_ASSERT
(
arg_length
<
UINT_MAX32
);
if
(
alloc
(
arg_length
))
...
...
@@ -252,7 +249,6 @@ bool String::copy(const char *str,size_t arg_length, CHARSET_INFO *cs)
else
if
((
str_length
=
uint32
(
arg_length
)))
memcpy
(
Ptr
,
str
,
arg_length
);
Ptr
[
arg_length
]
=
0
;
set_charset
(
cs
);
return
FALSE
;
}
...
...
@@ -262,7 +258,7 @@ bool String::copy(const char *str,size_t arg_length, CHARSET_INFO *cs)
from valgrind
*/
bool
String
::
copy_or_move
(
const
char
*
str
,
size_t
arg_length
,
CHARSET_INFO
*
cs
)
bool
Binary_string
::
copy_or_move
(
const
char
*
str
,
size_t
arg_length
)
{
DBUG_ASSERT
(
arg_length
<
UINT_MAX32
);
if
(
alloc
(
arg_length
))
...
...
@@ -270,7 +266,6 @@ bool String::copy_or_move(const char *str,size_t arg_length, CHARSET_INFO *cs)
if
((
str_length
=
uint32
(
arg_length
)))
memmove
(
Ptr
,
str
,
arg_length
);
Ptr
[
arg_length
]
=
0
;
set_charset
(
cs
);
return
FALSE
;
}
...
...
@@ -488,7 +483,7 @@ bool String::set_ascii(const char *str, size_t arg_length)
/* This is used by mysql.cc */
bool
S
tring
::
fill
(
uint32
max_length
,
char
fill_char
)
bool
Binary_s
tring
::
fill
(
uint32
max_length
,
char
fill_char
)
{
if
(
str_length
>
max_length
)
Ptr
[
str_length
=
max_length
]
=
0
;
...
...
@@ -508,18 +503,6 @@ void String::strip_sp()
str_length
--
;
}
bool
String
::
append
(
const
String
&
s
)
{
if
(
s
.
length
())
{
if
(
realloc_with_extra_if_needed
(
str_length
+
s
.
length
()))
return
TRUE
;
memcpy
(
Ptr
+
str_length
,
s
.
ptr
(),
s
.
length
());
str_length
+=
s
.
length
();
}
return
FALSE
;
}
/*
Append an ASCII string to the a string of the current character set
...
...
@@ -550,24 +533,11 @@ bool String::append(const char *s,size_t size)
/*
For an ASCII compatinble string we can just append.
*/
if
(
realloc_with_extra_if_needed
(
str_length
+
arg_length
))
return
TRUE
;
memcpy
(
Ptr
+
str_length
,
s
,
arg_length
);
str_length
+=
arg_length
;
return
FALSE
;
return
Binary_string
::
append
(
s
,
arg_length
);
}
/*
Append a 0-terminated ASCII string
*/
bool
String
::
append
(
const
char
*
s
)
{
return
append
(
s
,
(
uint
)
strlen
(
s
));
}
bool
String
::
append_longlong
(
longlong
val
)
bool
Binary_string
::
append_longlong
(
longlong
val
)
{
if
(
realloc
(
str_length
+
MAX_BIGINT_WIDTH
+
2
))
return
TRUE
;
...
...
@@ -577,7 +547,7 @@ bool String::append_longlong(longlong val)
}
bool
S
tring
::
append_ulonglong
(
ulonglong
val
)
bool
Binary_s
tring
::
append_ulonglong
(
ulonglong
val
)
{
if
(
realloc
(
str_length
+
MAX_BIGINT_WIDTH
+
2
))
return
TRUE
;
...
...
@@ -617,18 +587,13 @@ bool String::append(const char *s, size_t arg_length, CHARSET_INFO *cs)
return
TRUE
;
str_length
+=
copy_and_convert
(
Ptr
+
str_length
,
(
uint32
)
add_length
,
charset
(),
s
,
(
uint32
)
arg_length
,
cs
,
&
dummy_errors
);
return
false
;
}
else
{
if
(
realloc_with_extra_if_needed
(
str_length
+
arg_length
))
return
TRUE
;
memcpy
(
Ptr
+
str_length
,
s
,
arg_length
);
str_length
+=
(
uint32
)
arg_length
;
}
return
FALSE
;
return
Binary_string
::
append
(
s
,
arg_length
);
}
bool
String
::
append
(
IO_CACHE
*
file
,
uint32
arg_length
)
bool
Binary_string
::
append
(
IO_CACHE
*
file
,
uint32
arg_length
)
{
if
(
realloc_with_extra_if_needed
(
str_length
+
arg_length
))
return
TRUE
;
...
...
@@ -735,17 +700,8 @@ int Static_binary_string::strrstr(const Static_binary_string &s, uint32 offset)
return
-
1
;
}
/*
Replace substring with string
If wrong parameter or not enough memory, do nothing
*/
bool
String
::
replace
(
uint32
offset
,
uint32
arg_length
,
const
String
&
to
)
{
return
replace
(
offset
,
arg_length
,
to
.
ptr
(),
to
.
length
());
}
bool
String
::
replace
(
uint32
offset
,
uint32
arg_length
,
bool
Binary_string
::
replace
(
uint32
offset
,
uint32
arg_length
,
const
char
*
to
,
uint32
to_length
)
{
long
diff
=
(
long
)
to_length
-
(
long
)
arg_length
;
...
...
@@ -777,7 +733,7 @@ bool String::replace(uint32 offset,uint32 arg_length,
// added by Holyfoot for "geometry" needs
int
S
tring
::
reserve
(
size_t
space_needed
,
size_t
grow_by
)
int
Binary_s
tring
::
reserve
(
size_t
space_needed
,
size_t
grow_by
)
{
if
(
Alloced_length
<
str_length
+
space_needed
)
{
...
...
@@ -936,12 +892,12 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
of a constant string.
Not safe to reuse.
*/
if
(
from
->
Alloced_length
>
0
)
// "from" is #c or #d (not a constant)
if
(
from
->
alloced_length
()
>
0
)
// "from" is #c or #d (not a constant)
{
if
(
from
->
Alloced_length
>=
from_length
)
if
(
from
->
alloced_length
()
>=
from_length
)
return
from
;
// #c or #d (large enough to store from_length bytes)
if
(
from
->
alloced
)
if
(
from
->
is_alloced
()
)
{
(
void
)
from
->
realloc
(
from_length
);
return
from
;
// #d (reallocated to fit from_length bytes)
...
...
@@ -980,7 +936,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
Note, as we can't distinguish between #a and #b for sure,
so we can't assert "not #a", but we can at least assert "not #e".
*/
DBUG_ASSERT
(
!
from
->
alloced
||
from
->
Alloced_length
>
0
);
// Not #e
DBUG_ASSERT
(
!
from
->
is_alloced
()
||
from
->
alloced_length
()
>
0
);
// Not #e
(
void
)
from
->
realloc
(
from_length
);
return
from
;
...
...
sql/sql_string.h
View file @
bb9b4182
...
...
@@ -233,6 +233,12 @@ class Static_binary_string
!
memcmp
(
ptr
(),
other
->
ptr
(),
length
());
}
void
set
(
char
*
str
,
size_t
len
)
{
Ptr
=
str
;
str_length
=
(
uint32
)
len
;
}
void
swap
(
Static_binary_string
&
s
)
{
swap_variables
(
char
*
,
Ptr
,
s
.
Ptr
);
...
...
@@ -359,55 +365,54 @@ class Static_binary_string
};
class
String
:
public
Charset
,
public
Static_binary_string
class
Binary_string
:
public
Static_binary_string
{
uint32
Alloced_length
,
extra_alloc
;
bool
alloced
,
thread_specific
;
public:
String
()
bool
alloced
,
thread_specific
;
void
init_private_data
()
{
Alloced_length
=
extra_alloc
=
0
;
alloced
=
thread_specific
=
0
;
alloced
=
thread_specific
=
false
;
}
String
(
size_t
length_arg
)
public:
Binary_string
()
{
alloced
=
thread_specific
=
0
;
Alloced_length
=
extra_alloc
=
0
;
init_private_data
();
}
explicit
Binary_string
(
size_t
length_arg
)
{
init_private_data
();
(
void
)
real_alloc
(
length_arg
);
}
String
(
const
char
*
str
,
CHARSET_INFO
*
cs
)
:
String
(
str
,
strlen
(
str
),
cs
)
explicit
Binary_string
(
const
char
*
str
)
:
Binary_string
(
str
,
strlen
(
str
)
)
{
}
/*
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
room for zero termination).
*/
String
(
const
char
*
str
,
size_t
len
,
CHARSET_INFO
*
cs
)
:
Charset
(
cs
),
Static_binary_string
((
char
*
)
str
,
len
)
Binary_string
(
const
char
*
str
,
size_t
len
)
:
Static_binary_string
((
char
*
)
str
,
len
)
{
Alloced_length
=
extra_alloc
=
0
;
alloced
=
thread_specific
=
0
;
init_private_data
();
}
String
(
char
*
str
,
size_t
len
,
CHARSET_INFO
*
cs
)
:
Charset
(
cs
),
Static_binary_string
(
str
,
len
)
Binary_string
(
char
*
str
,
size_t
len
)
:
Static_binary_string
(
str
,
len
)
{
Alloced_length
=
(
uint32
)
len
;
extra_alloc
=
0
;
alloced
=
thread_specific
=
0
;
}
String
(
const
String
&
str
)
:
Charset
(
str
),
Static_binary_string
(
str
)
explicit
Binary_string
(
const
Binary_string
&
str
)
:
Static_binary_string
(
str
)
{
Alloced_length
=
str
.
Alloced_length
;
extra_alloc
=
0
;
alloced
=
thread_specific
=
0
;
}
~
S
tring
()
{
free
();
}
~
Binary_s
tring
()
{
free
();
}
/* Mark variable thread specific it it's not allocated already */
inline
void
set_thread_specific
()
...
...
@@ -415,42 +420,23 @@ class String: public Charset, public Static_binary_string
if
(
!
alloced
)
thread_specific
=
1
;
}
bool
is_alloced
()
const
{
return
alloced
;
}
inline
uint32
alloced_length
()
const
{
return
Alloced_length
;}
inline
uint32
extra_allocation
()
const
{
return
extra_alloc
;}
inline
void
extra_allocation
(
size_t
len
)
{
extra_alloc
=
(
uint32
)
len
;
}
inline
void
mark_as_const
()
{
Alloced_length
=
0
;}
inline
char
*
c_ptr
()
{
DBUG_ASSERT
(
!
alloced
||
!
Ptr
||
!
Alloced_length
||
(
Alloced_length
>=
(
str_length
+
1
)));
if
(
!
Ptr
||
Ptr
[
str_length
])
/* Should be safe */
(
void
)
realloc
(
str_length
);
return
Ptr
;
}
inline
char
*
c_ptr_quick
()
inline
bool
uses_buffer_owned_by
(
const
Binary_string
*
s
)
const
{
if
(
Ptr
&&
str_length
<
Alloced_length
)
Ptr
[
str_length
]
=
0
;
return
Ptr
;
}
inline
char
*
c_ptr_safe
()
{
if
(
Ptr
&&
str_length
<
Alloced_length
)
Ptr
[
str_length
]
=
0
;
else
(
void
)
realloc
(
str_length
);
return
Ptr
;
return
(
s
->
alloced
&&
Ptr
>=
s
->
Ptr
&&
Ptr
<
s
->
Ptr
+
s
->
str_length
);
}
void
set
(
String
&
str
,
size_t
offset
,
size_t
arg_length
)
/* Swap two string objects. Efficient way to exchange data without memcpy. */
void
swap
(
Binary_string
&
s
)
{
DBUG_ASSERT
(
&
str
!=
this
);
free
();
Ptr
=
(
char
*
)
str
.
ptr
()
+
offset
;
str_length
=
(
uint32
)
arg_length
;
if
(
str
.
Alloced_length
)
Alloced_length
=
(
uint32
)(
str
.
Alloced_length
-
offset
);
set_charset
(
str
);
Static_binary_string
::
swap
(
s
);
swap_variables
(
uint32
,
Alloced_length
,
s
.
Alloced_length
);
swap_variables
(
bool
,
alloced
,
s
.
alloced
);
}
/**
...
...
@@ -458,51 +444,38 @@ class String: public Charset, public Static_binary_string
@param str Pointer to the new buffer.
@param arg_length Length of the new buffer in characters, excluding any
null character.
@param cs Character set to use for interpreting string data.
@note The new buffer will not be null terminated.
*/
inline
void
set
(
char
*
str
,
size_t
arg_length
,
CHARSET_INFO
*
cs
)
void
set_alloced
(
char
*
str
,
size_t
length_arg
,
size_t
alloced_length_arg
)
{
free
();
Ptr
=
(
char
*
)
str
;
str_length
=
Alloced_length
=
(
uint32
)
arg_length
;
set_charset
(
cs
);
Static_binary_string
::
set
(
str
,
length_arg
);
DBUG_ASSERT
(
alloced_length_arg
<
UINT_MAX32
);
Alloced_length
=
(
uint32
)
alloced_length_arg
;
}
inline
void
set
(
c
onst
char
*
str
,
size_t
arg_length
,
CHARSET_INFO
*
cs
)
inline
void
set
(
c
har
*
str
,
size_t
arg_length
)
{
free
();
Ptr
=
(
char
*
)
str
;
str_length
=
(
uint32
)
arg_length
;
set_charset
(
cs
);
set_alloced
(
str
,
arg_length
,
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
(
const
char
*
str
,
size_t
arg_length
)
{
if
(
!
alloced
)
{
Ptr
=
(
char
*
)
str
;
str_length
=
Alloced_length
=
(
uint32
)
arg_length
;
}
set_charset
(
cs
);
free
();
Static_binary_string
::
set
((
char
*
)
str
,
arg_length
);
}
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
(
uint
num
,
CHARSET_INFO
*
cs
)
{
return
set_int
(
num
,
true
,
cs
);
}
bool
set
(
long
num
,
CHARSET_INFO
*
cs
)
{
return
set_int
(
num
,
false
,
cs
);
}
bool
set
(
ulong
num
,
CHARSET_INFO
*
cs
)
{
return
set_int
(
num
,
true
,
cs
);
}
bool
set
(
longlong
num
,
CHARSET_INFO
*
cs
)
{
return
set_int
(
num
,
false
,
cs
);
}
bool
set
(
ulonglong
num
,
CHARSET_INFO
*
cs
)
{
return
set_int
((
longlong
)
num
,
true
,
cs
);
}
bool
set_real
(
double
num
,
uint
decimals
,
CHARSET_INFO
*
cs
);
bool
set_hex
(
ulonglong
num
);
bool
set_hex
(
const
char
*
str
,
uint32
len
);
void
set
(
Binary_string
&
str
,
size_t
offset
,
size_t
arg_length
)
{
DBUG_ASSERT
(
&
str
!=
this
);
free
();
Static_binary_string
::
set
((
char
*
)
str
.
ptr
()
+
offset
,
arg_length
);
if
(
str
.
Alloced_length
)
Alloced_length
=
(
uint32
)
(
str
.
Alloced_length
-
offset
);
}
/* Take over handling of buffer from some other object */
void
reset
(
char
*
ptr_arg
,
size_t
length_arg
,
size_t
alloced_length_arg
,
CHARSET_INFO
*
cs
)
void
reset
(
char
*
ptr_arg
,
size_t
length_arg
,
size_t
alloced_length_arg
)
{
free
();
Ptr
=
ptr_arg
;
str_length
=
(
uint32
)
length_arg
;
Alloced_length
=
(
uint32
)
alloced_length_arg
;
set_charset
(
cs
);
set_alloced
(
ptr_arg
,
length_arg
,
alloced_length_arg
);
alloced
=
ptr_arg
!=
0
;
}
...
...
@@ -510,11 +483,119 @@ class String: public Charset, public Static_binary_string
char
*
release
()
{
char
*
old
=
Ptr
;
Ptr
=
0
;
str_length
=
Alloced_length
=
extra_alloc
=
0
;
alloced
=
thread_specific
=
0
;
Static_binary_string
::
set
(
NULL
,
0
)
;
init_private_data
()
;
return
old
;
}
inline
void
set_quick
(
char
*
str
,
size_t
arg_length
)
{
if
(
!
alloced
)
{
Static_binary_string
::
set
(
str
,
arg_length
);
Alloced_length
=
(
uint32
)
arg_length
;
}
}
inline
Binary_string
&
operator
=
(
const
Binary_string
&
s
)
{
if
(
&
s
!=
this
)
{
/*
It is forbidden to do assignments like
some_string = substring_of_that_string
*/
DBUG_ASSERT
(
!
s
.
uses_buffer_owned_by
(
this
));
set_alloced
((
char
*
)
s
.
Ptr
,
s
.
str_length
,
s
.
Alloced_length
);
}
return
*
this
;
}
bool
set_hex
(
ulonglong
num
);
bool
set_hex
(
const
char
*
str
,
uint32
len
);
bool
copy
();
// Alloc string if not alloced
bool
copy
(
const
Binary_string
&
s
);
// Allocate new string
bool
copy
(
const
char
*
s
,
size_t
arg_length
);
// Allocate new string
bool
copy_or_move
(
const
char
*
s
,
size_t
arg_length
);
bool
append_ulonglong
(
ulonglong
val
);
bool
append_longlong
(
longlong
val
);
bool
append
(
const
char
*
s
,
size_t
size
)
{
if
(
!
size
)
return
false
;
if
(
realloc_with_extra_if_needed
(
str_length
+
size
))
return
true
;
q_append
(
s
,
size
);
return
false
;
}
bool
append
(
const
Binary_string
&
s
)
{
return
append
(
s
.
ptr
(),
s
.
length
());
}
bool
append
(
IO_CACHE
*
file
,
uint32
arg_length
);
inline
bool
append_char
(
char
chr
)
{
if
(
str_length
<
Alloced_length
)
{
Ptr
[
str_length
++
]
=
chr
;
}
else
{
if
(
unlikely
(
realloc_with_extra
(
str_length
+
1
)))
return
true
;
Ptr
[
str_length
++
]
=
chr
;
}
return
false
;
}
bool
append_hex
(
const
char
*
src
,
uint32
srclen
)
{
for
(
const
char
*
src_end
=
src
+
srclen
;
src
!=
src_end
;
src
++
)
{
if
(
unlikely
(
append_char
(
_dig_vec_lower
[((
uchar
)
*
src
)
>>
4
]))
||
unlikely
(
append_char
(
_dig_vec_lower
[((
uchar
)
*
src
)
&
0x0F
])))
return
true
;
}
return
false
;
}
bool
append_with_step
(
const
char
*
s
,
uint32
arg_length
,
uint32
step_alloc
)
{
uint32
new_length
=
arg_length
+
str_length
;
if
(
new_length
>
Alloced_length
&&
unlikely
(
realloc
(
new_length
+
step_alloc
)))
return
true
;
q_append
(
s
,
arg_length
);
return
false
;
}
inline
char
*
c_ptr
()
{
DBUG_ASSERT
(
!
alloced
||
!
Ptr
||
!
Alloced_length
||
(
Alloced_length
>=
(
str_length
+
1
)));
if
(
!
Ptr
||
Ptr
[
str_length
])
// Should be safe
(
void
)
realloc
(
str_length
);
return
Ptr
;
}
inline
char
*
c_ptr_quick
()
{
if
(
Ptr
&&
str_length
<
Alloced_length
)
Ptr
[
str_length
]
=
0
;
return
Ptr
;
}
inline
char
*
c_ptr_safe
()
{
if
(
Ptr
&&
str_length
<
Alloced_length
)
Ptr
[
str_length
]
=
0
;
else
(
void
)
realloc
(
str_length
);
return
Ptr
;
}
inline
void
free
()
{
if
(
alloced
)
...
...
@@ -523,8 +604,7 @@ class String: public Charset, public Static_binary_string
my_free
(
Ptr
);
}
Alloced_length
=
extra_alloc
=
0
;
Ptr
=
0
;
str_length
=
0
;
/* Safety */
Static_binary_string
::
set
(
NULL
,
0
);
// Safety
}
inline
bool
alloc
(
size_t
arg_length
)
{
...
...
@@ -538,7 +618,7 @@ class String: public Charset, public Static_binary_string
{
if
(
realloc_raw
(
arg_length
))
return
TRUE
;
Ptr
[
arg_length
]
=
0
;
// This make other funcs shorter
Ptr
[
arg_length
]
=
0
;
// This make other funcs shorter
return
FALSE
;
}
bool
realloc_with_extra
(
size_t
arg_length
)
...
...
@@ -572,37 +652,179 @@ class String: public Charset, public Static_binary_string
arg_length
,
MYF
((
thread_specific
?
MY_THREAD_SPECIFIC
:
0
))))))
{
Alloced_length
=
0
;
Alloced_length
=
0
;
real_alloc
(
arg_length
);
}
else
{
Ptr
=
new_ptr
;
Alloced_length
=
(
uint32
)
arg_length
;
Ptr
=
new_ptr
;
Alloced_length
=
(
uint32
)
arg_length
;
}
}
}
bool
is_alloced
()
const
{
return
alloced
;
}
inline
String
&
operator
=
(
const
String
&
s
)
void
move
(
Binary_string
&
s
)
{
if
(
&
s
!=
this
)
set_alloced
(
s
.
Ptr
,
s
.
str_length
,
s
.
Alloced_length
);
extra_alloc
=
s
.
extra_alloc
;
alloced
=
s
.
alloced
;
thread_specific
=
s
.
thread_specific
;
s
.
alloced
=
0
;
}
bool
fill
(
uint32
max_length
,
char
fill
);
/*
Replace substring with string
If wrong parameter or not enough memory, do nothing
*/
bool
replace
(
uint32
offset
,
uint32
arg_length
,
const
char
*
to
,
uint32
length
);
bool
replace
(
uint32
offset
,
uint32
arg_length
,
const
Static_binary_string
&
to
)
{
return
replace
(
offset
,
arg_length
,
to
.
ptr
(),
to
.
length
());
}
int
reserve
(
size_t
space_needed
)
{
return
realloc
(
str_length
+
space_needed
);
}
int
reserve
(
size_t
space_needed
,
size_t
grow_by
);
inline
char
*
prep_append
(
uint32
arg_length
,
uint32
step_alloc
)
{
uint32
new_length
=
arg_length
+
str_length
;
if
(
new_length
>
Alloced_length
)
{
if
(
unlikely
(
realloc
(
new_length
+
step_alloc
)))
return
0
;
}
uint32
old_length
=
str_length
;
str_length
+=
arg_length
;
return
Ptr
+
old_length
;
// Area to use
}
void
q_net_store_length
(
ulonglong
length
)
{
DBUG_ASSERT
(
Alloced_length
>=
(
str_length
+
net_length_size
(
length
)));
char
*
pos
=
(
char
*
)
net_store_length
((
uchar
*
)(
Ptr
+
str_length
),
length
);
str_length
=
uint32
(
pos
-
Ptr
);
}
void
q_net_store_data
(
const
uchar
*
from
,
size_t
length
)
{
DBUG_ASSERT
(
length
<
UINT_MAX32
);
DBUG_ASSERT
(
Alloced_length
>=
(
str_length
+
length
+
net_length_size
(
length
)));
q_net_store_length
(
length
);
q_append
((
const
char
*
)
from
,
(
uint32
)
length
);
}
};
class
String
:
public
Charset
,
public
Binary_string
{
public:
String
()
{
}
String
(
size_t
length_arg
)
:
Binary_string
(
length_arg
)
{
}
String
(
const
char
*
str
,
CHARSET_INFO
*
cs
)
:
Charset
(
cs
),
Binary_string
(
str
)
{
}
/*
It is forbidden to do assignments like
some_string = substring_of_that_string
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
room for zero termination).
*/
DBUG_ASSERT
(
!
s
.
uses_buffer_owned_by
(
this
));
free
();
Ptr
=
s
.
Ptr
;
str_length
=
s
.
str_length
;
Alloced_length
=
s
.
Alloced_length
;
String
(
const
char
*
str
,
size_t
len
,
CHARSET_INFO
*
cs
)
:
Charset
(
cs
),
Binary_string
((
char
*
)
str
,
len
)
{
}
String
(
char
*
str
,
size_t
len
,
CHARSET_INFO
*
cs
)
:
Charset
(
cs
),
Binary_string
(
str
,
len
)
{
}
String
(
const
String
&
str
)
:
Charset
(
str
),
Binary_string
(
str
)
{
}
void
set
(
String
&
str
,
size_t
offset
,
size_t
arg_length
)
{
Binary_string
::
set
(
str
,
offset
,
arg_length
);
set_charset
(
str
);
}
inline
void
set
(
char
*
str
,
size_t
arg_length
,
CHARSET_INFO
*
cs
)
{
Binary_string
::
set
(
str
,
arg_length
);
set_charset
(
cs
);
}
inline
void
set
(
const
char
*
str
,
size_t
arg_length
,
CHARSET_INFO
*
cs
)
{
Binary_string
::
set
(
str
,
arg_length
);
set_charset
(
cs
);
}
bool
set_ascii
(
const
char
*
str
,
size_t
arg_length
);
inline
void
set_quick
(
char
*
str
,
size_t
arg_length
,
CHARSET_INFO
*
cs
)
{
Binary_string
::
set_quick
(
str
,
arg_length
);
set_charset
(
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
(
uint
num
,
CHARSET_INFO
*
cs
)
{
return
set_int
(
num
,
true
,
cs
);
}
bool
set
(
long
num
,
CHARSET_INFO
*
cs
)
{
return
set_int
(
num
,
false
,
cs
);
}
bool
set
(
ulong
num
,
CHARSET_INFO
*
cs
)
{
return
set_int
(
num
,
true
,
cs
);
}
bool
set
(
longlong
num
,
CHARSET_INFO
*
cs
)
{
return
set_int
(
num
,
false
,
cs
);
}
bool
set
(
ulonglong
num
,
CHARSET_INFO
*
cs
)
{
return
set_int
((
longlong
)
num
,
true
,
cs
);
}
bool
set_real
(
double
num
,
uint
decimals
,
CHARSET_INFO
*
cs
);
bool
set_hex
(
ulonglong
num
)
{
set_charset
(
&
my_charset_latin1
);
return
Binary_string
::
set_hex
(
num
);
}
bool
set_hex
(
const
char
*
str
,
uint32
len
)
{
set_charset
(
&
my_charset_latin1
);
return
Binary_string
::
set_hex
(
str
,
len
);
}
/* Take over handling of buffer from some other object */
void
reset
(
char
*
ptr_arg
,
size_t
length_arg
,
size_t
alloced_length_arg
,
CHARSET_INFO
*
cs
)
{
Binary_string
::
reset
(
ptr_arg
,
length_arg
,
alloced_length_arg
);
set_charset
(
cs
);
}
inline
String
&
operator
=
(
const
String
&
s
)
{
if
(
&
s
!=
this
)
{
set_charset
(
s
);
Binary_string
::
operator
=
(
s
);
}
return
*
this
;
}
bool
copy
();
// Alloc string if not alloced
bool
copy
(
const
String
&
s
);
// Allocate new string
bool
copy
(
const
char
*
s
,
size_t
arg_length
,
CHARSET_INFO
*
cs
);
// Allocate new string
bool
copy_or_move
(
const
char
*
s
,
size_t
arg_length
,
CHARSET_INFO
*
cs
);
bool
copy
()
{
return
Binary_string
::
copy
();
}
bool
copy
(
const
String
&
s
)
{
set_charset
(
s
);
return
Binary_string
::
copy
(
s
);
}
bool
copy
(
const
char
*
s
,
size_t
arg_length
,
CHARSET_INFO
*
cs
)
{
set_charset
(
cs
);
return
Binary_string
::
copy
(
s
,
arg_length
);
}
bool
copy_or_move
(
const
char
*
s
,
size_t
arg_length
,
CHARSET_INFO
*
cs
)
{
set_charset
(
cs
);
return
Binary_string
::
copy_or_move
(
s
,
arg_length
);
}
static
bool
needs_conversion
(
size_t
arg_length
,
CHARSET_INFO
*
cs_from
,
CHARSET_INFO
*
cs_to
,
uint32
*
offset
);
...
...
@@ -624,22 +846,42 @@ class String: public Charset, public Static_binary_string
{
if
(
unlikely
(
alloc
(
tocs
->
mbmaxlen
*
src_length
)))
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
);
set_charset
(
tocs
);
return
false
;
}
void
move
(
String
&
s
)
// Append without character set conversion
bool
append
(
const
String
&
s
)
{
free
();
Ptr
=
s
.
Ptr
;
str_length
=
s
.
str_length
;
Alloced_length
=
s
.
Alloced_length
;
extra_alloc
=
s
.
extra_alloc
;
alloced
=
s
.
alloced
;
thread_specific
=
s
.
thread_specific
;
s
.
alloced
=
0
;
return
Binary_string
::
append
(
s
);
}
inline
bool
append
(
char
chr
)
{
return
Binary_string
::
append_char
(
chr
);
}
bool
append_hex
(
const
char
*
src
,
uint32
srclen
)
{
return
Binary_string
::
append_hex
(
src
,
srclen
);
}
bool
append_hex
(
const
uchar
*
src
,
uint32
srclen
)
{
return
Binary_string
::
append_hex
((
const
char
*
)
src
,
srclen
);
}
bool
append
(
IO_CACHE
*
file
,
uint32
arg_length
)
{
return
Binary_string
::
append
(
file
,
arg_length
);
}
inline
bool
append
(
const
char
*
s
,
uint32
arg_length
,
uint32
step_alloc
)
{
return
append_with_step
(
s
,
arg_length
,
step_alloc
);
}
// Append with optional character set conversion from ASCII (e.g. to UCS2)
bool
append
(
const
char
*
s
)
{
return
append
(
s
,
strlen
(
s
));
}
bool
append
(
const
String
&
s
);
bool
append
(
const
char
*
s
);
bool
append
(
const
LEX_STRING
*
ls
)
{
DBUG_ASSERT
(
ls
->
length
<
UINT_MAX32
&&
...
...
@@ -659,44 +901,13 @@ class String: public Charset, public Static_binary_string
return
append
(
&
ls
);
}
bool
append
(
const
char
*
s
,
size_t
size
);
bool
append
(
const
char
*
s
,
size_t
arg_length
,
CHARSET_INFO
*
cs
);
bool
append_ulonglong
(
ulonglong
val
);
bool
append_longlong
(
longlong
val
);
bool
append
(
IO_CACHE
*
file
,
uint32
arg_length
);
bool
append_with_prefill
(
const
char
*
s
,
uint32
arg_length
,
uint32
full_length
,
char
fill_char
);
bool
append_parenthesized
(
long
nr
,
int
radix
=
10
);
bool
replace
(
uint32
offset
,
uint32
arg_length
,
const
char
*
to
,
uint32
length
);
bool
replace
(
uint32
offset
,
uint32
arg_length
,
const
String
&
to
);
inline
bool
append
(
char
chr
)
{
if
(
str_length
<
Alloced_length
)
{
Ptr
[
str_length
++
]
=
chr
;
}
else
{
if
(
unlikely
(
realloc_with_extra
(
str_length
+
1
)))
return
1
;
Ptr
[
str_length
++
]
=
chr
;
}
return
0
;
}
bool
append_hex
(
const
char
*
src
,
uint32
srclen
)
{
for
(
const
char
*
src_end
=
src
+
srclen
;
src
!=
src_end
;
src
++
)
{
if
(
unlikely
(
append
(
_dig_vec_lower
[((
uchar
)
*
src
)
>>
4
]))
||
unlikely
(
append
(
_dig_vec_lower
[((
uchar
)
*
src
)
&
0x0F
])))
return
true
;
}
return
false
;
}
bool
append_hex
(
const
uchar
*
src
,
uint32
srclen
)
{
return
append_hex
((
const
char
*
)
src
,
srclen
);
}
bool
fill
(
uint32
max_length
,
char
fill
);
// Append with optional character set conversion from cs to charset()
bool
append
(
const
char
*
s
,
size_t
arg_length
,
CHARSET_INFO
*
cs
);
void
strip_sp
();
friend
int
sortcmp
(
const
String
*
a
,
const
String
*
b
,
CHARSET_INFO
*
cs
);
friend
int
stringcmp
(
const
String
*
a
,
const
String
*
b
);
...
...
@@ -713,37 +924,6 @@ class String: public Charset, public Static_binary_string
return
(
int
)
Charset
::
charpos
(
ptr
()
+
offset
,
end
(),
(
size_t
)
i
);
}
int
reserve
(
size_t
space_needed
)
{
return
realloc
(
str_length
+
space_needed
);
}
int
reserve
(
size_t
space_needed
,
size_t
grow_by
);
/* Inline (general) functions used by the protocol functions */
inline
char
*
prep_append
(
uint32
arg_length
,
uint32
step_alloc
)
{
uint32
new_length
=
arg_length
+
str_length
;
if
(
new_length
>
Alloced_length
)
{
if
(
unlikely
(
realloc
(
new_length
+
step_alloc
)))
return
0
;
}
uint32
old_length
=
str_length
;
str_length
+=
arg_length
;
return
Ptr
+
old_length
;
/* Area to use */
}
inline
bool
append
(
const
char
*
s
,
uint32
arg_length
,
uint32
step_alloc
)
{
uint32
new_length
=
arg_length
+
str_length
;
if
(
new_length
>
Alloced_length
&&
unlikely
(
realloc
(
new_length
+
step_alloc
)))
return
TRUE
;
memcpy
(
Ptr
+
str_length
,
s
,
arg_length
);
str_length
+=
arg_length
;
return
FALSE
;
}
void
print
(
String
*
to
)
const
;
void
print_with_conversion
(
String
*
to
,
CHARSET_INFO
*
cs
)
const
;
void
print
(
String
*
to
,
CHARSET_INFO
*
cs
)
const
...
...
@@ -766,19 +946,12 @@ class String: public Charset, public Static_binary_string
return
append_for_single_quote
(
st
,
(
uint32
)
len
);
}
/* Swap two string objects. Efficient way to exchange data without memcpy. */
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
);
Binary_string
::
swap
(
s
);
}
inline
bool
uses_buffer_owned_by
(
const
String
*
s
)
const
{
return
(
s
->
alloced
&&
Ptr
>=
s
->
Ptr
&&
Ptr
<
s
->
Ptr
+
s
->
str_length
);
}
uint
well_formed_length
()
const
{
return
(
uint
)
Well_formed_prefix
(
charset
(),
ptr
(),
length
()).
length
();
...
...
@@ -795,20 +968,6 @@ class String: public Charset, public Static_binary_string
{
return
!
sortcmp
(
this
,
other
,
cs
);
}
void
q_net_store_length
(
ulonglong
length
)
{
DBUG_ASSERT
(
Alloced_length
>=
(
str_length
+
net_length_size
(
length
)));
char
*
pos
=
(
char
*
)
net_store_length
((
uchar
*
)(
Ptr
+
str_length
),
length
);
str_length
=
uint32
(
pos
-
Ptr
);
}
void
q_net_store_data
(
const
uchar
*
from
,
size_t
length
)
{
DBUG_ASSERT
(
length
<
UINT_MAX32
);
DBUG_ASSERT
(
Alloced_length
>=
(
str_length
+
length
+
net_length_size
(
length
)));
q_net_store_length
(
length
);
q_append
((
const
char
*
)
from
,
(
uint32
)
length
);
}
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment