00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #pragma once
00021
00022
00023
00024 #include <drizzled/common.h>
00025 #include <drizzled/util/data_ref.h>
00026
00027 #include <cassert>
00028 #include <cstdlib>
00029 #include <cstring>
00030 #include <string>
00031
00032 #include <drizzled/visibility.h>
00033 #include <drizzled/common_fwd.h>
00034
00035 #ifndef NOT_FIXED_DEC
00036 #define NOT_FIXED_DEC (uint8_t)31
00037 #endif
00038
00039 namespace drizzled {
00040
00041 extern DRIZZLED_API String my_empty_string;
00042 extern const String my_null_string;
00043
00044 int sortcmp(const String *a,const String *b, const charset_info_st * const cs);
00045 int stringcmp(const String *a,const String *b);
00046 String *copy_if_not_alloced(String *a,String *b,size_t arg_length);
00047 size_t well_formed_copy_nchars(const charset_info_st * const to_cs,
00048 char *to, size_t to_length,
00049 const charset_info_st * const from_cs,
00050 const char *from, size_t from_length,
00051 size_t nchars,
00052 const char **well_formed_error_pos,
00053 const char **cannot_convert_error_pos,
00054 const char **from_end_pos);
00055
00056
00057 class DRIZZLED_API String
00058 {
00059 char *Ptr;
00060 size_t str_length,Alloced_length;
00061 bool alloced;
00062 const charset_info_st *str_charset;
00063
00064 public:
00065 String();
00066 String(size_t length_arg);
00067 String(const char*, const charset_info_st*);
00068 String(const char*, size_t, const charset_info_st*);
00069 String(char *str, size_t len, const charset_info_st*);
00070 String(str_ref, const charset_info_st*);
00071 String(const String&);
00072
00073 static void *operator new(size_t size, memory::Root *mem_root);
00074 static void operator delete(void *, size_t)
00075 { }
00076 static void operator delete(void *, memory::Root *)
00077 { }
00078 ~String();
00079
00080 inline void set_charset(const charset_info_st * const charset_arg)
00081 { str_charset= charset_arg; }
00082 inline const charset_info_st *charset() const { return str_charset; }
00083 inline size_t length() const { return str_length;}
00084 inline size_t alloced_length() const { return Alloced_length;}
00085 inline char& operator [] (size_t i) const { return Ptr[i]; }
00086 inline void length(size_t len) { str_length=len; }
00087 inline bool empty() const { return str_length == 0; }
00088 inline void mark_as_const() { Alloced_length= 0; }
00089 inline char *ptr() { return Ptr; }
00090 inline const char *ptr() const { return Ptr; }
00091 inline char *c_ptr()
00092 {
00093 if (str_length == Alloced_length)
00094 realloc(str_length);
00095 else
00096 Ptr[str_length]= 0;
00097
00098 return Ptr;
00099 }
00100 inline const char* begin() const
00101 {
00102 return Ptr;
00103 }
00104 inline const char* end() const
00105 {
00106 return begin() + size();
00107 }
00108 inline const char* data() const
00109 {
00110 return Ptr;
00111 }
00112 inline size_t size() const
00113 {
00114 return length();
00115 }
00116 inline const char* c_str()
00117 {
00118 if (Ptr && str_length < Alloced_length)
00119 Ptr[str_length]=0;
00120 else
00121 realloc(str_length);
00122 return Ptr;
00123 }
00124 void append_identifier(const char *name, size_t length);
00125 void append_identifier(str_ref);
00126
00127 void set(String &str,size_t offset,size_t arg_length)
00128 {
00129 assert(&str != this);
00130 free();
00131 Ptr= str.ptr()+offset; str_length=arg_length; alloced=0;
00132 if (str.Alloced_length)
00133 Alloced_length=str.Alloced_length-offset;
00134 else
00135 Alloced_length=0;
00136 str_charset=str.str_charset;
00137 }
00138 inline void set(char *str,size_t arg_length, const charset_info_st * const cs)
00139 {
00140 free();
00141 Ptr= str; str_length=Alloced_length=arg_length ; alloced=0;
00142 str_charset=cs;
00143 }
00144
00145 inline void set(const char *str,size_t arg_length, const charset_info_st * const cs)
00146 {
00147 free();
00148 Ptr= const_cast<char*>(str);
00149 str_length=arg_length; Alloced_length=0 ; alloced=0;
00150 str_charset=cs;
00151 }
00152 void set_ascii(const char *str, size_t arg_length);
00153
00154 inline void set_quick(char *str,size_t arg_length, const charset_info_st * const cs)
00155 {
00156 if (!alloced)
00157 {
00158 Ptr= str; str_length= Alloced_length= arg_length;
00159 }
00160 str_charset= cs;
00161 }
00162
00163 void set_int(int64_t num, bool unsigned_flag, const charset_info_st * const cs);
00164 void set(int64_t num, const charset_info_st * const cs)
00165 { set_int(num, false, cs); }
00166 void set(uint64_t num, const charset_info_st * const cs)
00167 { set_int(static_cast<int64_t>(num), true, cs); }
00168 void set_real(double num,size_t decimals, const charset_info_st* cs);
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 inline void chop()
00193 {
00194 Ptr[str_length--]= '\0';
00195 }
00196
00197 inline void free()
00198 {
00199 if (alloced)
00200 {
00201 alloced=0;
00202 Alloced_length=0;
00203 ::free(Ptr);
00204 Ptr=0;
00205 str_length=0;
00206 }
00207 }
00208 inline void alloc(size_t arg_length)
00209 {
00210 if (arg_length >= Alloced_length)
00211 real_alloc(arg_length);
00212 }
00213 void real_alloc(size_t arg_length);
00214 void realloc(size_t arg_length);
00215 inline void shrink(size_t arg_length)
00216 {
00217 if (arg_length < Alloced_length)
00218 {
00219 char *new_ptr;
00220 if (!(new_ptr= reinterpret_cast<char*>(::realloc(Ptr,arg_length))))
00221 {
00222 Alloced_length = 0;
00223 real_alloc(arg_length);
00224 }
00225 else
00226 {
00227 Ptr=new_ptr;
00228 Alloced_length=arg_length;
00229 }
00230 }
00231 }
00232 bool is_alloced() { return alloced; } const
00233 inline String& operator = (const String &s)
00234 {
00235 if (&s != this)
00236 {
00237
00238
00239
00240
00241 assert(!s.uses_buffer_owned_by(this));
00242 free();
00243 Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
00244 alloced=0;
00245 }
00246 return *this;
00247 }
00248
00249 void copy();
00250 void copy(const String&);
00251 void copy(const std::string&, const charset_info_st*);
00252 void copy(const char*, size_t, const charset_info_st*);
00253 static bool needs_conversion(size_t arg_length, const charset_info_st* cs_from, const charset_info_st* cs_to);
00254 void set_or_copy_aligned(const char *s, size_t arg_length, const charset_info_st*);
00255 void copy(const char*s,size_t arg_length, const charset_info_st& csto);
00256 void append(const char*);
00257 void append(const char*, size_t);
00258 void append(str_ref);
00259 void append_with_prefill(const char *s, size_t arg_length, size_t full_length, char fill_char);
00260 int strstr(const String &search,size_t offset=0);
00261 int strrstr(const String &search,size_t offset=0);
00262 void replace(size_t offset,size_t arg_length,const char *to,size_t length);
00263 void replace(size_t offset,size_t arg_length,const String &to);
00264
00265 inline void append(char chr)
00266 {
00267 if (str_length < Alloced_length)
00268 {
00269 Ptr[str_length++]=chr;
00270 }
00271 else
00272 {
00273 realloc(str_length+1);
00274 Ptr[str_length++]=chr;
00275 }
00276 }
00277 friend int sortcmp(const String *a,const String *b, const charset_info_st * const cs);
00278 friend int stringcmp(const String *a,const String *b);
00279 friend String *copy_if_not_alloced(String *a,String *b,size_t arg_length);
00280 size_t numchars() const;
00281 int charpos(int i, size_t offset= 0) const;
00282
00283 void reserve(size_t space_needed)
00284 {
00285 realloc(str_length + space_needed);
00286 }
00287 void reserve(size_t space_needed, size_t grow_by);
00288
00289 inline void append(const char *s, size_t arg_length, size_t step_alloc)
00290 {
00291 size_t new_length= arg_length + str_length;
00292 if (new_length > Alloced_length)
00293 realloc(new_length + step_alloc);
00294 memcpy(Ptr+str_length, s, arg_length);
00295 str_length+= arg_length;
00296 }
00297
00298 void print(String&) const;
00299
00300
00301 void swap(String &s);
00302
00303 inline bool uses_buffer_owned_by(const String *s) const
00304 {
00305 return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
00306 }
00307 };
00308
00309 bool check_if_only_end_space(const charset_info_st* const, char *str, char *end);
00310
00311 std::ostream& operator<<(std::ostream&, const String&);
00312
00313 }
00314
00315 bool operator==(const drizzled::String &s1, const drizzled::String &s2);
00316 bool operator!=(const drizzled::String &s1, const drizzled::String &s2);