00001 /* Copyright (C) 2000 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 /* This file is originally from the mysql distribution. Coded by monty */ 00018 00019 #ifdef USE_PRAGMA_INTERFACE 00020 #pragma interface /* gcc class implementation */ 00021 #endif 00022 00023 #ifndef NOT_FIXED_DEC 00024 #define NOT_FIXED_DEC 31 00025 #endif 00026 00027 class String; 00028 int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); 00029 String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); 00030 uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs, 00031 const char *from, uint32 from_length, 00032 CHARSET_INFO *from_cs, uint *errors); 00033 00034 class String 00035 { 00036 char *Ptr; 00037 uint32 str_length,Alloced_length; 00038 bool alloced; 00039 CHARSET_INFO *str_charset; 00040 public: 00041 String() 00042 { 00043 Ptr=0; str_length=Alloced_length=0; alloced=0; 00044 str_charset= &my_charset_bin; 00045 } 00046 String(uint32 length_arg) 00047 { 00048 alloced=0; Alloced_length=0; (void) real_alloc(length_arg); 00049 str_charset= &my_charset_bin; 00050 } 00051 String(const char *str, CHARSET_INFO *cs) 00052 { 00053 Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0; 00054 str_charset=cs; 00055 } 00056 String(const char *str,uint32 len, CHARSET_INFO *cs) 00057 { 00058 Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0; 00059 str_charset=cs; 00060 } 00061 String(char *str,uint32 len, CHARSET_INFO *cs) 00062 { 00063 Ptr=(char*) str; Alloced_length=str_length=len; alloced=0; 00064 str_charset=cs; 00065 } 00066 String(const String &str) 00067 { 00068 Ptr=str.Ptr ; str_length=str.str_length ; 00069 Alloced_length=str.Alloced_length; alloced=0; 00070 str_charset=str.str_charset; 00071 } 00072 static void *operator new(size_t size, MEM_ROOT *mem_root) 00073 { return (void*) alloc_root(mem_root, (uint) size); } 00074 static void operator delete(void *ptr_arg,size_t size) 00075 { TRASH(ptr_arg, size); } 00076 static void operator delete(void *ptr_arg, MEM_ROOT *mem_root) 00077 { /* never called */ } 00078 ~String() { free(); } 00079 00080 inline void set_charset(CHARSET_INFO *charset) { str_charset= charset; } 00081 inline CHARSET_INFO *charset() const { return str_charset; } 00082 inline uint32 length() const { return str_length;} 00083 inline uint32 alloced_length() const { return Alloced_length;} 00084 inline char& operator [] (uint32 i) const { return Ptr[i]; } 00085 inline void length(uint32 len) { str_length=len ; } 00086 inline bool is_empty() { return (str_length == 0); } 00087 inline void mark_as_const() { Alloced_length= 0;} 00088 inline const char *ptr() const { return Ptr; } 00089 inline char *c_ptr() 00090 { 00091 if (!Ptr || Ptr[str_length]) /* Should be safe */ 00092 (void) realloc(str_length); 00093 return Ptr; 00094 } 00095 inline char *c_ptr_quick() 00096 { 00097 if (Ptr && str_length < Alloced_length) 00098 Ptr[str_length]=0; 00099 return Ptr; 00100 } 00101 inline char *c_ptr_safe() 00102 { 00103 if (Ptr && str_length < Alloced_length) 00104 Ptr[str_length]=0; 00105 else 00106 (void) realloc(str_length); 00107 return Ptr; 00108 } 00109 00110 void set(String &str,uint32 offset,uint32 arg_length) 00111 { 00112 DBUG_ASSERT(&str != this); 00113 free(); 00114 Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0; 00115 if (str.Alloced_length) 00116 Alloced_length=str.Alloced_length-offset; 00117 else 00118 Alloced_length=0; 00119 str_charset=str.str_charset; 00120 } 00121 inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs) 00122 { 00123 free(); 00124 Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0; 00125 str_charset=cs; 00126 } 00127 inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs) 00128 { 00129 free(); 00130 Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0; 00131 str_charset=cs; 00132 } 00133 bool set_ascii(const char *str, uint32 arg_length); 00134 inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs) 00135 { 00136 if (!alloced) 00137 { 00138 Ptr=(char*) str; str_length=Alloced_length=arg_length; 00139 } 00140 str_charset=cs; 00141 } 00142 bool set_int(longlong num, bool unsigned_flag, CHARSET_INFO *cs); 00143 bool set(longlong num, CHARSET_INFO *cs) 00144 { return set_int(num, false, cs); } 00145 bool set(ulonglong num, CHARSET_INFO *cs) 00146 { return set_int((longlong)num, true, cs); } 00147 bool set_real(double num,uint decimals, CHARSET_INFO *cs); 00148 00149 /* 00150 PMG 2004.11.12 00151 This is a method that works the same as perl's "chop". It simply 00152 drops the last character of a string. This is useful in the case 00153 of the federated storage handler where I'm building a unknown 00154 number, list of values and fields to be used in a sql insert 00155 statement to be run on the remote server, and have a comma after each. 00156 When the list is complete, I "chop" off the trailing comma 00157 00158 ex. 00159 String stringobj; 00160 stringobj.append("VALUES ('foo', 'fi', 'fo',"); 00161 stringobj.chop(); 00162 stringobj.append(")"); 00163 00164 In this case, the value of string was: 00165 00166 VALUES ('foo', 'fi', 'fo', 00167 VALUES ('foo', 'fi', 'fo' 00168 VALUES ('foo', 'fi', 'fo') 00169 00170 */ 00171 inline void chop() 00172 { 00173 Ptr[str_length--]= '\0'; 00174 } 00175 00176 inline void free() 00177 { 00178 if (alloced) 00179 { 00180 alloced=0; 00181 Alloced_length=0; 00182 my_free(Ptr,MYF(0)); 00183 Ptr=0; 00184 str_length=0; /* Safety */ 00185 } 00186 } 00187 inline bool alloc(uint32 arg_length) 00188 { 00189 if (arg_length < Alloced_length) 00190 return 0; 00191 return real_alloc(arg_length); 00192 } 00193 bool real_alloc(uint32 arg_length); // Empties old string 00194 bool realloc(uint32 arg_length); 00195 inline void shrink(uint32 arg_length) // Shrink buffer 00196 { 00197 if (arg_length < Alloced_length) 00198 { 00199 char *new_ptr; 00200 if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0)))) 00201 { 00202 Alloced_length = 0; 00203 real_alloc(arg_length); 00204 } 00205 else 00206 { 00207 Ptr=new_ptr; 00208 Alloced_length=arg_length; 00209 } 00210 } 00211 } 00212 bool is_alloced() { return alloced; } 00213 inline String& operator = (const String &s) 00214 { 00215 if (&s != this) 00216 { 00217 /* 00218 It is forbidden to do assignments like 00219 some_string = substring_of_that_string 00220 */ 00221 DBUG_ASSERT(!s.uses_buffer_owned_by(this)); 00222 free(); 00223 Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length; 00224 alloced=0; 00225 } 00226 return *this; 00227 } 00228 00229 bool copy(); // Alloc string if not alloced 00230 bool copy(const String &s); // Allocate new string 00231 bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string 00232 static bool needs_conversion(uint32 arg_length, 00233 CHARSET_INFO *cs_from, CHARSET_INFO *cs_to, 00234 uint32 *offset); 00235 bool copy_aligned(const char *s, uint32 arg_length, uint32 offset, 00236 CHARSET_INFO *cs); 00237 bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs); 00238 bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom, 00239 CHARSET_INFO *csto, uint *errors); 00240 bool append(const String &s); 00241 bool append(const char *s); 00242 bool append(const char *s,uint32 arg_length); 00243 bool append(const char *s,uint32 arg_length, CHARSET_INFO *cs); 00244 bool append(IO_CACHE* file, uint32 arg_length); 00245 bool append_with_prefill(const char *s, uint32 arg_length, 00246 uint32 full_length, char fill_char); 00247 int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 00248 int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 00249 bool replace(uint32 offset,uint32 arg_length,const char *to,uint32 length); 00250 bool replace(uint32 offset,uint32 arg_length,const String &to); 00251 inline bool append(char chr) 00252 { 00253 if (str_length < Alloced_length) 00254 { 00255 Ptr[str_length++]=chr; 00256 } 00257 else 00258 { 00259 if (realloc(str_length+1)) 00260 return 1; 00261 Ptr[str_length++]=chr; 00262 } 00263 return 0; 00264 } 00265 bool fill(uint32 max_length,char fill); 00266 void strip_sp(); 00267 friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); 00268 friend int stringcmp(const String *a,const String *b); 00269 friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); 00270 uint32 numchars(); 00271 int charpos(int i,uint32 offset=0); 00272 00273 int reserve(uint32 space_needed) 00274 { 00275 return realloc(str_length + space_needed); 00276 } 00277 int reserve(uint32 space_needed, uint32 grow_by); 00278 00279 /* 00280 The following append operations do NOT check alloced memory 00281 q_*** methods writes values of parameters itself 00282 qs_*** methods writes string representation of value 00283 */ 00284 void q_append(const char c) 00285 { 00286 Ptr[str_length++] = c; 00287 } 00288 void q_append(const uint32 n) 00289 { 00290 int4store(Ptr + str_length, n); 00291 str_length += 4; 00292 } 00293 void q_append(double d) 00294 { 00295 float8store(Ptr + str_length, d); 00296 str_length += 8; 00297 } 00298 void q_append(double *d) 00299 { 00300 float8store(Ptr + str_length, *d); 00301 str_length += 8; 00302 } 00303 void q_append(const char *data, uint32 data_len) 00304 { 00305 memcpy(Ptr + str_length, data, data_len); 00306 str_length += data_len; 00307 } 00308 00309 void write_at_position(int position, uint32 value) 00310 { 00311 int4store(Ptr + position,value); 00312 } 00313 00314 void qs_append(const char *str, uint32 len); 00315 void qs_append(double d); 00316 void qs_append(double *d); 00317 inline void qs_append(const char c) 00318 { 00319 Ptr[str_length]= c; 00320 str_length++; 00321 } 00322 void qs_append(int i); 00323 void qs_append(uint i); 00324 00325 /* Inline (general) functions used by the protocol functions */ 00326 00327 inline char *prep_append(uint32 arg_length, uint32 step_alloc) 00328 { 00329 uint32 new_length= arg_length + str_length; 00330 if (new_length > Alloced_length) 00331 { 00332 if (realloc(new_length + step_alloc)) 00333 return 0; 00334 } 00335 uint32 old_length= str_length; 00336 str_length+= arg_length; 00337 return Ptr+ old_length; /* Area to use */ 00338 } 00339 00340 inline bool append(const char *s, uint32 arg_length, uint32 step_alloc) 00341 { 00342 uint32 new_length= arg_length + str_length; 00343 if (new_length > Alloced_length && realloc(new_length + step_alloc)) 00344 return TRUE; 00345 memcpy(Ptr+str_length, s, arg_length); 00346 str_length+= arg_length; 00347 return FALSE; 00348 } 00349 void print(String *print); 00350 00351 /* Swap two string objects. Efficient way to exchange data without memcpy. */ 00352 void swap(String &s); 00353 00354 inline bool uses_buffer_owned_by(const String *s) const 00355 { 00356 return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length); 00357 } 00358 };
1.4.7

