~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/* This file is originally from the mysql distribution. Coded by monty */
17
212.5.39 by Monty Taylor
Phew. Moved my_base and my_global.
18
#include "global.h"
212.5.13 by Monty Taylor
Moved my_sys/my_pthread/my_nosys and mysys_err to mysys.
19
#include <mysys/my_sys.h>
212.5.45 by Monty Taylor
Removed excess AM_CPPFLAGS from the tree. Now the only thing that should be in the include path should be -I${top_srcdir} and -I${top_builddir}w
20
#include <mystrings/m_string.h>
1 by brian
clean slate
21
398.1.5 by Monty Taylor
Removed C++ includes and std namespace from global.h.
22
#include <algorithm>
23
1 by brian
clean slate
24
/*
25
  The following extern declarations are ok as these are interface functions
26
  required by the string function
27
*/
28
481 by Brian Aker
Remove all of uchar.
29
extern unsigned char* sql_alloc(unsigned size);
1 by brian
clean slate
30
extern void sql_element_free(void *ptr);
31
32
#include "sql_string.h"
33
34
/*****************************************************************************
35
** String functions
36
*****************************************************************************/
37
205 by Brian Aker
uint32 -> uin32_t
38
bool String::real_alloc(uint32_t arg_length)
1 by brian
clean slate
39
{
40
  arg_length=ALIGN_SIZE(arg_length+1);
41
  str_length=0;
42
  if (Alloced_length < arg_length)
43
  {
44
    free();
641.3.6 by Monty Taylor
Removed some my_malloc calls.
45
    if (!(Ptr=(char*) malloc(arg_length)))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
46
      return true;
1 by brian
clean slate
47
    Alloced_length=arg_length;
48
    alloced=1;
49
  }
50
  Ptr[0]=0;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
51
  return false;
1 by brian
clean slate
52
}
53
54
55
/*
56
** Check that string is big enough. Set string[alloc_length] to 0
57
** (for C functions)
58
*/
59
205 by Brian Aker
uint32 -> uin32_t
60
bool String::realloc(uint32_t alloc_length)
1 by brian
clean slate
61
{
205 by Brian Aker
uint32 -> uin32_t
62
  uint32_t len=ALIGN_SIZE(alloc_length+1);
1 by brian
clean slate
63
  if (Alloced_length < len)
64
  {
65
    char *new_ptr;
66
    if (alloced)
67
    {
656.1.26 by Monty Taylor
Finally removed all of the my_malloc stuff.
68
      if ((new_ptr= (char*) ::realloc(Ptr,len)))
1 by brian
clean slate
69
      {
70
	Ptr=new_ptr;
71
	Alloced_length=len;
72
      }
73
      else
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
74
	return true;				// Signal error
1 by brian
clean slate
75
    }
641.3.6 by Monty Taylor
Removed some my_malloc calls.
76
    else if ((new_ptr= (char*) malloc(len)))
1 by brian
clean slate
77
    {
78
      if (str_length)				// Avoid bugs in memcpy on AIX
79
	memcpy(new_ptr,Ptr,str_length);
80
      new_ptr[str_length]=0;
81
      Ptr=new_ptr;
82
      Alloced_length=len;
83
      alloced=1;
84
    }
85
    else
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
86
      return true;			// Signal error
1 by brian
clean slate
87
  }
88
  Ptr[alloc_length]=0;			// This make other funcs shorter
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
89
  return false;
1 by brian
clean slate
90
}
91
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
92
bool String::set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs)
1 by brian
clean slate
93
{
482 by Brian Aker
Remove uint.
94
  uint32_t l=20*cs->mbmaxlen+1;
1 by brian
clean slate
95
  int base= unsigned_flag ? 10 : -10;
96
97
  if (alloc(l))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
98
    return true;
205 by Brian Aker
uint32 -> uin32_t
99
  str_length=(uint32_t) (cs->cset->int64_t10_to_str)(cs,Ptr,l,base,num);
1 by brian
clean slate
100
  str_charset=cs;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
101
  return false;
1 by brian
clean slate
102
}
103
482 by Brian Aker
Remove uint.
104
bool String::set_real(double num,uint32_t decimals, const CHARSET_INFO * const cs)
1 by brian
clean slate
105
{
106
  char buff[FLOATING_POINT_BUFFER];
482 by Brian Aker
Remove uint.
107
  uint32_t dummy_errors;
1 by brian
clean slate
108
  size_t len;
109
110
  str_charset=cs;
111
  if (decimals >= NOT_FIXED_DEC)
112
  {
113
    len= my_gcvt(num, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
114
    return copy(buff, len, &my_charset_utf8_general_ci, cs, &dummy_errors);
1 by brian
clean slate
115
  }
116
  len= my_fcvt(num, decimals, buff, NULL);
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
117
  return copy(buff, (uint32_t) len, &my_charset_utf8_general_ci, cs,
1 by brian
clean slate
118
              &dummy_errors);
119
}
120
121
122
bool String::copy()
123
{
124
  if (!alloced)
125
  {
126
    Alloced_length=0;				// Force realloc
127
    return realloc(str_length);
128
  }
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
129
  return false;
1 by brian
clean slate
130
}
131
132
bool String::copy(const String &str)
133
{
134
  if (alloc(str.str_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
135
    return true;
1 by brian
clean slate
136
  str_length=str.str_length;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
137
  memmove(Ptr, str.Ptr, str_length);		// May be overlapping
1 by brian
clean slate
138
  Ptr[str_length]=0;
139
  str_charset=str.str_charset;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
140
  return false;
1 by brian
clean slate
141
}
142
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
143
bool String::copy(const char *str,uint32_t arg_length, const CHARSET_INFO * const cs)
1 by brian
clean slate
144
{
145
  if (alloc(arg_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
146
    return true;
1 by brian
clean slate
147
  if ((str_length=arg_length))
148
    memcpy(Ptr,str,arg_length);
149
  Ptr[arg_length]=0;
150
  str_charset=cs;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
151
  return false;
1 by brian
clean slate
152
}
153
154
155
/*
156
  Checks that the source string can be just copied to the destination string
157
  without conversion.
158
159
  SYNPOSIS
160
161
  needs_conversion()
162
  arg_length		Length of string to copy.
163
  from_cs		Character set to copy from
164
  to_cs			Character set to copy to
205 by Brian Aker
uint32 -> uin32_t
165
  uint32_t *offset	Returns number of unaligned characters.
1 by brian
clean slate
166
167
  RETURN
168
   0  No conversion needed
169
   1  Either character set conversion or adding leading  zeros
170
      (e.g. for UCS-2) must be done
171
172
  NOTE
173
  to_cs may be NULL for "no conversion" if the system variable
174
  character_set_results is NULL.
175
*/
176
205 by Brian Aker
uint32 -> uin32_t
177
bool String::needs_conversion(uint32_t arg_length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
178
			      const CHARSET_INFO * const from_cs,
179
			      const CHARSET_INFO * const to_cs,
205 by Brian Aker
uint32 -> uin32_t
180
			      uint32_t *offset)
1 by brian
clean slate
181
{
182
  *offset= 0;
183
  if (!to_cs ||
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
184
      (to_cs == &my_charset_bin) ||
1 by brian
clean slate
185
      (to_cs == from_cs) ||
186
      my_charset_same(from_cs, to_cs) ||
187
      ((from_cs == &my_charset_bin) &&
188
       (!(*offset=(arg_length % to_cs->mbminlen)))))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
189
    return false;
190
  return true;
1 by brian
clean slate
191
}
192
193
194
/*
195
  Copy a multi-byte character sets with adding leading zeros.
196
197
  SYNOPSIS
198
199
  copy_aligned()
200
  str			String to copy
201
  arg_length		Length of string. This should NOT be dividable with
202
			cs->mbminlen.
203
  offset		arg_length % cs->mb_minlength
204
  cs			Character set for 'str'
205
206
  NOTES
207
    For real multi-byte, ascii incompatible charactser sets,
208
    like UCS-2, add leading zeros if we have an incomplete character.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
209
    Thus,
210
      SELECT _ucs2 0xAA
1 by brian
clean slate
211
    will automatically be converted into
212
      SELECT _ucs2 0x00AA
213
214
  RETURN
215
    0  ok
216
    1  error
217
*/
218
205 by Brian Aker
uint32 -> uin32_t
219
bool String::copy_aligned(const char *str,uint32_t arg_length, uint32_t offset,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
220
                          const CHARSET_INFO * const cs)
1 by brian
clean slate
221
{
222
  /* How many bytes are in incomplete character */
223
  offset= cs->mbmaxlen - offset; /* How many zeros we should prepend */
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
224
  assert(offset && offset != cs->mbmaxlen);
1 by brian
clean slate
225
205 by Brian Aker
uint32 -> uin32_t
226
  uint32_t aligned_length= arg_length + offset;
1 by brian
clean slate
227
  if (alloc(aligned_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
228
    return true;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
229
1 by brian
clean slate
230
  /*
231
    Note, this is only safe for big-endian UCS-2.
232
    If we add little-endian UCS-2 sometimes, this code
233
    will be more complicated. But it's OK for now.
234
  */
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
235
  memset(Ptr, 0, offset);
1 by brian
clean slate
236
  memcpy(Ptr + offset, str, arg_length);
237
  Ptr[aligned_length]=0;
238
  /* str_length is always >= 0 as arg_length is != 0 */
239
  str_length= aligned_length;
240
  str_charset= cs;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
241
  return false;
1 by brian
clean slate
242
}
243
244
205 by Brian Aker
uint32 -> uin32_t
245
bool String::set_or_copy_aligned(const char *str,uint32_t arg_length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
246
                                 const CHARSET_INFO * const cs)
1 by brian
clean slate
247
{
248
  /* How many bytes are in incomplete character */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
249
  uint32_t offset= (arg_length % cs->mbminlen);
250
1 by brian
clean slate
251
  if (!offset) /* All characters are complete, just copy */
252
  {
253
    set(str, arg_length, cs);
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
254
    return false;
1 by brian
clean slate
255
  }
256
  return copy_aligned(str, arg_length, offset, cs);
257
}
258
259
	/* Copy with charset conversion */
260
205 by Brian Aker
uint32 -> uin32_t
261
bool String::copy(const char *str, uint32_t arg_length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
262
		          const CHARSET_INFO * const from_cs,
482 by Brian Aker
Remove uint.
263
				  const CHARSET_INFO * const to_cs, uint32_t *errors)
1 by brian
clean slate
264
{
205 by Brian Aker
uint32 -> uin32_t
265
  uint32_t offset;
1 by brian
clean slate
266
  if (!needs_conversion(arg_length, from_cs, to_cs, &offset))
267
  {
268
    *errors= 0;
269
    return copy(str, arg_length, to_cs);
270
  }
271
  if ((from_cs == &my_charset_bin) && offset)
272
  {
273
    *errors= 0;
274
    return copy_aligned(str, arg_length, offset, to_cs);
275
  }
205 by Brian Aker
uint32 -> uin32_t
276
  uint32_t new_length= to_cs->mbmaxlen*arg_length;
1 by brian
clean slate
277
  if (alloc(new_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
278
    return true;
1 by brian
clean slate
279
  str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
280
                              str, arg_length, from_cs, errors);
281
  str_charset=to_cs;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
282
  return false;
1 by brian
clean slate
283
}
284
285
286
/*
287
  Set a string to the value of a latin1-string, keeping the original charset
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
288
1 by brian
clean slate
289
  SYNOPSIS
290
    copy_or_set()
291
    str			String of a simple charset (latin1)
292
    arg_length		Length of string
293
294
  IMPLEMENTATION
295
    If string object is of a simple character set, set it to point to the
296
    given string.
297
    If not, make a copy and convert it to the new character set.
298
299
  RETURN
300
    0	ok
301
    1	Could not allocate result buffer
302
303
*/
304
205 by Brian Aker
uint32 -> uin32_t
305
bool String::set_ascii(const char *str, uint32_t arg_length)
1 by brian
clean slate
306
{
307
  if (str_charset->mbminlen == 1)
308
  {
309
    set(str, arg_length, str_charset);
310
    return 0;
311
  }
482 by Brian Aker
Remove uint.
312
  uint32_t dummy_errors;
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
313
  return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
1 by brian
clean slate
314
}
315
316
317
/* This is used by mysql.cc */
318
205 by Brian Aker
uint32 -> uin32_t
319
bool String::fill(uint32_t max_length,char fill_char)
1 by brian
clean slate
320
{
321
  if (str_length > max_length)
322
    Ptr[str_length=max_length]=0;
323
  else
324
  {
325
    if (realloc(max_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
326
      return true;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
327
    memset(Ptr+str_length, fill_char, max_length-str_length);
1 by brian
clean slate
328
    str_length=max_length;
329
  }
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
330
  return false;
1 by brian
clean slate
331
}
332
333
bool String::append(const String &s)
334
{
335
  if (s.length())
336
  {
337
    if (realloc(str_length+s.length()))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
338
      return true;
1 by brian
clean slate
339
    memcpy(Ptr+str_length,s.ptr(),s.length());
340
    str_length+=s.length();
341
  }
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
342
  return false;
1 by brian
clean slate
343
}
344
345
346
/*
347
  Append an ASCII string to the a string of the current character set
348
*/
349
205 by Brian Aker
uint32 -> uin32_t
350
bool String::append(const char *s,uint32_t arg_length)
1 by brian
clean slate
351
{
352
  if (!arg_length)
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
353
    return false;
1 by brian
clean slate
354
355
  /*
356
    For an ASCII incompatible string, e.g. UCS-2, we need to convert
357
  */
358
  if (str_charset->mbminlen > 1)
359
  {
205 by Brian Aker
uint32 -> uin32_t
360
    uint32_t add_length=arg_length * str_charset->mbmaxlen;
482 by Brian Aker
Remove uint.
361
    uint32_t dummy_errors;
1 by brian
clean slate
362
    if (realloc(str_length+ add_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
363
      return true;
1 by brian
clean slate
364
    str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
365
				  s, arg_length, &my_charset_utf8_general_ci,
1 by brian
clean slate
366
                                  &dummy_errors);
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
367
    return false;
1 by brian
clean slate
368
  }
369
370
  /*
371
    For an ASCII compatinble string we can just append.
372
  */
373
  if (realloc(str_length+arg_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
374
    return true;
1 by brian
clean slate
375
  memcpy(Ptr+str_length,s,arg_length);
376
  str_length+=arg_length;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
377
  return false;
1 by brian
clean slate
378
}
379
380
381
/*
382
  Append a 0-terminated ASCII string
383
*/
384
385
bool String::append(const char *s)
386
{
387
  return append(s, strlen(s));
388
}
389
390
391
/*
392
  Append a string in the given charset to the string
393
  with character set recoding
394
*/
395
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
396
bool String::append(const char *s,uint32_t arg_length, const CHARSET_INFO * const cs)
1 by brian
clean slate
397
{
205 by Brian Aker
uint32 -> uin32_t
398
  uint32_t dummy_offset;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
399
1 by brian
clean slate
400
  if (needs_conversion(arg_length, cs, str_charset, &dummy_offset))
401
  {
205 by Brian Aker
uint32 -> uin32_t
402
    uint32_t add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
482 by Brian Aker
Remove uint.
403
    uint32_t dummy_errors;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
404
    if (realloc(str_length + add_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
405
      return true;
1 by brian
clean slate
406
    str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
407
				  s, arg_length, cs, &dummy_errors);
408
  }
409
  else
410
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
411
    if (realloc(str_length + arg_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
412
      return true;
1 by brian
clean slate
413
    memcpy(Ptr + str_length, s, arg_length);
414
    str_length+= arg_length;
415
  }
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
416
  return false;
1 by brian
clean slate
417
}
418
419
205 by Brian Aker
uint32 -> uin32_t
420
bool String::append(IO_CACHE* file, uint32_t arg_length)
1 by brian
clean slate
421
{
422
  if (realloc(str_length+arg_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
423
    return true;
481 by Brian Aker
Remove all of uchar.
424
  if (my_b_read(file, (unsigned char*) Ptr + str_length, arg_length))
1 by brian
clean slate
425
  {
426
    shrink(str_length);
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
427
    return true;
1 by brian
clean slate
428
  }
429
  str_length+=arg_length;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
430
  return false;
1 by brian
clean slate
431
}
432
205 by Brian Aker
uint32 -> uin32_t
433
bool String::append_with_prefill(const char *s,uint32_t arg_length,
434
		 uint32_t full_length, char fill_char)
1 by brian
clean slate
435
{
436
  int t_length= arg_length > full_length ? arg_length : full_length;
437
438
  if (realloc(str_length + t_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
439
    return true;
1 by brian
clean slate
440
  t_length= full_length - arg_length;
441
  if (t_length > 0)
442
  {
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
443
    memset(Ptr+str_length, fill_char, t_length);
1 by brian
clean slate
444
    str_length=str_length + t_length;
445
  }
446
  append(s, arg_length);
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
447
  return false;
1 by brian
clean slate
448
}
449
205 by Brian Aker
uint32 -> uin32_t
450
uint32_t String::numchars()
1 by brian
clean slate
451
{
452
  return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
453
}
454
205 by Brian Aker
uint32 -> uin32_t
455
int String::charpos(int i,uint32_t offset)
1 by brian
clean slate
456
{
457
  if (i <= 0)
458
    return i;
459
  return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
460
}
461
205 by Brian Aker
uint32 -> uin32_t
462
int String::strstr(const String &s,uint32_t offset)
1 by brian
clean slate
463
{
464
  if (s.length()+offset <= str_length)
465
  {
466
    if (!s.length())
467
      return ((int) offset);	// Empty string is always found
468
469
    register const char *str = Ptr+offset;
470
    register const char *search=s.ptr();
471
    const char *end=Ptr+str_length-s.length()+1;
472
    const char *search_end=s.ptr()+s.length();
473
skip:
474
    while (str != end)
475
    {
476
      if (*str++ == *search)
477
      {
478
	register char *i,*j;
479
	i=(char*) str; j=(char*) search+1;
480
	while (j != search_end)
481
	  if (*i++ != *j++) goto skip;
482
	return (int) (str-Ptr) -1;
483
      }
484
    }
485
  }
486
  return -1;
487
}
488
489
/*
490
** Search string from end. Offset is offset to the end of string
491
*/
492
205 by Brian Aker
uint32 -> uin32_t
493
int String::strrstr(const String &s,uint32_t offset)
1 by brian
clean slate
494
{
495
  if (s.length() <= offset && offset <= str_length)
496
  {
497
    if (!s.length())
498
      return offset;				// Empty string is always found
499
    register const char *str = Ptr+offset-1;
500
    register const char *search=s.ptr()+s.length()-1;
501
502
    const char *end=Ptr+s.length()-2;
503
    const char *search_end=s.ptr()-1;
504
skip:
505
    while (str != end)
506
    {
507
      if (*str-- == *search)
508
      {
509
	register char *i,*j;
510
	i=(char*) str; j=(char*) search-1;
511
	while (j != search_end)
512
	  if (*i-- != *j--) goto skip;
513
	return (int) (i-Ptr) +1;
514
      }
515
    }
516
  }
517
  return -1;
518
}
519
520
/*
521
  Replace substring with string
522
  If wrong parameter or not enough memory, do nothing
523
*/
524
205 by Brian Aker
uint32 -> uin32_t
525
bool String::replace(uint32_t offset,uint32_t arg_length,const String &to)
1 by brian
clean slate
526
{
527
  return replace(offset,arg_length,to.ptr(),to.length());
528
}
529
205 by Brian Aker
uint32 -> uin32_t
530
bool String::replace(uint32_t offset,uint32_t arg_length,
531
                     const char *to, uint32_t to_length)
1 by brian
clean slate
532
{
533
  long diff = (long) to_length-(long) arg_length;
534
  if (offset+arg_length <= str_length)
535
  {
536
    if (diff < 0)
537
    {
538
      if (to_length)
539
	memcpy(Ptr+offset,to,to_length);
629.3.4 by Kristian Nielsen
Take Mats'es changes from bmove()->memcpy(), and fix all of them to be
540
      memmove(Ptr+offset+to_length, Ptr+offset+arg_length,
541
              str_length-offset-arg_length);
1 by brian
clean slate
542
    }
543
    else
544
    {
545
      if (diff)
546
      {
205 by Brian Aker
uint32 -> uin32_t
547
	if (realloc(str_length+(uint32_t) diff))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
548
	  return true;
481 by Brian Aker
Remove all of uchar.
549
	bmove_upp((unsigned char*) Ptr+str_length+diff, (unsigned char*) Ptr+str_length,
1 by brian
clean slate
550
		  str_length-offset-arg_length);
551
      }
552
      if (to_length)
553
	memcpy(Ptr+offset,to,to_length);
554
    }
205 by Brian Aker
uint32 -> uin32_t
555
    str_length+=(uint32_t) diff;
1 by brian
clean slate
556
  }
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
557
  return false;
1 by brian
clean slate
558
}
559
560
561
// added by Holyfoot for "geometry" needs
205 by Brian Aker
uint32 -> uin32_t
562
int String::reserve(uint32_t space_needed, uint32_t grow_by)
1 by brian
clean slate
563
{
564
  if (Alloced_length < str_length + space_needed)
565
  {
398.1.4 by Monty Taylor
Renamed max/min.
566
    if (realloc(Alloced_length + cmax(space_needed, grow_by) - 1))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
567
      return true;
1 by brian
clean slate
568
  }
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
569
  return false;
1 by brian
clean slate
570
}
571
205 by Brian Aker
uint32 -> uin32_t
572
void String::qs_append(const char *str, uint32_t len)
1 by brian
clean slate
573
{
574
  memcpy(Ptr + str_length, str, len + 1);
575
  str_length += len;
576
}
577
578
void String::qs_append(double d)
579
{
580
  char *buff = Ptr + str_length;
581
  str_length+= my_gcvt(d, MY_GCVT_ARG_DOUBLE, FLOATING_POINT_BUFFER - 1, buff, NULL);
582
}
583
584
void String::qs_append(double *d)
585
{
586
  double ld;
587
  float8get(ld, (char*) d);
588
  qs_append(ld);
589
}
590
591
void String::qs_append(int i)
592
{
593
  char *buff= Ptr + str_length;
594
  char *end= int10_to_str(i, buff, -10);
595
  str_length+= (int) (end-buff);
596
}
597
482 by Brian Aker
Remove uint.
598
void String::qs_append(uint32_t i)
1 by brian
clean slate
599
{
600
  char *buff= Ptr + str_length;
601
  char *end= int10_to_str(i, buff, 10);
602
  str_length+= (int) (end-buff);
603
}
604
605
/*
606
  Compare strings according to collation, without end space.
607
608
  SYNOPSIS
609
    sortcmp()
610
    s		First string
611
    t		Second string
612
    cs		Collation
613
614
  NOTE:
615
    Normally this is case sensitive comparison
616
617
  RETURN
618
  < 0	s < t
619
  0	s == t
620
  > 0	s > t
621
*/
622
623
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
624
int sortcmp(const String *s,const String *t, const CHARSET_INFO * const cs)
1 by brian
clean slate
625
{
626
 return cs->coll->strnncollsp(cs,
481 by Brian Aker
Remove all of uchar.
627
                              (unsigned char *) s->ptr(),s->length(),
628
                              (unsigned char *) t->ptr(),t->length(), 0);
1 by brian
clean slate
629
}
630
631
632
/*
633
  Compare strings byte by byte. End spaces are also compared.
634
635
  SYNOPSIS
636
    stringcmp()
637
    s		First string
638
    t		Second string
639
640
  NOTE:
481 by Brian Aker
Remove all of uchar.
641
    Strings are compared as a stream of unsigned chars
1 by brian
clean slate
642
643
  RETURN
644
  < 0	s < t
645
  0	s == t
646
  > 0	s > t
647
*/
648
649
650
int stringcmp(const String *s,const String *t)
651
{
398.1.4 by Monty Taylor
Renamed max/min.
652
  uint32_t s_len=s->length(),t_len=t->length(),len=cmin(s_len,t_len);
1 by brian
clean slate
653
  int cmp= memcmp(s->ptr(), t->ptr(), len);
654
  return (cmp) ? cmp : (int) (s_len - t_len);
655
}
656
657
205 by Brian Aker
uint32 -> uin32_t
658
String *copy_if_not_alloced(String *to,String *from,uint32_t from_length)
1 by brian
clean slate
659
{
660
  if (from->Alloced_length >= from_length)
661
    return from;
662
  if (from->alloced || !to || from == to)
663
  {
664
    (void) from->realloc(from_length);
665
    return from;
666
  }
667
  if (to->realloc(from_length))
668
    return from;				// Actually an error
398.1.4 by Monty Taylor
Renamed max/min.
669
  if ((to->str_length=cmin(from->str_length,from_length)))
1 by brian
clean slate
670
    memcpy(to->Ptr,from->Ptr,to->str_length);
671
  to->str_charset=from->str_charset;
672
  return to;
673
}
674
675
676
/****************************************************************************
677
  Help functions
678
****************************************************************************/
679
680
/*
681
  copy a string from one character set to another
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
682
1 by brian
clean slate
683
  SYNOPSIS
684
    copy_and_convert()
685
    to			Store result here
686
    to_cs		Character set of result string
687
    from		Copy from here
688
    from_length		Length of from string
689
    from_cs		From character set
690
691
  NOTES
692
    'to' must be big enough as form_length * to_cs->mbmaxlen
693
694
  RETURN
695
    length of bytes copied to 'to'
696
*/
697
698
205 by Brian Aker
uint32 -> uin32_t
699
static uint32_t
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
700
copy_and_convert_extended(char *to, uint32_t to_length,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
701
                          const CHARSET_INFO * const to_cs,
205 by Brian Aker
uint32 -> uin32_t
702
                          const char *from, uint32_t from_length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
703
                          const CHARSET_INFO * const from_cs,
482 by Brian Aker
Remove uint.
704
                          uint32_t *errors)
1 by brian
clean slate
705
{
706
  int         cnvres;
707
  my_wc_t     wc;
481 by Brian Aker
Remove all of uchar.
708
  const unsigned char *from_end= (const unsigned char*) from+from_length;
1 by brian
clean slate
709
  char *to_start= to;
481 by Brian Aker
Remove all of uchar.
710
  unsigned char *to_end= (unsigned char*) to+to_length;
1 by brian
clean slate
711
  my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc;
712
  my_charset_conv_wc_mb wc_mb= to_cs->cset->wc_mb;
482 by Brian Aker
Remove uint.
713
  uint32_t error_count= 0;
1 by brian
clean slate
714
715
  while (1)
716
  {
481 by Brian Aker
Remove all of uchar.
717
    if ((cnvres= (*mb_wc)(from_cs, &wc, (unsigned char*) from,
1 by brian
clean slate
718
				      from_end)) > 0)
719
      from+= cnvres;
720
    else if (cnvres == MY_CS_ILSEQ)
721
    {
722
      error_count++;
723
      from++;
724
      wc= '?';
725
    }
726
    else if (cnvres > MY_CS_TOOSMALL)
727
    {
728
      /*
729
        A correct multibyte sequence detected
730
        But it doesn't have Unicode mapping.
731
      */
732
      error_count++;
733
      from+= (-cnvres);
734
      wc= '?';
735
    }
736
    else
737
      break;  // Not enough characters
738
739
outp:
481 by Brian Aker
Remove all of uchar.
740
    if ((cnvres= (*wc_mb)(to_cs, wc, (unsigned char*) to, to_end)) > 0)
1 by brian
clean slate
741
      to+= cnvres;
742
    else if (cnvres == MY_CS_ILUNI && wc != '?')
743
    {
744
      error_count++;
745
      wc= '?';
746
      goto outp;
747
    }
748
    else
749
      break;
750
  }
751
  *errors= error_count;
205 by Brian Aker
uint32 -> uin32_t
752
  return (uint32_t) (to - to_start);
1 by brian
clean slate
753
}
754
755
756
/*
757
  Optimized for quick copying of ASCII characters in the range 0x00..0x7F.
758
*/
205 by Brian Aker
uint32 -> uin32_t
759
uint32_t
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
760
copy_and_convert(char *to, uint32_t to_length, const CHARSET_INFO * const to_cs,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
761
                 const char *from, uint32_t from_length,
482 by Brian Aker
Remove uint.
762
				 const CHARSET_INFO * const from_cs, uint32_t *errors)
1 by brian
clean slate
763
{
764
  /*
765
    If any of the character sets is not ASCII compatible,
766
    immediately switch to slow mb_wc->wc_mb method.
767
  */
768
  if ((to_cs->state | from_cs->state) & MY_CS_NONASCII)
769
    return copy_and_convert_extended(to, to_length, to_cs,
770
                                     from, from_length, from_cs, errors);
771
398.1.4 by Monty Taylor
Renamed max/min.
772
  uint32_t length= cmin(to_length, from_length), length2= length;
1 by brian
clean slate
773
774
#if defined(__i386__)
775
  /*
776
    Special loop for i386, it allows to refer to a
777
    non-aligned memory block as UINT32, which makes
778
    it possible to copy four bytes at once. This
779
    gives about 10% performance improvement comparing
780
    to byte-by-byte loop.
781
  */
782
  for ( ; length >= 4; length-= 4, from+= 4, to+= 4)
783
  {
205 by Brian Aker
uint32 -> uin32_t
784
    if ((*(uint32_t*)from) & 0x80808080)
1 by brian
clean slate
785
      break;
205 by Brian Aker
uint32 -> uin32_t
786
    *((uint32_t*) to)= *((const uint32_t*) from);
1 by brian
clean slate
787
  }
788
#endif
789
790
  for (; ; *to++= *from++, length--)
791
  {
792
    if (!length)
793
    {
794
      *errors= 0;
795
      return length2;
796
    }
797
    if (*((unsigned char*) from) > 0x7F) /* A non-ASCII character */
798
    {
205 by Brian Aker
uint32 -> uin32_t
799
      uint32_t copied_length= length2 - length;
1 by brian
clean slate
800
      to_length-= copied_length;
801
      from_length-= copied_length;
802
      return copied_length + copy_and_convert_extended(to, to_length,
803
                                                       to_cs,
804
                                                       from, from_length,
805
                                                       from_cs,
806
                                                       errors);
807
    }
808
  }
809
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
810
  assert(false); // Should never get to here
1 by brian
clean slate
811
  return 0;           // Make compiler happy
812
}
813
814
815
/**
816
  Copy string with HEX-encoding of "bad" characters.
817
818
  @details This functions copies the string pointed by "src"
819
  to the string pointed by "dst". Not more than "srclen" bytes
820
  are read from "src". Any sequences of bytes representing
821
  a not-well-formed substring (according to cs) are hex-encoded,
822
  and all well-formed substrings (according to cs) are copied as is.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
823
  Not more than "dstlen" bytes are written to "dst". The number
1 by brian
clean slate
824
  of bytes written to "dst" is returned.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
825
1 by brian
clean slate
826
   @param      cs       character set pointer of the destination string
827
   @param[out] dst      destination string
828
   @param      dstlen   size of dst
829
   @param      src      source string
830
   @param      srclen   length of src
831
832
   @retval     result length
833
*/
834
835
size_t
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
836
my_copy_with_hex_escaping(const CHARSET_INFO * const cs,
1 by brian
clean slate
837
                          char *dst, size_t dstlen,
838
                          const char *src, size_t srclen)
839
{
840
  const char *srcend= src + srclen;
841
  char *dst0= dst;
842
843
  for ( ; src < srcend ; )
844
  {
845
    size_t chlen;
846
    if ((chlen= my_ismbchar(cs, src, srcend)))
847
    {
848
      if (dstlen < chlen)
849
        break; /* purecov: inspected */
850
      memcpy(dst, src, chlen);
851
      src+= chlen;
852
      dst+= chlen;
853
      dstlen-= chlen;
854
    }
855
    else if (*src & 0x80)
856
    {
857
      if (dstlen < 4)
858
        break; /* purecov: inspected */
859
      *dst++= '\\';
860
      *dst++= 'x';
861
      *dst++= _dig_vec_upper[((unsigned char) *src) >> 4];
862
      *dst++= _dig_vec_upper[((unsigned char) *src) & 15];
863
      src++;
864
      dstlen-= 4;
865
    }
866
    else
867
    {
868
      if (dstlen < 1)
869
        break; /* purecov: inspected */
870
      *dst++= *src++;
871
      dstlen--;
872
    }
873
  }
874
  return dst - dst0;
875
}
876
877
/*
878
  copy a string,
879
  with optional character set conversion,
880
  with optional left padding (for binary -> UCS2 conversion)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
881
1 by brian
clean slate
882
  SYNOPSIS
883
    well_formed_copy_nchars()
884
    to			     Store result here
885
    to_length                Maxinum length of "to" string
886
    to_cs		     Character set of "to" string
887
    from		     Copy from here
888
    from_length		     Length of from string
889
    from_cs		     From character set
890
    nchars                   Copy not more that nchars characters
891
    well_formed_error_pos    Return position when "from" is not well formed
892
                             or NULL otherwise.
893
    cannot_convert_error_pos Return position where a not convertable
894
                             character met, or NULL otherwise.
895
    from_end_pos             Return position where scanning of "from"
896
                             string stopped.
897
  NOTES
898
899
  RETURN
900
    length of bytes copied to 'to'
901
*/
902
903
205 by Brian Aker
uint32 -> uin32_t
904
uint32_t
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
905
well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
482 by Brian Aker
Remove uint.
906
                        char *to, uint32_t to_length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
907
                        const CHARSET_INFO * const from_cs,
482 by Brian Aker
Remove uint.
908
                        const char *from, uint32_t from_length,
909
                        uint32_t nchars,
1 by brian
clean slate
910
                        const char **well_formed_error_pos,
911
                        const char **cannot_convert_error_pos,
912
                        const char **from_end_pos)
913
{
482 by Brian Aker
Remove uint.
914
  uint32_t res;
1 by brian
clean slate
915
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
916
  if ((to_cs == &my_charset_bin) ||
1 by brian
clean slate
917
      (from_cs == &my_charset_bin) ||
918
      (to_cs == from_cs) ||
919
      my_charset_same(from_cs, to_cs))
920
  {
921
    if (to_length < to_cs->mbminlen || !nchars)
922
    {
923
      *from_end_pos= from;
924
      *cannot_convert_error_pos= NULL;
925
      *well_formed_error_pos= NULL;
926
      return 0;
927
    }
928
929
    if (to_cs == &my_charset_bin)
930
    {
398.1.4 by Monty Taylor
Renamed max/min.
931
      res= cmin(cmin(nchars, to_length), from_length);
1 by brian
clean slate
932
      memmove(to, from, res);
933
      *from_end_pos= from + res;
934
      *well_formed_error_pos= NULL;
935
      *cannot_convert_error_pos= NULL;
936
    }
937
    else
938
    {
939
      int well_formed_error;
482 by Brian Aker
Remove uint.
940
      uint32_t from_offset;
1 by brian
clean slate
941
942
      if ((from_offset= (from_length % to_cs->mbminlen)) &&
943
          (from_cs == &my_charset_bin))
944
      {
945
        /*
946
          Copying from BINARY to UCS2 needs to prepend zeros sometimes:
947
          INSERT INTO t1 (ucs2_column) VALUES (0x01);
948
          0x01 -> 0x0001
949
        */
482 by Brian Aker
Remove uint.
950
        uint32_t pad_length= to_cs->mbminlen - from_offset;
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
951
        memset(to, 0, pad_length);
1 by brian
clean slate
952
        memmove(to + pad_length, from, from_offset);
953
        nchars--;
954
        from+= from_offset;
955
        from_length-= from_offset;
956
        to+= to_cs->mbminlen;
957
        to_length-= to_cs->mbminlen;
958
      }
959
960
      set_if_smaller(from_length, to_length);
961
      res= to_cs->cset->well_formed_len(to_cs, from, from + from_length,
962
                                        nchars, &well_formed_error);
963
      memmove(to, from, res);
964
      *from_end_pos= from + res;
965
      *well_formed_error_pos= well_formed_error ? from + res : NULL;
966
      *cannot_convert_error_pos= NULL;
967
      if (from_offset)
968
        res+= to_cs->mbminlen;
969
    }
970
  }
971
  else
972
  {
973
    int cnvres;
974
    my_wc_t wc;
975
    my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc;
976
    my_charset_conv_wc_mb wc_mb= to_cs->cset->wc_mb;
481 by Brian Aker
Remove all of uchar.
977
    const unsigned char *from_end= (const unsigned char*) from + from_length;
978
    unsigned char *to_end= (unsigned char*) to + to_length;
1 by brian
clean slate
979
    char *to_start= to;
980
    *well_formed_error_pos= NULL;
981
    *cannot_convert_error_pos= NULL;
982
983
    for ( ; nchars; nchars--)
984
    {
985
      const char *from_prev= from;
481 by Brian Aker
Remove all of uchar.
986
      if ((cnvres= (*mb_wc)(from_cs, &wc, (unsigned char*) from, from_end)) > 0)
1 by brian
clean slate
987
        from+= cnvres;
988
      else if (cnvres == MY_CS_ILSEQ)
989
      {
990
        if (!*well_formed_error_pos)
991
          *well_formed_error_pos= from;
992
        from++;
993
        wc= '?';
994
      }
995
      else if (cnvres > MY_CS_TOOSMALL)
996
      {
997
        /*
998
          A correct multibyte sequence detected
999
          But it doesn't have Unicode mapping.
1000
        */
1001
        if (!*cannot_convert_error_pos)
1002
          *cannot_convert_error_pos= from;
1003
        from+= (-cnvres);
1004
        wc= '?';
1005
      }
1006
      else
1007
        break;  // Not enough characters
1008
1009
outp:
481 by Brian Aker
Remove all of uchar.
1010
      if ((cnvres= (*wc_mb)(to_cs, wc, (unsigned char*) to, to_end)) > 0)
1 by brian
clean slate
1011
        to+= cnvres;
1012
      else if (cnvres == MY_CS_ILUNI && wc != '?')
1013
      {
1014
        if (!*cannot_convert_error_pos)
1015
          *cannot_convert_error_pos= from_prev;
1016
        wc= '?';
1017
        goto outp;
1018
      }
1019
      else
1020
      {
1021
        from= from_prev;
1022
        break;
1023
      }
1024
    }
1025
    *from_end_pos= from;
1026
    res= to - to_start;
1027
  }
205 by Brian Aker
uint32 -> uin32_t
1028
  return (uint32_t) res;
1 by brian
clean slate
1029
}
1030
1031
1032
1033
1034
void String::print(String *str)
1035
{
1036
  char *st= (char*)Ptr, *end= st+str_length;
1037
  for (; st < end; st++)
1038
  {
481 by Brian Aker
Remove all of uchar.
1039
    unsigned char c= *st;
1 by brian
clean slate
1040
    switch (c)
1041
    {
1042
    case '\\':
520.4.32 by Monty Taylor
Fixed oops.
1043
      str->append("\\\\", sizeof("\\\\")-1);
1 by brian
clean slate
1044
      break;
1045
    case '\0':
520.4.32 by Monty Taylor
Fixed oops.
1046
      str->append("\\0", sizeof("\\0")-1);
1 by brian
clean slate
1047
      break;
1048
    case '\'':
520.4.32 by Monty Taylor
Fixed oops.
1049
      str->append("\\'", sizeof("\\'")-1);
1 by brian
clean slate
1050
      break;
1051
    case '\n':
520.4.32 by Monty Taylor
Fixed oops.
1052
      str->append("\\n", sizeof("\\n")-1);
1 by brian
clean slate
1053
      break;
1054
    case '\r':
520.4.32 by Monty Taylor
Fixed oops.
1055
      str->append("\\r", sizeof("\\r")-1);
1 by brian
clean slate
1056
      break;
1057
    case '\032': // Ctrl-Z
520.4.32 by Monty Taylor
Fixed oops.
1058
      str->append("\\Z", sizeof("\\Z")-1);
1 by brian
clean slate
1059
      break;
1060
    default:
1061
      str->append(c);
1062
    }
1063
  }
1064
}
1065
1066
1067
/*
1068
  Exchange state of this object and argument.
1069
1070
  SYNOPSIS
1071
    String::swap()
1072
1073
  RETURN
1074
    Target string will contain state of this object and vice versa.
1075
*/
1076
1077
void String::swap(String &s)
1078
{
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
1079
  std::swap(Ptr, s.Ptr);
1080
  std::swap(str_length, s.str_length);
1081
  std::swap(Alloced_length, s.Alloced_length);
1082
  std::swap(alloced, s.alloced);
1083
  std::swap(str_charset, s.str_charset);
1 by brian
clean slate
1084
}
598.1.1 by Super-User
Fixed solaris build crap.
1085
1086
1087
bool operator==(const String &s1, const String &s2)
1088
{
1089
  return stringcmp(&s1,&s2) == 0;
1090
}
1091
1092
bool operator!=(const String &s1, const String &s2)
1093
{
1094
  return !(s1 == s2);
1095
}
1096