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 const char *ptr() const { return Ptr; } 00088 inline char *c_ptr() 00089 { 00090 if (!Ptr || Ptr[str_length]) /* Should be safe */ 00091 (void) realloc(str_length); 00092 return Ptr; 00093 } 00094 inline char *c_ptr_quick() 00095 { 00096 if (Ptr && str_length < Alloced_length) 00097 Ptr[str_length]=0; 00098 return Ptr; 00099 } 00100 inline char *c_ptr_safe() 00101 { 00102 if (Ptr && str_length < Alloced_length) 00103 Ptr[str_length]=0; 00104 else 00105 (void) realloc(str_length); 00106 return Ptr; 00107 } 00108 00109 void set(String &str,uint32 offset,uint32 arg_length) 00110 { 00111 DBUG_ASSERT(&str != this); 00112 free(); 00113 Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0; 00114 if (str.Alloced_length) 00115 Alloced_length=str.Alloced_length-offset; 00116 else 00117 Alloced_length=0; 00118 str_charset=str.str_charset; 00119 } 00120 inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs) 00121 { 00122 free(); 00123 Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0; 00124 str_charset=cs; 00125 } 00126 inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs) 00127 { 00128 free(); 00129 Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0; 00130 str_charset=cs; 00131 } 00132 bool set_ascii(const char *str, uint32 arg_length); 00133 inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs) 00134 { 00135 if (!alloced) 00136 { 00137 Ptr=(char*) str; str_length=Alloced_length=arg_length; 00138 } 00139 str_charset=cs; 00140 } 00141 bool set(longlong num, CHARSET_INFO *cs); 00142 bool set(ulonglong num, CHARSET_INFO *cs); 00143 bool set(double num,uint decimals, CHARSET_INFO *cs); 00144 00145 /* 00146 PMG 2004.11.12 00147 This is a method that works the same as perl's "chop". It simply 00148 drops the last character of a string. This is useful in the case 00149 of the federated storage handler where I'm building a unknown 00150 number, list of values and fields to be used in a sql insert 00151 statement to be run on the remote server, and have a comma after each. 00152 When the list is complete, I "chop" off the trailing comma 00153 00154 ex. 00155 String stringobj; 00156 stringobj.append("VALUES ('foo', 'fi', 'fo',"); 00157 stringobj.chop(); 00158 stringobj.append(")"); 00159 00160 In this case, the value of string was: 00161 00162 VALUES ('foo', 'fi', 'fo', 00163 VALUES ('foo', 'fi', 'fo' 00164 VALUES ('foo', 'fi', 'fo') 00165 00166 */ 00167 inline void chop() 00168 { 00169 Ptr[str_length--]= '\0'; 00170 } 00171 00172 inline void free() 00173 { 00174 if (alloced) 00175 { 00176 alloced=0; 00177 Alloced_length=0; 00178 my_free(Ptr,MYF(0)); 00179 Ptr=0; 00180 str_length=0; /* Safety */ 00181 } 00182 } 00183 inline bool alloc(uint32 arg_length) 00184 { 00185 if (arg_length < Alloced_length) 00186 return 0; 00187 return real_alloc(arg_length); 00188 } 00189 bool real_alloc(uint32 arg_length); // Empties old string 00190 bool realloc(uint32 arg_length); 00191 inline void shrink(uint32 arg_length) // Shrink buffer 00192 { 00193 if (arg_length < Alloced_length) 00194 { 00195 char *new_ptr; 00196 if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0)))) 00197 { 00198 Alloced_length = 0; 00199 real_alloc(arg_length); 00200 } 00201 else 00202 { 00203 Ptr=new_ptr; 00204 Alloced_length=arg_length; 00205 } 00206 } 00207 } 00208 bool is_alloced() { return alloced; } 00209 inline String& operator = (const String &s) 00210 { 00211 if (&s != this) 00212 { 00213 /* 00214 It is forbidden to do assignments like 00215 some_string = substring_of_that_string 00216 */ 00217 DBUG_ASSERT(!s.uses_buffer_owned_by(this)); 00218 free(); 00219 Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length; 00220 alloced=0; 00221 } 00222 return *this; 00223 } 00224 00225 bool copy(); // Alloc string if not alloced 00226 bool copy(const String &s); // Allocate new string 00227 bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string 00228 static bool needs_conversion(uint32 arg_length, 00229 CHARSET_INFO *cs_from, CHARSET_INFO *cs_to, 00230 uint32 *offset); 00231 bool copy_aligned(const char *s, uint32 arg_length, uint32 offset, 00232 CHARSET_INFO *cs); 00233 bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs); 00234 bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom, 00235 CHARSET_INFO *csto, uint *errors); 00236 bool append(const String &s); 00237 bool append(const char *s); 00238 bool append(const char *s,uint32 arg_length); 00239 bool append(const char *s,uint32 arg_length, CHARSET_INFO *cs); 00240 bool append(IO_CACHE* file, uint32 arg_length); 00241 bool append_with_prefill(const char *s, uint32 arg_length, 00242 uint32 full_length, char fill_char); 00243 int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 00244 int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 00245 bool replace(uint32 offset,uint32 arg_length,const char *to,uint32 length); 00246 bool replace(uint32 offset,uint32 arg_length,const String &to); 00247 inline bool append(char chr) 00248 { 00249 if (str_length < Alloced_length) 00250 { 00251 Ptr[str_length++]=chr; 00252 } 00253 else 00254 { 00255 if (realloc(str_length+1)) 00256 return 1; 00257 Ptr[str_length++]=chr; 00258 } 00259 return 0; 00260 } 00261 bool fill(uint32 max_length,char fill); 00262 void strip_sp(); 00263 friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); 00264 friend int stringcmp(const String *a,const String *b); 00265 friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); 00266 uint32 numchars(); 00267 int charpos(int i,uint32 offset=0); 00268 00269 int reserve(uint32 space_needed) 00270 { 00271 return realloc(str_length + space_needed); 00272 } 00273 int reserve(uint32 space_needed, uint32 grow_by); 00274 00275 /* 00276 The following append operations do NOT check alloced memory 00277 q_*** methods writes values of parameters itself 00278 qs_*** methods writes string representation of value 00279 */ 00280 void q_append(const char c) 00281 { 00282 Ptr[str_length++] = c; 00283 } 00284 void q_append(const uint32 n) 00285 { 00286 int4store(Ptr + str_length, n); 00287 str_length += 4; 00288 } 00289 void q_append(double d) 00290 { 00291 float8store(Ptr + str_length, d); 00292 str_length += 8; 00293 } 00294 void q_append(double *d) 00295 { 00296 float8store(Ptr + str_length, *d); 00297 str_length += 8; 00298 } 00299 void q_append(const char *data, uint32 data_len) 00300 { 00301 memcpy(Ptr + str_length, data, data_len); 00302 str_length += data_len; 00303 } 00304 00305 void write_at_position(int position, uint32 value) 00306 { 00307 int4store(Ptr + position,value); 00308 } 00309 00310 void qs_append(const char *str, uint32 len); 00311 void qs_append(double d); 00312 void qs_append(double *d); 00313 inline void qs_append(const char c) 00314 { 00315 Ptr[str_length]= c; 00316 str_length++; 00317 } 00318 void qs_append(int i); 00319 void qs_append(uint i); 00320 00321 /* Inline (general) functions used by the protocol functions */ 00322 00323 inline char *prep_append(uint32 arg_length, uint32 step_alloc) 00324 { 00325 uint32 new_length= arg_length + str_length; 00326 if (new_length > Alloced_length) 00327 { 00328 if (realloc(new_length + step_alloc)) 00329 return 0; 00330 } 00331 uint32 old_length= str_length; 00332 str_length+= arg_length; 00333 return Ptr+ old_length; /* Area to use */ 00334 } 00335 00336 inline bool append(const char *s, uint32 arg_length, uint32 step_alloc) 00337 { 00338 uint32 new_length= arg_length + str_length; 00339 if (new_length > Alloced_length && realloc(new_length + step_alloc)) 00340 return TRUE; 00341 memcpy(Ptr+str_length, s, arg_length); 00342 str_length+= arg_length; 00343 return FALSE; 00344 } 00345 void print(String *print); 00346 00347 /* Swap two string objects. Efficient way to exchange data without memcpy. */ 00348 void swap(String &s); 00349 00350 inline bool uses_buffer_owned_by(const String *s) const 00351 { 00352 return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length); 00353 } 00354 };
1.4.7

