~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
  Checks that the source string can be just copied to the destination string
235
  without conversion.
236
237
  SYNPOSIS
238
239
  needs_conversion()
240
  arg_length		Length of string to copy.
241
  from_cs		Character set to copy from
242
  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).
243
  size_t *offset	Returns number of unaligned characters.
1 by brian
clean slate
244
245
  RETURN
246
   0  No conversion needed
247
   1  Either character set conversion or adding leading  zeros
248
      (e.g. for UCS-2) must be done
249
250
  NOTE
251
  to_cs may be NULL for "no conversion" if the system variable
252
  character_set_results is NULL.
253
*/
254
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
255
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.
256
			      const CHARSET_INFO * const from_cs,
257
			      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).
258
			      size_t *offset)
1 by brian
clean slate
259
{
260
  *offset= 0;
261
  if (!to_cs ||
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
262
      (to_cs == &my_charset_bin) ||
1 by brian
clean slate
263
      (to_cs == from_cs) ||
264
      my_charset_same(from_cs, to_cs) ||
265
      ((from_cs == &my_charset_bin) &&
266
       (!(*offset=(arg_length % to_cs->mbminlen)))))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
267
    return false;
268
  return true;
1 by brian
clean slate
269
}
270
271
272
273
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
274
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.
275
                                 const CHARSET_INFO * const cs)
1 by brian
clean slate
276
{
277
  /* 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).
278
  size_t offset= (arg_length % cs->mbminlen);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
279
910.1.5 by Brian Aker
Remove some dead bits of string (and fix the semi_join test).
280
  assert(!offset); /* All characters are complete, just copy */
281
282
  set(str, arg_length, cs);
283
  return false;
1 by brian
clean slate
284
}
285
286
	/* Copy with charset conversion */
287
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
288
bool String::copy(const char *str, size_t arg_length,
975.1.2 by Brian Aker
LCOV cleanup (more of...).
289
		          const CHARSET_INFO * const,
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
290
				  const CHARSET_INFO * const to_cs, size_t *errors)
1 by brian
clean slate
291
{
975.1.2 by Brian Aker
LCOV cleanup (more of...).
292
  *errors= 0;
293
  return copy(str, arg_length, to_cs);
1 by brian
clean slate
294
}
295
296
297
/*
298
  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:
299
1 by brian
clean slate
300
  SYNOPSIS
301
    copy_or_set()
302
    str			String of a simple charset (latin1)
303
    arg_length		Length of string
304
305
  IMPLEMENTATION
306
    If string object is of a simple character set, set it to point to the
307
    given string.
308
    If not, make a copy and convert it to the new character set.
309
310
  RETURN
311
    0	ok
312
    1	Could not allocate result buffer
313
314
*/
315
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
316
bool String::set_ascii(const char *str, size_t arg_length)
1 by brian
clean slate
317
{
318
  if (str_charset->mbminlen == 1)
319
  {
320
    set(str, arg_length, str_charset);
321
    return 0;
322
  }
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
323
  size_t dummy_errors;
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
324
  return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
1 by brian
clean slate
325
}
326
327
bool String::append(const String &s)
328
{
329
  if (s.length())
330
  {
331
    if (realloc(str_length+s.length()))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
332
      return true;
1 by brian
clean slate
333
    memcpy(Ptr+str_length,s.ptr(),s.length());
334
    str_length+=s.length();
335
  }
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
336
  return false;
1 by brian
clean slate
337
}
338
339
340
/*
341
  Append an ASCII string to the a string of the current character set
342
*/
343
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
344
bool String::append(const char *s,size_t arg_length)
1 by brian
clean slate
345
{
346
  if (!arg_length)
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
347
    return false;
1 by brian
clean slate
348
349
  /*
350
    For an ASCII compatinble string we can just append.
351
  */
352
  if (realloc(str_length+arg_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
353
    return true;
1 by brian
clean slate
354
  memcpy(Ptr+str_length,s,arg_length);
355
  str_length+=arg_length;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
356
  return false;
1 by brian
clean slate
357
}
358
359
360
/*
361
  Append a 0-terminated ASCII string
362
*/
363
364
bool String::append(const char *s)
365
{
366
  return append(s, strlen(s));
367
}
368
369
370
/*
371
  Append a string in the given charset to the string
372
  with character set recoding
373
*/
374
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
375
bool String::append(const char *s,size_t arg_length, const CHARSET_INFO * const)
1 by brian
clean slate
376
{
975.1.2 by Brian Aker
LCOV cleanup (more of...).
377
  if (realloc(str_length + arg_length))
378
    return true;
379
  memcpy(Ptr + str_length, s, arg_length);
380
  str_length+= arg_length;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
381
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
382
  return false;
1 by brian
clean slate
383
}
384
385
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
386
bool String::append_with_prefill(const char *s,size_t arg_length,
387
		 size_t full_length, char fill_char)
1 by brian
clean slate
388
{
389
  int t_length= arg_length > full_length ? arg_length : full_length;
390
391
  if (realloc(str_length + t_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
392
    return true;
1 by brian
clean slate
393
  t_length= full_length - arg_length;
394
  if (t_length > 0)
395
  {
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
396
    memset(Ptr+str_length, fill_char, t_length);
1 by brian
clean slate
397
    str_length=str_length + t_length;
398
  }
399
  append(s, arg_length);
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
400
  return false;
1 by brian
clean slate
401
}
402
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
403
size_t String::numchars()
1 by brian
clean slate
404
{
405
  return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
406
}
407
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
408
int String::charpos(int i,size_t offset)
1 by brian
clean slate
409
{
410
  if (i <= 0)
411
    return i;
412
  return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
413
}
414
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
415
int String::strstr(const String &s,size_t offset)
1 by brian
clean slate
416
{
417
  if (s.length()+offset <= str_length)
418
  {
419
    if (!s.length())
420
      return ((int) offset);	// Empty string is always found
421
422
    register const char *str = Ptr+offset;
423
    register const char *search=s.ptr();
424
    const char *end=Ptr+str_length-s.length()+1;
425
    const char *search_end=s.ptr()+s.length();
426
skip:
427
    while (str != end)
428
    {
429
      if (*str++ == *search)
430
      {
431
	register char *i,*j;
432
	i=(char*) str; j=(char*) search+1;
433
	while (j != search_end)
434
	  if (*i++ != *j++) goto skip;
435
	return (int) (str-Ptr) -1;
436
      }
437
    }
438
  }
439
  return -1;
440
}
441
442
/*
443
** Search string from end. Offset is offset to the end of string
444
*/
445
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
446
int String::strrstr(const String &s,size_t offset)
1 by brian
clean slate
447
{
448
  if (s.length() <= offset && offset <= str_length)
449
  {
450
    if (!s.length())
451
      return offset;				// Empty string is always found
452
    register const char *str = Ptr+offset-1;
453
    register const char *search=s.ptr()+s.length()-1;
454
455
    const char *end=Ptr+s.length()-2;
456
    const char *search_end=s.ptr()-1;
457
skip:
458
    while (str != end)
459
    {
460
      if (*str-- == *search)
461
      {
462
	register char *i,*j;
463
	i=(char*) str; j=(char*) search-1;
464
	while (j != search_end)
465
	  if (*i-- != *j--) goto skip;
466
	return (int) (i-Ptr) +1;
467
      }
468
    }
469
  }
470
  return -1;
471
}
472
473
/*
474
  Replace substring with string
475
  If wrong parameter or not enough memory, do nothing
476
*/
477
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
478
bool String::replace(size_t offset,size_t arg_length,const String &to)
1 by brian
clean slate
479
{
480
  return replace(offset,arg_length,to.ptr(),to.length());
481
}
482
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
483
bool String::replace(size_t offset,size_t arg_length,
484
                     const char *to, size_t to_length)
1 by brian
clean slate
485
{
486
  long diff = (long) to_length-(long) arg_length;
487
  if (offset+arg_length <= str_length)
488
  {
489
    if (diff < 0)
490
    {
491
      if (to_length)
492
	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
493
      memmove(Ptr+offset+to_length, Ptr+offset+arg_length,
494
              str_length-offset-arg_length);
1 by brian
clean slate
495
    }
496
    else
497
    {
498
      if (diff)
499
      {
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
500
	if (realloc(str_length+(size_t) diff))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
501
	  return true;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
502
	internal::bmove_upp((unsigned char*) Ptr+str_length+diff,
503
                            (unsigned char*) Ptr+str_length,
504
                            str_length-offset-arg_length);
1 by brian
clean slate
505
      }
506
      if (to_length)
507
	memcpy(Ptr+offset,to,to_length);
508
    }
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
509
    str_length+=(size_t) diff;
1 by brian
clean slate
510
  }
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
511
  return false;
1 by brian
clean slate
512
}
513
514
515
516
/*
517
  Compare strings according to collation, without end space.
518
519
  SYNOPSIS
520
    sortcmp()
521
    s		First string
522
    t		Second string
523
    cs		Collation
524
525
  NOTE:
526
    Normally this is case sensitive comparison
527
528
  RETURN
529
  < 0	s < t
530
  0	s == t
531
  > 0	s > t
532
*/
533
534
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
535
int sortcmp(const String *s,const String *t, const CHARSET_INFO * const cs)
1 by brian
clean slate
536
{
537
 return cs->coll->strnncollsp(cs,
481 by Brian Aker
Remove all of uchar.
538
                              (unsigned char *) s->ptr(),s->length(),
539
                              (unsigned char *) t->ptr(),t->length(), 0);
1 by brian
clean slate
540
}
541
542
543
/*
544
  Compare strings byte by byte. End spaces are also compared.
545
546
  SYNOPSIS
547
    stringcmp()
548
    s		First string
549
    t		Second string
550
551
  NOTE:
481 by Brian Aker
Remove all of uchar.
552
    Strings are compared as a stream of unsigned chars
1 by brian
clean slate
553
554
  RETURN
555
  < 0	s < t
556
  0	s == t
557
  > 0	s > t
558
*/
559
560
561
int stringcmp(const String *s,const String *t)
562
{
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
563
  size_t s_len= s->length(), t_len= t->length(), len= min(s_len,t_len);
1 by brian
clean slate
564
  int cmp= memcmp(s->ptr(), t->ptr(), len);
565
  return (cmp) ? cmp : (int) (s_len - t_len);
566
}
567
568
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
569
String *copy_if_not_alloced(String *to,String *from,size_t from_length)
1 by brian
clean slate
570
{
571
  if (from->Alloced_length >= from_length)
572
    return from;
573
  if (from->alloced || !to || from == to)
574
  {
575
    (void) from->realloc(from_length);
576
    return from;
577
  }
578
  if (to->realloc(from_length))
579
    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).
580
  if ((to->str_length= min(from->str_length,from_length)))
1 by brian
clean slate
581
    memcpy(to->Ptr,from->Ptr,to->str_length);
582
  to->str_charset=from->str_charset;
583
  return to;
584
}
585
586
587
/****************************************************************************
588
  Help functions
589
****************************************************************************/
590
591
/*
592
  copy a string,
593
  with optional character set conversion,
594
  with optional left padding (for binary -> UCS2 conversion)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
595
1 by brian
clean slate
596
  SYNOPSIS
597
    well_formed_copy_nchars()
598
    to			     Store result here
599
    to_length                Maxinum length of "to" string
600
    to_cs		     Character set of "to" string
601
    from		     Copy from here
602
    from_length		     Length of from string
603
    from_cs		     From character set
604
    nchars                   Copy not more that nchars characters
605
    well_formed_error_pos    Return position when "from" is not well formed
606
                             or NULL otherwise.
607
    cannot_convert_error_pos Return position where a not convertable
608
                             character met, or NULL otherwise.
609
    from_end_pos             Return position where scanning of "from"
610
                             string stopped.
611
  NOTES
612
613
  RETURN
614
    length of bytes copied to 'to'
615
*/
616
617
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
618
size_t
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
619
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).
620
                        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.
621
                        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).
622
                        const char *from, size_t from_length,
623
                        size_t nchars,
1 by brian
clean slate
624
                        const char **well_formed_error_pos,
625
                        const char **cannot_convert_error_pos,
626
                        const char **from_end_pos)
627
{
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
628
  size_t res;
1 by brian
clean slate
629
1034 by Brian Aker
Dead Code
630
  assert((to_cs == &my_charset_bin) ||
631
         (from_cs == &my_charset_bin) ||
632
         (to_cs == from_cs) ||
633
         my_charset_same(from_cs, to_cs));
634
635
  if (to_length < to_cs->mbminlen || !nchars)
636
  {
637
    *from_end_pos= from;
638
    *cannot_convert_error_pos= NULL;
639
    *well_formed_error_pos= NULL;
640
    return 0;
641
  }
642
643
  if (to_cs == &my_charset_bin)
644
  {
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).
645
    res= min(min(nchars, to_length), from_length);
1034 by Brian Aker
Dead Code
646
    memmove(to, from, res);
647
    *from_end_pos= from + res;
648
    *well_formed_error_pos= NULL;
649
    *cannot_convert_error_pos= NULL;
1 by brian
clean slate
650
  }
651
  else
652
  {
1034 by Brian Aker
Dead Code
653
    int well_formed_error;
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
654
    size_t from_offset;
1 by brian
clean slate
655
1034 by Brian Aker
Dead Code
656
    if ((from_offset= (from_length % to_cs->mbminlen)) &&
657
        (from_cs == &my_charset_bin))
1 by brian
clean slate
658
    {
1034 by Brian Aker
Dead Code
659
      /*
660
        Copying from BINARY to UCS2 needs to prepend zeros sometimes:
661
        INSERT INTO t1 (ucs2_column) VALUES (0x01);
662
        0x01 -> 0x0001
663
      */
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
664
      size_t pad_length= to_cs->mbminlen - from_offset;
1034 by Brian Aker
Dead Code
665
      memset(to, 0, pad_length);
666
      memmove(to + pad_length, from, from_offset);
667
      nchars--;
668
      from+= from_offset;
669
      from_length-= from_offset;
670
      to+= to_cs->mbminlen;
671
      to_length-= to_cs->mbminlen;
1 by brian
clean slate
672
    }
1034 by Brian Aker
Dead Code
673
674
    set_if_smaller(from_length, to_length);
675
    res= to_cs->cset->well_formed_len(to_cs, from, from + from_length,
676
                                      nchars, &well_formed_error);
677
    memmove(to, from, res);
678
    *from_end_pos= from + res;
679
    *well_formed_error_pos= well_formed_error ? from + res : NULL;
680
    *cannot_convert_error_pos= NULL;
681
    if (from_offset)
682
      res+= to_cs->mbminlen;
1 by brian
clean slate
683
  }
1034 by Brian Aker
Dead Code
684
685
  return res;
1 by brian
clean slate
686
}
687
688
689
690
691
void String::print(String *str)
692
{
693
  char *st= (char*)Ptr, *end= st+str_length;
694
  for (; st < end; st++)
695
  {
481 by Brian Aker
Remove all of uchar.
696
    unsigned char c= *st;
1 by brian
clean slate
697
    switch (c)
698
    {
699
    case '\\':
520.4.32 by Monty Taylor
Fixed oops.
700
      str->append("\\\\", sizeof("\\\\")-1);
1 by brian
clean slate
701
      break;
702
    case '\0':
520.4.32 by Monty Taylor
Fixed oops.
703
      str->append("\\0", sizeof("\\0")-1);
1 by brian
clean slate
704
      break;
705
    case '\'':
520.4.32 by Monty Taylor
Fixed oops.
706
      str->append("\\'", sizeof("\\'")-1);
1 by brian
clean slate
707
      break;
708
    case '\n':
520.4.32 by Monty Taylor
Fixed oops.
709
      str->append("\\n", sizeof("\\n")-1);
1 by brian
clean slate
710
      break;
711
    case '\r':
520.4.32 by Monty Taylor
Fixed oops.
712
      str->append("\\r", sizeof("\\r")-1);
1 by brian
clean slate
713
      break;
714
    case '\032': // Ctrl-Z
520.4.32 by Monty Taylor
Fixed oops.
715
      str->append("\\Z", sizeof("\\Z")-1);
1 by brian
clean slate
716
      break;
717
    default:
718
      str->append(c);
719
    }
720
  }
721
}
722
794 by Brian Aker
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
723
/*
724
  Quote the given identifier.
725
  If the given identifier is empty, it will be quoted.
726
727
  SYNOPSIS
728
  append_identifier()
729
  name                  the identifier to be appended
730
  name_length           length of the appending identifier
731
*/
732
733
/* Factor the extern out */
734
extern const CHARSET_INFO *system_charset_info, *files_charset_info;
735
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
736
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
737
{
738
  const char *name_end;
739
  char quote_char;
740
  int q= '`';
741
742
  /*
743
    The identifier must be quoted as it includes a quote character or
744
   it's a keyword
745
  */
746
779.3.10 by Monty Taylor
Turned on -Wshadow.
747
  reserve(in_length*2 + 2);
794 by Brian Aker
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
748
  quote_char= (char) q;
749
  append(&quote_char, 1, system_charset_info);
750
779.3.10 by Monty Taylor
Turned on -Wshadow.
751
  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
752
  {
753
    unsigned char chr= (unsigned char) *name;
779.3.10 by Monty Taylor
Turned on -Wshadow.
754
    in_length= my_mbcharlen(system_charset_info, chr);
794 by Brian Aker
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
755
    /*
756
      my_mbcharlen can return 0 on a wrong multibyte
757
      sequence. It is possible when upgrading from 4.0,
758
      and identifier contains some accented characters.
759
      The manual says it does not work. So we'll just
760
      change length to 1 not to hang in the endless loop.
761
    */
779.3.10 by Monty Taylor
Turned on -Wshadow.
762
    if (!in_length)
763
      in_length= 1;
764
    if (in_length == 1 && chr == (unsigned char) quote_char)
794 by Brian Aker
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
765
      append(&quote_char, 1, system_charset_info);
779.3.10 by Monty Taylor
Turned on -Wshadow.
766
    append(name, in_length, system_charset_info);
794 by Brian Aker
Refactor append_identifier and remove dead OPTION_QUOTE_SHOW_CREATE option
767
  }
768
  append(&quote_char, 1, system_charset_info);
769
}
770
1 by brian
clean slate
771
772
/*
773
  Exchange state of this object and argument.
774
775
  SYNOPSIS
776
    String::swap()
777
778
  RETURN
779
    Target string will contain state of this object and vice versa.
780
*/
781
782
void String::swap(String &s)
783
{
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
784
  std::swap(Ptr, s.Ptr);
785
  std::swap(str_length, s.str_length);
786
  std::swap(Alloced_length, s.Alloced_length);
787
  std::swap(alloced, s.alloced);
788
  std::swap(str_charset, s.str_charset);
1 by brian
clean slate
789
}
598.1.1 by Super-User
Fixed solaris build crap.
790
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
791
void String::q_append(const size_t n)
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
792
{
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
793
  int8store(Ptr + str_length, n);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
794
  str_length += 4;
795
}
796
void String::q_append(double d)
797
{
798
  float8store(Ptr + str_length, d);
799
  str_length += 8;
800
}
801
void String::q_append(double *d)
802
{
803
  float8store(Ptr + str_length, *d);
804
  str_length += 8;
805
}
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
806
void String::q_append(const char *data, size_t data_len)
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
807
{
808
  memcpy(Ptr + str_length, data, data_len);
809
  str_length += data_len;
810
}
811
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
812
void String::write_at_position(int position, size_t value)
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
813
{
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
814
  int8store(Ptr + position,value);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
815
}
1241.9.51 by Monty Taylor
More mysys stuff out of headers.
816
bool check_if_only_end_space(const CHARSET_INFO * const cs, char *str,
817
                             char *end)
818
{
819
  return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
820
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
821
2023.2.1 by Brian Aker
Merge in BOOL type.
822
std::ostream& operator<<(std::ostream& output, const String &str)
823
{
824
  output << "String:(";
825
  output <<  const_cast<String&>(str).c_str();
826
  output << ", ";
827
  output << str.length();
828
  output << ")";
829
830
  return output;  // for multiple << operators.
831
}
832
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
833
} /* namespace drizzled */
834
835
bool operator==(const drizzled::String &s1, const drizzled::String &s2)
836
{
837
  return stringcmp(&s1,&s2) == 0;
838
}
839
840
bool operator!=(const drizzled::String &s1, const drizzled::String &s2)
841
{
842
  return !(s1 == s2);
843
}
844