~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
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
15
16
/* This file is originally from the mysql distribution. Coded by monty */
17
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
18
#include "config.h"
19
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
20
#include "drizzled/internal/my_sys.h"
21
#include "drizzled/internal/m_string.h"
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
22
#include "drizzled/charset.h"
1271.2.4 by Tim Penhey
Add some standard converstion functions.
23
#include "drizzled/global_charset_info.h"
1 by brian
clean slate
24
398.1.5 by Monty Taylor
Removed C++ includes and std namespace from global.h.
25
#include <algorithm>
26
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
27
#include "drizzled/sql_string.h"
28
1067.4.4 by Nathan Williams
The rest of the files in the drizzled directory were purged of the cmin macro and replace with std::min (except for the definition in globals.h and 1 usage in stacktrace.cc).
29
using namespace std;
30
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
31
namespace drizzled
32
{
1271.2.4 by Tim Penhey
Add some standard converstion functions.
33
34
// Converstion functions to and from std::string.
35
36
std::string String_to_std_string(String const& s)
37
{
38
   return std::string(s.ptr(), s.length());
39
}
40
41
String* set_String_from_std_string(String* s, std::string const& cs)
42
{
43
   s->set_ascii(cs.c_str(), cs.length());
1271.3.2 by Tim Penhey
Remove the converter not being used, and make the String setter copy the underlying string.
44
   s->copy();
1271.2.4 by Tim Penhey
Add some standard converstion functions.
45
   return s;
46
}
47
1 by brian
clean slate
48
/*****************************************************************************
49
** String functions
50
*****************************************************************************/
51
1241.16.2 by Monty Taylor
Cleaned effc++ warnings from sql_string.
52
String::String()
53
  : Ptr(NULL),
54
    str_length(0),
55
    Alloced_length(0),
56
    alloced(false),
57
    str_charset(&my_charset_bin)
58
{ }
59
60
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
61
String::String(size_t length_arg)
1241.16.2 by Monty Taylor
Cleaned effc++ warnings from sql_string.
62
  : Ptr(NULL),
63
    str_length(0),
64
    Alloced_length(0),
65
    alloced(false),
66
    str_charset(&my_charset_bin)
67
{
68
  (void) real_alloc(length_arg);
69
}
70
71
String::String(const char *str, const CHARSET_INFO * const cs)
72
  : Ptr(const_cast<char *>(str)),
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
73
    str_length(static_cast<size_t>(strlen(str))),
1241.16.2 by Monty Taylor
Cleaned effc++ warnings from sql_string.
74
    Alloced_length(0),
75
    alloced(false),
76
    str_charset(cs)
77
{ }
78
1253.2.5 by Monty Taylor
Merged from trunk.
79
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
80
String::String(const char *str, size_t len, const CHARSET_INFO * const cs)
1241.16.2 by Monty Taylor
Cleaned effc++ warnings from sql_string.
81
  : Ptr(const_cast<char *>(str)),
82
    str_length(len),
83
    Alloced_length(0),
84
    alloced(false),
85
    str_charset(cs)
86
{ }
87
88
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
89
String::String(char *str, size_t len, const CHARSET_INFO * const cs)
1241.16.2 by Monty Taylor
Cleaned effc++ warnings from sql_string.
90
  : Ptr(str),
91
    str_length(len),
1241.9.51 by Monty Taylor
More mysys stuff out of headers.
92
    Alloced_length(len),
1241.16.2 by Monty Taylor
Cleaned effc++ warnings from sql_string.
93
    alloced(false),
94
    str_charset(cs)
95
{ }
96
97
98
String::String(const String &str)
99
  : Ptr(str.Ptr),
100
    str_length(str.str_length),
101
    Alloced_length(str.Alloced_length),
102
    alloced(false),
103
    str_charset(str.str_charset)
104
{ }
105
106
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
107
void *String::operator new(size_t size, memory::Root *mem_root)
1241.9.51 by Monty Taylor
More mysys stuff out of headers.
108
{
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
109
  return mem_root->alloc_root(static_cast<size_t>(size));
1241.9.51 by Monty Taylor
More mysys stuff out of headers.
110
}
111
1022.2.29 by Monty Taylor
Fixed some no-inline warnings.
112
String::~String() { free(); }
113
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
114
bool String::real_alloc(size_t arg_length)
1 by brian
clean slate
115
{
116
  arg_length=ALIGN_SIZE(arg_length+1);
117
  str_length=0;
118
  if (Alloced_length < arg_length)
119
  {
1885.2.2 by Andrew Hutchings
Fixed a double free()
120
    if (Alloced_length > 0)
121
      free();
641.3.6 by Monty Taylor
Removed some my_malloc calls.
122
    if (!(Ptr=(char*) malloc(arg_length)))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
123
      return true;
1 by brian
clean slate
124
    Alloced_length=arg_length;
125
    alloced=1;
126
  }
127
  Ptr[0]=0;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
128
  return false;
1 by brian
clean slate
129
}
130
131
132
/*
133
** Check that string is big enough. Set string[alloc_length] to 0
134
** (for C functions)
135
*/
136
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
137
bool String::realloc(size_t alloc_length)
1 by brian
clean slate
138
{
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
139
  size_t len=ALIGN_SIZE(alloc_length+1);
1 by brian
clean slate
140
  if (Alloced_length < len)
141
  {
142
    char *new_ptr;
143
    if (alloced)
144
    {
656.1.26 by Monty Taylor
Finally removed all of the my_malloc stuff.
145
      if ((new_ptr= (char*) ::realloc(Ptr,len)))
1 by brian
clean slate
146
      {
147
	Ptr=new_ptr;
148
	Alloced_length=len;
149
      }
150
      else
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
151
	return true;				// Signal error
1 by brian
clean slate
152
    }
641.3.6 by Monty Taylor
Removed some my_malloc calls.
153
    else if ((new_ptr= (char*) malloc(len)))
1 by brian
clean slate
154
    {
155
      if (str_length)				// Avoid bugs in memcpy on AIX
156
	memcpy(new_ptr,Ptr,str_length);
157
      new_ptr[str_length]=0;
158
      Ptr=new_ptr;
159
      Alloced_length=len;
160
      alloced=1;
161
    }
162
    else
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
163
      return true;			// Signal error
1 by brian
clean slate
164
  }
165
  Ptr[alloc_length]=0;			// This make other funcs shorter
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
166
  return false;
1 by brian
clean slate
167
}
168
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
169
bool String::set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs)
1 by brian
clean slate
170
{
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
171
  size_t l=20*cs->mbmaxlen+1;
1 by brian
clean slate
172
  int base= unsigned_flag ? 10 : -10;
173
174
  if (alloc(l))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
175
    return true;
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
176
  str_length=(size_t) (cs->cset->int64_t10_to_str)(cs,Ptr,l,base,num);
1 by brian
clean slate
177
  str_charset=cs;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
178
  return false;
1 by brian
clean slate
179
}
180
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
181
bool String::set_real(double num,size_t decimals, const CHARSET_INFO * const cs)
1 by brian
clean slate
182
{
183
  char buff[FLOATING_POINT_BUFFER];
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
184
  size_t dummy_errors;
1 by brian
clean slate
185
  size_t len;
186
187
  str_charset=cs;
188
  if (decimals >= NOT_FIXED_DEC)
189
  {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
190
    len= internal::my_gcvt(num,
191
                           internal::MY_GCVT_ARG_DOUBLE,
192
                           sizeof(buff) - 1, buff, NULL);
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
193
    return copy(buff, len, &my_charset_utf8_general_ci, cs, &dummy_errors);
1 by brian
clean slate
194
  }
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
195
  len= internal::my_fcvt(num, decimals, buff, NULL);
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
196
  return copy(buff, (size_t) len, &my_charset_utf8_general_ci, cs,
1 by brian
clean slate
197
              &dummy_errors);
198
}
199
200
201
bool String::copy()
202
{
203
  if (!alloced)
204
  {
205
    Alloced_length=0;				// Force realloc
206
    return realloc(str_length);
207
  }
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
208
  return false;
1 by brian
clean slate
209
}
210
211
bool String::copy(const String &str)
212
{
213
  if (alloc(str.str_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
214
    return true;
1 by brian
clean slate
215
  str_length=str.str_length;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
216
  memmove(Ptr, str.Ptr, str_length);		// May be overlapping
1 by brian
clean slate
217
  Ptr[str_length]=0;
218
  str_charset=str.str_charset;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
219
  return false;
1 by brian
clean slate
220
}
221
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
222
bool String::copy(const char *str,size_t arg_length, const CHARSET_INFO * const cs)
1 by brian
clean slate
223
{
224
  if (alloc(arg_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
225
    return true;
1 by brian
clean slate
226
  if ((str_length=arg_length))
227
    memcpy(Ptr,str,arg_length);
228
  Ptr[arg_length]=0;
229
  str_charset=cs;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
230
  return false;
1 by brian
clean slate
231
}
232
233
234
/*
235
  Checks that the source string can be just copied to the destination string
236
  without conversion.
237
238
  SYNPOSIS
239
240
  needs_conversion()
241
  arg_length		Length of string to copy.
242
  from_cs		Character set to copy from
243
  to_cs			Character set to copy to
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
244
  size_t *offset	Returns number of unaligned characters.
1 by brian
clean slate
245
246
  RETURN
247
   0  No conversion needed
248
   1  Either character set conversion or adding leading  zeros
249
      (e.g. for UCS-2) must be done
250
251
  NOTE
252
  to_cs may be NULL for "no conversion" if the system variable
253
  character_set_results is NULL.
254
*/
255
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
256
bool String::needs_conversion(size_t arg_length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
257
			      const CHARSET_INFO * const from_cs,
258
			      const CHARSET_INFO * const to_cs,
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
259
			      size_t *offset)
1 by brian
clean slate
260
{
261
  *offset= 0;
262
  if (!to_cs ||
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
263
      (to_cs == &my_charset_bin) ||
1 by brian
clean slate
264
      (to_cs == from_cs) ||
265
      my_charset_same(from_cs, to_cs) ||
266
      ((from_cs == &my_charset_bin) &&
267
       (!(*offset=(arg_length % to_cs->mbminlen)))))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
268
    return false;
269
  return true;
1 by brian
clean slate
270
}
271
272
273
274
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
275
bool String::set_or_copy_aligned(const char *str,size_t arg_length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
276
                                 const CHARSET_INFO * const cs)
1 by brian
clean slate
277
{
278
  /* How many bytes are in incomplete character */
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
279
  size_t offset= (arg_length % cs->mbminlen);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
280
910.1.5 by Brian Aker
Remove some dead bits of string (and fix the semi_join test).
281
  assert(!offset); /* All characters are complete, just copy */
282
283
  set(str, arg_length, cs);
284
  return false;
1 by brian
clean slate
285
}
286
287
	/* Copy with charset conversion */
288
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
289
bool String::copy(const char *str, size_t arg_length,
975.1.2 by Brian Aker
LCOV cleanup (more of...).
290
		          const CHARSET_INFO * const,
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
291
				  const CHARSET_INFO * const to_cs, size_t *errors)
1 by brian
clean slate
292
{
975.1.2 by Brian Aker
LCOV cleanup (more of...).
293
  *errors= 0;
294
  return copy(str, arg_length, to_cs);
1 by brian
clean slate
295
}
296
297
298
/*
299
  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:
300
1 by brian
clean slate
301
  SYNOPSIS
302
    copy_or_set()
303
    str			String of a simple charset (latin1)
304
    arg_length		Length of string
305
306
  IMPLEMENTATION
307
    If string object is of a simple character set, set it to point to the
308
    given string.
309
    If not, make a copy and convert it to the new character set.
310
311
  RETURN
312
    0	ok
313
    1	Could not allocate result buffer
314
315
*/
316
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
317
bool String::set_ascii(const char *str, size_t arg_length)
1 by brian
clean slate
318
{
319
  if (str_charset->mbminlen == 1)
320
  {
321
    set(str, arg_length, str_charset);
322
    return 0;
323
  }
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
324
  size_t dummy_errors;
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
325
  return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
1 by brian
clean slate
326
}
327
328
bool String::append(const String &s)
329
{
330
  if (s.length())
331
  {
332
    if (realloc(str_length+s.length()))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
333
      return true;
1 by brian
clean slate
334
    memcpy(Ptr+str_length,s.ptr(),s.length());
335
    str_length+=s.length();
336
  }
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
337
  return false;
1 by brian
clean slate
338
}
339
340
341
/*
342
  Append an ASCII string to the a string of the current character set
343
*/
344
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
345
bool String::append(const char *s,size_t arg_length)
1 by brian
clean slate
346
{
347
  if (!arg_length)
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
348
    return false;
1 by brian
clean slate
349
350
  /*
351
    For an ASCII compatinble string we can just append.
352
  */
353
  if (realloc(str_length+arg_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
354
    return true;
1 by brian
clean slate
355
  memcpy(Ptr+str_length,s,arg_length);
356
  str_length+=arg_length;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
357
  return false;
1 by brian
clean slate
358
}
359
360
361
/*
362
  Append a 0-terminated ASCII string
363
*/
364
365
bool String::append(const char *s)
366
{
367
  return append(s, strlen(s));
368
}
369
370
371
/*
372
  Append a string in the given charset to the string
373
  with character set recoding
374
*/
375
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
376
bool String::append(const char *s,size_t arg_length, const CHARSET_INFO * const)
1 by brian
clean slate
377
{
975.1.2 by Brian Aker
LCOV cleanup (more of...).
378
  if (realloc(str_length + arg_length))
379
    return true;
380
  memcpy(Ptr + str_length, s, arg_length);
381
  str_length+= arg_length;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
382
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
383
  return false;
1 by brian
clean slate
384
}
385
386
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
387
bool String::append_with_prefill(const char *s,size_t arg_length,
388
		 size_t full_length, char fill_char)
1 by brian
clean slate
389
{
390
  int t_length= arg_length > full_length ? arg_length : full_length;
391
392
  if (realloc(str_length + t_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
393
    return true;
1 by brian
clean slate
394
  t_length= full_length - arg_length;
395
  if (t_length > 0)
396
  {
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
397
    memset(Ptr+str_length, fill_char, t_length);
1 by brian
clean slate
398
    str_length=str_length + t_length;
399
  }
400
  append(s, arg_length);
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
401
  return false;
1 by brian
clean slate
402
}
403
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
404
size_t String::numchars()
1 by brian
clean slate
405
{
406
  return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
407
}
408
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
409
int String::charpos(int i,size_t offset)
1 by brian
clean slate
410
{
411
  if (i <= 0)
412
    return i;
413
  return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
414
}
415
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
416
int String::strstr(const String &s,size_t offset)
1 by brian
clean slate
417
{
418
  if (s.length()+offset <= str_length)
419
  {
420
    if (!s.length())
421
      return ((int) offset);	// Empty string is always found
422
423
    register const char *str = Ptr+offset;
424
    register const char *search=s.ptr();
425
    const char *end=Ptr+str_length-s.length()+1;
426
    const char *search_end=s.ptr()+s.length();
427
skip:
428
    while (str != end)
429
    {
430
      if (*str++ == *search)
431
      {
432
	register char *i,*j;
433
	i=(char*) str; j=(char*) search+1;
434
	while (j != search_end)
435
	  if (*i++ != *j++) goto skip;
436
	return (int) (str-Ptr) -1;
437
      }
438
    }
439
  }
440
  return -1;
441
}
442
443
/*
444
** Search string from end. Offset is offset to the end of string
445
*/
446
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
447
int String::strrstr(const String &s,size_t offset)
1 by brian
clean slate
448
{
449
  if (s.length() <= offset && offset <= str_length)
450
  {
451
    if (!s.length())
452
      return offset;				// Empty string is always found
453
    register const char *str = Ptr+offset-1;
454
    register const char *search=s.ptr()+s.length()-1;
455
456
    const char *end=Ptr+s.length()-2;
457
    const char *search_end=s.ptr()-1;
458
skip:
459
    while (str != end)
460
    {
461
      if (*str-- == *search)
462
      {
463
	register char *i,*j;
464
	i=(char*) str; j=(char*) search-1;
465
	while (j != search_end)
466
	  if (*i-- != *j--) goto skip;
467
	return (int) (i-Ptr) +1;
468
      }
469
    }
470
  }
471
  return -1;
472
}
473
474
/*
475
  Replace substring with string
476
  If wrong parameter or not enough memory, do nothing
477
*/
478
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
479
bool String::replace(size_t offset,size_t arg_length,const String &to)
1 by brian
clean slate
480
{
481
  return replace(offset,arg_length,to.ptr(),to.length());
482
}
483
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
484
bool String::replace(size_t offset,size_t arg_length,
485
                     const char *to, size_t to_length)
1 by brian
clean slate
486
{
487
  long diff = (long) to_length-(long) arg_length;
488
  if (offset+arg_length <= str_length)
489
  {
490
    if (diff < 0)
491
    {
492
      if (to_length)
493
	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
494
      memmove(Ptr+offset+to_length, Ptr+offset+arg_length,
495
              str_length-offset-arg_length);
1 by brian
clean slate
496
    }
497
    else
498
    {
499
      if (diff)
500
      {
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
501
	if (realloc(str_length+(size_t) diff))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
502
	  return true;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
503
	internal::bmove_upp((unsigned char*) Ptr+str_length+diff,
504
                            (unsigned char*) Ptr+str_length,
505
                            str_length-offset-arg_length);
1 by brian
clean slate
506
      }
507
      if (to_length)
508
	memcpy(Ptr+offset,to,to_length);
509
    }
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
510
    str_length+=(size_t) diff;
1 by brian
clean slate
511
  }
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
512
  return false;
1 by brian
clean slate
513
}
514
515
516
517
/*
518
  Compare strings according to collation, without end space.
519
520
  SYNOPSIS
521
    sortcmp()
522
    s		First string
523
    t		Second string
524
    cs		Collation
525
526
  NOTE:
527
    Normally this is case sensitive comparison
528
529
  RETURN
530
  < 0	s < t
531
  0	s == t
532
  > 0	s > t
533
*/
534
535
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
536
int sortcmp(const String *s,const String *t, const CHARSET_INFO * const cs)
1 by brian
clean slate
537
{
538
 return cs->coll->strnncollsp(cs,
481 by Brian Aker
Remove all of uchar.
539
                              (unsigned char *) s->ptr(),s->length(),
540
                              (unsigned char *) t->ptr(),t->length(), 0);
1 by brian
clean slate
541
}
542
543
544
/*
545
  Compare strings byte by byte. End spaces are also compared.
546
547
  SYNOPSIS
548
    stringcmp()
549
    s		First string
550
    t		Second string
551
552
  NOTE:
481 by Brian Aker
Remove all of uchar.
553
    Strings are compared as a stream of unsigned chars
1 by brian
clean slate
554
555
  RETURN
556
  < 0	s < t
557
  0	s == t
558
  > 0	s > t
559
*/
560
561
562
int stringcmp(const String *s,const String *t)
563
{
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
564
  size_t s_len= s->length(), t_len= t->length(), len= min(s_len,t_len);
1 by brian
clean slate
565
  int cmp= memcmp(s->ptr(), t->ptr(), len);
566
  return (cmp) ? cmp : (int) (s_len - t_len);
567
}
568
569
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
570
String *copy_if_not_alloced(String *to,String *from,size_t from_length)
1 by brian
clean slate
571
{
572
  if (from->Alloced_length >= from_length)
573
    return from;
574
  if (from->alloced || !to || from == to)
575
  {
576
    (void) from->realloc(from_length);
577
    return from;
578
  }
579
  if (to->realloc(from_length))
580
    return from;				// Actually an error
1067.4.4 by Nathan Williams
The rest of the files in the drizzled directory were purged of the cmin macro and replace with std::min (except for the definition in globals.h and 1 usage in stacktrace.cc).
581
  if ((to->str_length= min(from->str_length,from_length)))
1 by brian
clean slate
582
    memcpy(to->Ptr,from->Ptr,to->str_length);
583
  to->str_charset=from->str_charset;
584
  return to;
585
}
586
587
588
/****************************************************************************
589
  Help functions
590
****************************************************************************/
591
592
/*
593
  copy a string,
594
  with optional character set conversion,
595
  with optional left padding (for binary -> UCS2 conversion)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
596
1 by brian
clean slate
597
  SYNOPSIS
598
    well_formed_copy_nchars()
599
    to			     Store result here
600
    to_length                Maxinum length of "to" string
601
    to_cs		     Character set of "to" string
602
    from		     Copy from here
603
    from_length		     Length of from string
604
    from_cs		     From character set
605
    nchars                   Copy not more that nchars characters
606
    well_formed_error_pos    Return position when "from" is not well formed
607
                             or NULL otherwise.
608
    cannot_convert_error_pos Return position where a not convertable
609
                             character met, or NULL otherwise.
610
    from_end_pos             Return position where scanning of "from"
611
                             string stopped.
612
  NOTES
613
614
  RETURN
615
    length of bytes copied to 'to'
616
*/
617
618
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
619
size_t
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
620
well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
621
                        char *to, size_t to_length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
622
                        const CHARSET_INFO * const from_cs,
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
623
                        const char *from, size_t from_length,
624
                        size_t nchars,
1 by brian
clean slate
625
                        const char **well_formed_error_pos,
626
                        const char **cannot_convert_error_pos,
627
                        const char **from_end_pos)
628
{
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
629
  size_t res;
1 by brian
clean slate
630
1034 by Brian Aker
Dead Code
631
  assert((to_cs == &my_charset_bin) ||
632
         (from_cs == &my_charset_bin) ||
633
         (to_cs == from_cs) ||
634
         my_charset_same(from_cs, to_cs));
635
636
  if (to_length < to_cs->mbminlen || !nchars)
637
  {
638
    *from_end_pos= from;
639
    *cannot_convert_error_pos= NULL;
640
    *well_formed_error_pos= NULL;
641
    return 0;
642
  }
643
644
  if (to_cs == &my_charset_bin)
645
  {
1067.4.4 by Nathan Williams
The rest of the files in the drizzled directory were purged of the cmin macro and replace with std::min (except for the definition in globals.h and 1 usage in stacktrace.cc).
646
    res= min(min(nchars, to_length), from_length);
1034 by Brian Aker
Dead Code
647
    memmove(to, from, res);
648
    *from_end_pos= from + res;
649
    *well_formed_error_pos= NULL;
650
    *cannot_convert_error_pos= NULL;
1 by brian
clean slate
651
  }
652
  else
653
  {
1034 by Brian Aker
Dead Code
654
    int well_formed_error;
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
655
    size_t from_offset;
1 by brian
clean slate
656
1034 by Brian Aker
Dead Code
657
    if ((from_offset= (from_length % to_cs->mbminlen)) &&
658
        (from_cs == &my_charset_bin))
1 by brian
clean slate
659
    {
1034 by Brian Aker
Dead Code
660
      /*
661
        Copying from BINARY to UCS2 needs to prepend zeros sometimes:
662
        INSERT INTO t1 (ucs2_column) VALUES (0x01);
663
        0x01 -> 0x0001
664
      */
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
665
      size_t pad_length= to_cs->mbminlen - from_offset;
1034 by Brian Aker
Dead Code
666
      memset(to, 0, pad_length);
667
      memmove(to + pad_length, from, from_offset);
668
      nchars--;
669
      from+= from_offset;
670
      from_length-= from_offset;
671
      to+= to_cs->mbminlen;
672
      to_length-= to_cs->mbminlen;
1 by brian
clean slate
673
    }
1034 by Brian Aker
Dead Code
674
675
    set_if_smaller(from_length, to_length);
676
    res= to_cs->cset->well_formed_len(to_cs, from, from + from_length,
677
                                      nchars, &well_formed_error);
678
    memmove(to, from, res);
679
    *from_end_pos= from + res;
680
    *well_formed_error_pos= well_formed_error ? from + res : NULL;
681
    *cannot_convert_error_pos= NULL;
682
    if (from_offset)
683
      res+= to_cs->mbminlen;
1 by brian
clean slate
684
  }
1034 by Brian Aker
Dead Code
685
686
  return res;
1 by brian
clean slate
687
}
688
689
690
691
692
void String::print(String *str)
693
{
694
  char *st= (char*)Ptr, *end= st+str_length;
695
  for (; st < end; st++)
696
  {
481 by Brian Aker
Remove all of uchar.
697
    unsigned char c= *st;
1 by brian
clean slate
698
    switch (c)
699
    {
700
    case '\\':
520.4.32 by Monty Taylor
Fixed oops.
701
      str->append("\\\\", sizeof("\\\\")-1);
1 by brian
clean slate
702
      break;
703
    case '\0':
520.4.32 by Monty Taylor
Fixed oops.
704
      str->append("\\0", sizeof("\\0")-1);
1 by brian
clean slate
705
      break;
706
    case '\'':
520.4.32 by Monty Taylor
Fixed oops.
707
      str->append("\\'", sizeof("\\'")-1);
1 by brian
clean slate
708
      break;
709
    case '\n':
520.4.32 by Monty Taylor
Fixed oops.
710
      str->append("\\n", sizeof("\\n")-1);
1 by brian
clean slate
711
      break;
712
    case '\r':
520.4.32 by Monty Taylor
Fixed oops.
713
      str->append("\\r", sizeof("\\r")-1);
1 by brian
clean slate
714
      break;
715
    case '\032': // Ctrl-Z
520.4.32 by Monty Taylor
Fixed oops.
716
      str->append("\\Z", sizeof("\\Z")-1);
1 by brian
clean slate
717
      break;
718
    default:
719
      str->append(c);
720
    }
721
  }
722
}
723
794 by Brian Aker
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
724
/*
725
  Quote the given identifier.
726
  If the given identifier is empty, it will be quoted.
727
728
  SYNOPSIS
729
  append_identifier()
730
  name                  the identifier to be appended
731
  name_length           length of the appending identifier
732
*/
733
734
/* Factor the extern out */
735
extern const CHARSET_INFO *system_charset_info, *files_charset_info;
736
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
737
void String::append_identifier(const char *name, size_t in_length)
794 by Brian Aker
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
738
{
739
  const char *name_end;
740
  char quote_char;
741
  int q= '`';
742
743
  /*
744
    The identifier must be quoted as it includes a quote character or
745
   it's a keyword
746
  */
747
779.3.10 by Monty Taylor
Turned on -Wshadow.
748
  reserve(in_length*2 + 2);
794 by Brian Aker
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
749
  quote_char= (char) q;
750
  append(&quote_char, 1, system_charset_info);
751
779.3.10 by Monty Taylor
Turned on -Wshadow.
752
  for (name_end= name+in_length ; name < name_end ; name+= in_length)
794 by Brian Aker
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
753
  {
754
    unsigned char chr= (unsigned char) *name;
779.3.10 by Monty Taylor
Turned on -Wshadow.
755
    in_length= my_mbcharlen(system_charset_info, chr);
794 by Brian Aker
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
756
    /*
757
      my_mbcharlen can return 0 on a wrong multibyte
758
      sequence. It is possible when upgrading from 4.0,
759
      and identifier contains some accented characters.
760
      The manual says it does not work. So we'll just
761
      change length to 1 not to hang in the endless loop.
762
    */
779.3.10 by Monty Taylor
Turned on -Wshadow.
763
    if (!in_length)
764
      in_length= 1;
765
    if (in_length == 1 && chr == (unsigned char) quote_char)
794 by Brian Aker
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
766
      append(&quote_char, 1, system_charset_info);
779.3.10 by Monty Taylor
Turned on -Wshadow.
767
    append(name, in_length, system_charset_info);
794 by Brian Aker
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
768
  }
769
  append(&quote_char, 1, system_charset_info);
770
}
771
1 by brian
clean slate
772
773
/*
774
  Exchange state of this object and argument.
775
776
  SYNOPSIS
777
    String::swap()
778
779
  RETURN
780
    Target string will contain state of this object and vice versa.
781
*/
782
783
void String::swap(String &s)
784
{
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
785
  std::swap(Ptr, s.Ptr);
786
  std::swap(str_length, s.str_length);
787
  std::swap(Alloced_length, s.Alloced_length);
788
  std::swap(alloced, s.alloced);
789
  std::swap(str_charset, s.str_charset);
1 by brian
clean slate
790
}
598.1.1 by Super-User
Fixed solaris build crap.
791
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
792
void String::q_append(const size_t n)
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
793
{
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
794
  int8store(Ptr + str_length, n);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
795
  str_length += 4;
796
}
797
void String::q_append(double d)
798
{
799
  float8store(Ptr + str_length, d);
800
  str_length += 8;
801
}
802
void String::q_append(double *d)
803
{
804
  float8store(Ptr + str_length, *d);
805
  str_length += 8;
806
}
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
807
void String::q_append(const char *data, size_t data_len)
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
808
{
809
  memcpy(Ptr + str_length, data, data_len);
810
  str_length += data_len;
811
}
812
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
813
void String::write_at_position(int position, size_t value)
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
814
{
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
815
  int8store(Ptr + position,value);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
816
}
1241.9.51 by Monty Taylor
More mysys stuff out of headers.
817
bool check_if_only_end_space(const CHARSET_INFO * const cs, char *str,
818
                             char *end)
819
{
820
  return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
821
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
822
823
} /* namespace drizzled */
824
825
bool operator==(const drizzled::String &s1, const drizzled::String &s2)
826
{
827
  return stringcmp(&s1,&s2) == 0;
828
}
829
830
bool operator!=(const drizzled::String &s1, const drizzled::String &s2)
831
{
832
  return !(s1 == s2);
833
}
834