diff options
Diffstat (limited to 'sql/sql_string.h')
-rw-r--r-- | sql/sql_string.h | 127 |
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; } |