summaryrefslogtreecommitdiff
path: root/sql/sql_string.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_string.h')
-rw-r--r--sql/sql_string.h127
1 files changed, 101 insertions, 26 deletions
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 234e8272b88..020628100cb 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -1,7 +1,9 @@
#ifndef SQL_STRING_INCLUDED
#define SQL_STRING_INCLUDED
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2013, Oracle and/or its affiliates.
+ Copyright (c) 2008, 2013, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,7 +29,6 @@
#include "m_string.h" /* TRASH */
class String;
-typedef struct charset_info_st CHARSET_INFO;
typedef struct st_io_cache IO_CACHE;
typedef struct st_mem_root MEM_ROOT;
@@ -54,39 +55,45 @@ uint convert_to_printable(char *to, size_t to_len,
class String
{
char *Ptr;
- uint32 str_length,Alloced_length;
+ uint32 str_length,Alloced_length, extra_alloc;
bool alloced;
CHARSET_INFO *str_charset;
public:
String()
{
- Ptr=0; str_length=Alloced_length=0; alloced=0;
+ Ptr=0; str_length=Alloced_length=extra_alloc=0; alloced=0;
str_charset= &my_charset_bin;
}
String(uint32 length_arg)
{
- alloced=0; Alloced_length=0; (void) real_alloc(length_arg);
+ alloced=0; Alloced_length= extra_alloc= 0; (void) real_alloc(length_arg);
str_charset= &my_charset_bin;
}
String(const char *str, CHARSET_INFO *cs)
{
- Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;
+ Ptr=(char*) str; str_length= (uint32) strlen(str);
+ Alloced_length= extra_alloc= 0; alloced=0;
str_charset=cs;
}
+ /*
+ 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,uint32 len, CHARSET_INFO *cs)
{
- Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;
+ Ptr=(char*) str; str_length=len; Alloced_length= extra_alloc=0; alloced=0;
str_charset=cs;
}
String(char *str,uint32 len, CHARSET_INFO *cs)
{
- Ptr=(char*) str; Alloced_length=str_length=len; alloced=0;
+ Ptr=(char*) str; Alloced_length=str_length=len; extra_alloc= 0; alloced=0;
str_charset=cs;
}
String(const String &str)
{
Ptr=str.Ptr ; str_length=str.str_length ;
- Alloced_length=str.Alloced_length; alloced=0;
+ Alloced_length=str.Alloced_length; extra_alloc= 0; alloced=0;
str_charset=str.str_charset;
}
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
@@ -106,8 +113,10 @@ public:
inline CHARSET_INFO *charset() const { return str_charset; }
inline uint32 length() const { return str_length;}
inline uint32 alloced_length() const { return Alloced_length;}
+ inline uint32 extra_allocation() const { return extra_alloc;}
inline char& operator [] (uint32 i) const { return Ptr[i]; }
inline void length(uint32 len) { str_length=len ; }
+ inline void extra_allocation(uint32 len) { extra_alloc= len; }
inline bool is_empty() const { return (str_length == 0); }
inline void mark_as_const() { Alloced_length= 0;}
inline const char *ptr() const { return Ptr; }
@@ -144,11 +153,9 @@ public:
{
DBUG_ASSERT(&str != this);
free();
- Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0;
+ Ptr=(char*) str.ptr()+offset; str_length=arg_length;
if (str.Alloced_length)
Alloced_length=str.Alloced_length-offset;
- else
- Alloced_length=0;
str_charset=str.str_charset;
}
@@ -164,13 +171,13 @@ public:
inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs)
{
free();
- Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0;
+ Ptr=(char*) str; str_length=Alloced_length=arg_length;
str_charset=cs;
}
inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs)
{
free();
- Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
+ Ptr=(char*) str; str_length=arg_length;
str_charset=cs;
}
bool set_ascii(const char *str, uint32 arg_length);
@@ -189,6 +196,18 @@ public:
{ return set_int((longlong)num, true, cs); }
bool set_real(double num,uint decimals, CHARSET_INFO *cs);
+ /* Move handling of buffer from some other object to String */
+ void reassociate(char *ptr, uint32 length, uint32 alloced_length,
+ CHARSET_INFO *cs)
+ {
+ free();
+ Ptr= ptr;
+ str_length= length;
+ Alloced_length= alloced_length;
+ str_charset= cs;
+ alloced= ptr != 0;
+ }
+
/*
PMG 2004.11.12
This is a method that works the same as perl's "chop". It simply
@@ -221,11 +240,11 @@ public:
if (alloced)
{
alloced=0;
- Alloced_length=0;
my_free(Ptr);
- Ptr=0;
- str_length=0; /* Safety */
}
+ Alloced_length= extra_alloc= 0;
+ Ptr=0;
+ str_length=0; /* Safety */
}
inline bool alloc(uint32 arg_length)
{
@@ -234,14 +253,38 @@ public:
return real_alloc(arg_length);
}
bool real_alloc(uint32 arg_length); // Empties old string
- bool realloc(uint32 arg_length);
-
+ bool realloc_raw(uint32 arg_length);
+ bool realloc(uint32 arg_length)
+ {
+ if (realloc_raw(arg_length))
+ return TRUE;
+ Ptr[arg_length]=0; // This make other funcs shorter
+ return FALSE;
+ }
+ bool realloc_with_extra(uint32 arg_length)
+ {
+ if (extra_alloc < 4096)
+ extra_alloc= extra_alloc*2+128;
+ if (realloc_raw(arg_length + extra_alloc))
+ return TRUE;
+ Ptr[arg_length]=0; // This make other funcs shorter
+ return FALSE;
+ }
+ bool realloc_with_extra_if_needed(uint32 arg_length)
+ {
+ if (arg_length < Alloced_length)
+ {
+ Ptr[arg_length]=0; // behave as if realloc was called.
+ return 0;
+ }
+ return realloc_with_extra(arg_length);
+ }
// Shrink the buffer, but only if it is allocated on the heap.
inline void shrink(uint32 arg_length)
{
if (!is_alloced())
return;
- if (arg_length < Alloced_length)
+ if (ALIGN_SIZE(arg_length+1) < Alloced_length)
{
char *new_ptr;
if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0))))
@@ -269,7 +312,6 @@ public:
free();
Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
str_charset=s.str_charset;
- alloced=0;
}
return *this;
}
@@ -285,6 +327,14 @@ public:
bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom,
CHARSET_INFO *csto, uint *errors);
+ void move(String &s)
+ {
+ free();
+ Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
+ extra_alloc= s.extra_alloc;
+ alloced= s.alloced;
+ s.alloced= 0;
+ }
bool append(const String &s);
bool append(const char *s);
bool append(LEX_STRING *ls)
@@ -309,19 +359,30 @@ public:
}
else
{
- if (realloc(str_length+1))
+ if (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 *end= src + srclen ; src != end ; src++)
+ {
+ if (append(_dig_vec_lower[((uchar) *src) >> 4]) ||
+ append(_dig_vec_lower[((uchar) *src) & 0x0F]))
+ return true;
+ }
+ return false;
+ }
bool fill(uint32 max_length,char fill);
void strip_sp();
friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
friend int stringcmp(const String *a,const String *b);
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
+ friend class Field;
uint32 numchars();
- int charpos(int i,uint32 offset=0);
+ int charpos(longlong i,uint32 offset=0);
int reserve(uint32 space_needed)
{
@@ -364,6 +425,10 @@ public:
int4store(Ptr + position,value);
}
+ void qs_append(const char *str)
+ {
+ qs_append(str, (uint32)strlen(str));
+ }
void qs_append(const char *str, uint32 len);
void qs_append(double d);
void qs_append(double *d);
@@ -373,7 +438,15 @@ public:
str_length++;
}
void qs_append(int i);
- void qs_append(uint i);
+ void qs_append(uint i)
+ {
+ qs_append((ulonglong)i);
+ }
+ void qs_append(ulong i)
+ {
+ qs_append((ulonglong)i);
+ }
+ void qs_append(ulonglong i);
/* Inline (general) functions used by the protocol functions */
@@ -400,6 +473,7 @@ public:
return FALSE;
}
void print(String *print);
+ void append_for_single_quote(const char *st, uint len);
/* Swap two string objects. Efficient way to exchange data without memcpy. */
void swap(String &s);
@@ -423,8 +497,9 @@ public:
}
};
-static inline bool check_if_only_end_space(CHARSET_INFO *cs, char *str,
- char *end)
+static inline bool check_if_only_end_space(CHARSET_INFO *cs,
+ const char *str,
+ const char *end)
{
return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
}