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
00026 #include <cassert>
00027 #include <cstdlib>
00028 #include <cstring>
00029 #include <string>
00030
00031 #include <drizzled/visibility.h>
00032
00033 #ifndef NOT_FIXED_DEC
00034 #define NOT_FIXED_DEC (uint8_t)31
00035 #endif
00036
00037 namespace drizzled
00038 {
00039
00040 class String;
00041
00042 extern DRIZZLED_API String my_empty_string;
00043 extern const String my_null_string;
00044 namespace memory { class Root; }
00045 typedef struct charset_info_st CHARSET_INFO;
00046
00047 DRIZZLED_API std::string String_to_std_string(String const& s);
00048 DRIZZLED_API String* set_String_from_std_string(String* s, std::string const& cs);
00049
00050 int sortcmp(const String *a,const String *b, const CHARSET_INFO * const cs);
00051 int stringcmp(const String *a,const String *b);
00052 String *copy_if_not_alloced(String *a,String *b,size_t arg_length);
00053 size_t well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
00054 char *to, size_t to_length,
00055 const CHARSET_INFO * const from_cs,
00056 const char *from, size_t from_length,
00057 size_t nchars,
00058 const char **well_formed_error_pos,
00059 const char **cannot_convert_error_pos,
00060 const char **from_end_pos);
00061
00062
00063 class DRIZZLED_API String
00064 {
00065 char *Ptr;
00066 size_t str_length,Alloced_length;
00067 bool alloced;
00068 const CHARSET_INFO *str_charset;
00069
00070 public:
00071 String();
00072 String(size_t length_arg);
00073 String(const char *str, const CHARSET_INFO * const cs);
00074 String(const char *str, size_t len, const CHARSET_INFO * const cs);
00075 String(char *str, size_t len, const CHARSET_INFO * const cs);
00076 String(const String &str);
00077
00078 static void *operator new(size_t size, memory::Root *mem_root);
00079 static void operator delete(void *, size_t)
00080 { }
00081 static void operator delete(void *, memory::Root *)
00082 { }
00083 ~String();
00084
00085 inline void set_charset(const CHARSET_INFO * const charset_arg)
00086 { str_charset= charset_arg; }
00087 inline const CHARSET_INFO *charset() const { return str_charset; }
00088 inline size_t length() const { return str_length;}
00089 inline size_t alloced_length() const { return Alloced_length;}
00090 inline char& operator [] (size_t i) const { return Ptr[i]; }
00091 inline void length(size_t len) { str_length=len ; }
00092 inline bool is_empty() { return (str_length == 0); }
00093 inline void mark_as_const() { Alloced_length= 0;}
00094 inline char *ptr() { return Ptr; }
00095 inline const char *ptr() const { return Ptr; }
00096 inline char *c_ptr()
00097 {
00098 if (str_length == Alloced_length)
00099 (void) realloc(str_length);
00100 else
00101 Ptr[str_length]= 0;
00102
00103 return Ptr;
00104 }
00105 inline char *c_ptr_quick()
00106 {
00107 if (Ptr && str_length < Alloced_length)
00108 Ptr[str_length]=0;
00109 return Ptr;
00110 }
00111 inline char *c_ptr_safe()
00112 {
00113 if (Ptr && str_length < Alloced_length)
00114 Ptr[str_length]=0;
00115 else
00116 (void) realloc(str_length);
00117 return Ptr;
00118 }
00119 inline char *c_str()
00120 {
00121 if (Ptr && str_length < Alloced_length)
00122 Ptr[str_length]=0;
00123 else
00124 (void) realloc(str_length);
00125 return Ptr;
00126 }
00127 void append_identifier(const char *name, size_t length);
00128
00129 void set(String &str,size_t offset,size_t arg_length)
00130 {
00131 assert(&str != this);
00132 free();
00133 Ptr= str.ptr()+offset; str_length=arg_length; alloced=0;
00134 if (str.Alloced_length)
00135 Alloced_length=str.Alloced_length-offset;
00136 else
00137 Alloced_length=0;
00138 str_charset=str.str_charset;
00139 }
00140 inline void set(char *str,size_t arg_length, const CHARSET_INFO * const cs)
00141 {
00142 free();
00143 Ptr= str; str_length=Alloced_length=arg_length ; alloced=0;
00144 str_charset=cs;
00145 }
00146 inline void set(const char *str,size_t arg_length, const CHARSET_INFO * const cs)
00147 {
00148 free();
00149 Ptr= const_cast<char*>(str);
00150 str_length=arg_length; Alloced_length=0 ; alloced=0;
00151 str_charset=cs;
00152 }
00153 bool set_ascii(const char *str, size_t arg_length);
00154 inline void set_quick(char *str,size_t arg_length, const CHARSET_INFO * const cs)
00155 {
00156 if (!alloced)
00157 {
00158 Ptr= str; str_length= Alloced_length= arg_length;
00159 }
00160 str_charset= cs;
00161 }
00162 bool set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs);
00163 bool set(int64_t num, const CHARSET_INFO * const cs)
00164 { return set_int(num, false, cs); }
00165 bool set(uint64_t num, const CHARSET_INFO * const cs)
00166 { return set_int(static_cast<int64_t>(num), true, cs); }
00167 bool set_real(double num,size_t decimals, const CHARSET_INFO * const cs);
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 inline void chop()
00192 {
00193 Ptr[str_length--]= '\0';
00194 }
00195
00196 inline void free()
00197 {
00198 if (alloced)
00199 {
00200 alloced=0;
00201 Alloced_length=0;
00202 ::free(Ptr);
00203 Ptr=0;
00204 str_length=0;
00205 }
00206 }
00207 inline bool alloc(size_t arg_length)
00208 {
00209 if (arg_length < Alloced_length)
00210 return 0;
00211 return real_alloc(arg_length);
00212 }
00213 bool real_alloc(size_t arg_length);
00214 bool 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; }
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 bool copy();
00250 bool copy(const String &s);
00251 bool copy(const std::string&, const CHARSET_INFO * const cs);
00252 bool copy(const char *s,size_t arg_length, const CHARSET_INFO * const cs);
00253 static bool needs_conversion(size_t arg_length,
00254 const CHARSET_INFO * const cs_from, const CHARSET_INFO * const cs_to,
00255 size_t *offset);
00256 bool set_or_copy_aligned(const char *s, size_t arg_length, const CHARSET_INFO * const cs);
00257 bool copy(const char*s,size_t arg_length, const CHARSET_INFO * const csfrom,
00258 const CHARSET_INFO * const csto, size_t *errors);
00259 bool append(const String &s);
00260 bool append(const char *s);
00261 bool append(const char *s,size_t arg_length);
00262 bool append(const char *s,size_t arg_length, const CHARSET_INFO * const cs);
00263 bool append_with_prefill(const char *s, size_t arg_length,
00264 size_t full_length, char fill_char);
00265 int strstr(const String &search,size_t offset=0);
00266 int strrstr(const String &search,size_t offset=0);
00267 bool replace(size_t offset,size_t arg_length,const char *to,size_t length);
00268 bool replace(size_t offset,size_t arg_length,const String &to);
00269 inline bool append(char chr)
00270 {
00271 if (str_length < Alloced_length)
00272 {
00273 Ptr[str_length++]=chr;
00274 }
00275 else
00276 {
00277 if (realloc(str_length+1))
00278 return 1;
00279 Ptr[str_length++]=chr;
00280 }
00281 return 0;
00282 }
00283 friend int sortcmp(const String *a,const String *b, const CHARSET_INFO * const cs);
00284 friend int stringcmp(const String *a,const String *b);
00285 friend String *copy_if_not_alloced(String *a,String *b,size_t arg_length);
00286 size_t numchars();
00287 int charpos(int i,size_t offset=0);
00288
00289 int reserve(size_t space_needed)
00290 {
00291 return realloc(str_length + space_needed);
00292 }
00293 int reserve(size_t space_needed, size_t grow_by);
00294
00295
00296
00297
00298
00299
00300 void q_append(const char c);
00301 void q_append(const size_t n);
00302 void q_append(double d);
00303 void q_append(double *d);
00304 void q_append(const char *data, size_t data_len);
00305 void write_at_position(int position, size_t value);
00306
00307
00308
00309 inline char *prep_append(size_t arg_length, size_t step_alloc)
00310 {
00311 size_t new_length= arg_length + str_length;
00312 if (new_length > Alloced_length)
00313 {
00314 if (realloc(new_length + step_alloc))
00315 return 0;
00316 }
00317 size_t old_length= str_length;
00318 str_length+= arg_length;
00319 return Ptr+ old_length;
00320 }
00321
00322 inline bool append(const char *s, size_t arg_length, size_t step_alloc)
00323 {
00324 size_t new_length= arg_length + str_length;
00325 if (new_length > Alloced_length && realloc(new_length + step_alloc))
00326 return true;
00327 memcpy(Ptr+str_length, s, arg_length);
00328 str_length+= arg_length;
00329 return false;
00330 }
00331 void print(String *print);
00332
00333
00334 void swap(String &s);
00335
00336 inline bool uses_buffer_owned_by(const String *s) const
00337 {
00338 return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
00339 }
00340 };
00341
00342 bool check_if_only_end_space(const CHARSET_INFO * const cs, char *str,
00343 char *end);
00344
00345 std::ostream& operator<<(std::ostream& output, const String &str);
00346
00347 }
00348
00349 bool operator==(const drizzled::String &s1, const drizzled::String &s2);
00350 bool operator!=(const drizzled::String &s1, const drizzled::String &s2);
00351
00352