~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
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
61
String::String(uint32_t length_arg)
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)),
73
    str_length(static_cast<uint32_t>(strlen(str))),
74
    Alloced_length(0),
75
    alloced(false),
76
    str_charset(cs)
77
{ }
78
1253.2.5 by Monty Taylor
Merged from trunk.
79
1241.16.2 by Monty Taylor
Cleaned effc++ warnings from sql_string.
80
String::String(const char *str, uint32_t len, const CHARSET_INFO * const cs)
81
  : Ptr(const_cast<char *>(str)),
82
    str_length(len),
83
    Alloced_length(0),
84
    alloced(false),
85
    str_charset(cs)
86
{ }
87
88
89
String::String(char *str, uint32_t len, const CHARSET_INFO * const cs)
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
{
1485 by Brian Aker
Updates to confine memroot
109
  return mem_root->alloc_root(static_cast<uint32_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
205 by Brian Aker
uint32 -> uin32_t
114
bool String::real_alloc(uint32_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
  {
120
    free();
641.3.6 by Monty Taylor
Removed some my_malloc calls.
121
    if (!(Ptr=(char*) malloc(arg_length)))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
122
      return true;
1 by brian
clean slate
123
    Alloced_length=arg_length;
124
    alloced=1;
125
  }
126
  Ptr[0]=0;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
127
  return false;
1 by brian
clean slate
128
}
129
130
131
/*
132
** Check that string is big enough. Set string[alloc_length] to 0
133
** (for C functions)
134
*/
135
205 by Brian Aker
uint32 -> uin32_t
136
bool String::realloc(uint32_t alloc_length)
1 by brian
clean slate
137
{
205 by Brian Aker
uint32 -> uin32_t
138
  uint32_t len=ALIGN_SIZE(alloc_length+1);
1 by brian
clean slate
139
  if (Alloced_length < len)
140
  {
141
    char *new_ptr;
142
    if (alloced)
143
    {
656.1.26 by Monty Taylor
Finally removed all of the my_malloc stuff.
144
      if ((new_ptr= (char*) ::realloc(Ptr,len)))
1 by brian
clean slate
145
      {
146
	Ptr=new_ptr;
147
	Alloced_length=len;
148
      }
149
      else
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
150
	return true;				// Signal error
1 by brian
clean slate
151
    }
641.3.6 by Monty Taylor
Removed some my_malloc calls.
152
    else if ((new_ptr= (char*) malloc(len)))
1 by brian
clean slate
153
    {
154
      if (str_length)				// Avoid bugs in memcpy on AIX
155
	memcpy(new_ptr,Ptr,str_length);
156
      new_ptr[str_length]=0;
157
      Ptr=new_ptr;
158
      Alloced_length=len;
159
      alloced=1;
160
    }
161
    else
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
162
      return true;			// Signal error
1 by brian
clean slate
163
  }
164
  Ptr[alloc_length]=0;			// This make other funcs shorter
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
165
  return false;
1 by brian
clean slate
166
}
167
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
168
bool String::set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs)
1 by brian
clean slate
169
{
482 by Brian Aker
Remove uint.
170
  uint32_t l=20*cs->mbmaxlen+1;
1 by brian
clean slate
171
  int base= unsigned_flag ? 10 : -10;
172
173
  if (alloc(l))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
174
    return true;
205 by Brian Aker
uint32 -> uin32_t
175
  str_length=(uint32_t) (cs->cset->int64_t10_to_str)(cs,Ptr,l,base,num);
1 by brian
clean slate
176
  str_charset=cs;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
177
  return false;
1 by brian
clean slate
178
}
179
482 by Brian Aker
Remove uint.
180
bool String::set_real(double num,uint32_t decimals, const CHARSET_INFO * const cs)
1 by brian
clean slate
181
{
182
  char buff[FLOATING_POINT_BUFFER];
482 by Brian Aker
Remove uint.
183
  uint32_t dummy_errors;
1 by brian
clean slate
184
  size_t len;
185
186
  str_charset=cs;
187
  if (decimals >= NOT_FIXED_DEC)
188
  {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
189
    len= internal::my_gcvt(num,
190
                           internal::MY_GCVT_ARG_DOUBLE,
191
                           sizeof(buff) - 1, buff, NULL);
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
192
    return copy(buff, len, &my_charset_utf8_general_ci, cs, &dummy_errors);
1 by brian
clean slate
193
  }
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
194
  len= internal::my_fcvt(num, decimals, buff, NULL);
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
195
  return copy(buff, (uint32_t) len, &my_charset_utf8_general_ci, cs,
1 by brian
clean slate
196
              &dummy_errors);
197
}
198
199
200
bool String::copy()
201
{
202
  if (!alloced)
203
  {
204
    Alloced_length=0;				// Force realloc
205
    return realloc(str_length);
206
  }
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
207
  return false;
1 by brian
clean slate
208
}
209
210
bool String::copy(const String &str)
211
{
212
  if (alloc(str.str_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
213
    return true;
1 by brian
clean slate
214
  str_length=str.str_length;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
215
  memmove(Ptr, str.Ptr, str_length);		// May be overlapping
1 by brian
clean slate
216
  Ptr[str_length]=0;
217
  str_charset=str.str_charset;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
218
  return false;
1 by brian
clean slate
219
}
220
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
221
bool String::copy(const char *str,uint32_t arg_length, const CHARSET_INFO * const cs)
1 by brian
clean slate
222
{
223
  if (alloc(arg_length))
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
224
    return true;
1 by brian
clean slate
225
  if ((str_length=arg_length))
226
    memcpy(Ptr,str,arg_length);
227
  Ptr[arg_length]=0;
228
  str_charset=cs;
51.1.74 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
229
  return false;
1 by brian
clean slate
230
}
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
205 by Brian Aker
uint32 -> uin32_t
243
  uint32_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
205 by Brian Aker
uint32 -> uin32_t
255
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.
256
			      const CHARSET_INFO * const from_cs,
257
			      const CHARSET_INFO * const to_cs,
205 by Brian Aker
uint32 -> uin32_t
258
			      uint32_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
205 by Brian Aker
uint32 -> uin32_t
274
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.
275
                                 const CHARSET_INFO * const cs)
1 by brian
clean slate
276
{
277
  /* How many bytes are in incomplete character */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
278
  uint32_t offset= (arg_length % cs->mbminlen);
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
205 by Brian Aker
uint32 -> uin32_t
288
bool String::copy(const char *str, uint32_t arg_length,
975.1.2 by Brian Aker
LCOV cleanup (more of...).
289
		          const CHARSET_INFO * const,
482 by Brian Aker
Remove uint.
290
				  const CHARSET_INFO * const to_cs, uint32_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
205 by Brian Aker
uint32 -> uin32_t
316
bool String::set_ascii(const char *str, uint32_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
  }
482 by Brian Aker
Remove uint.
323
  uint32_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
205 by Brian Aker
uint32 -> uin32_t
344
bool String::append(const char *s,uint32_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
975.1.2 by Brian Aker
LCOV cleanup (more of...).
375
bool String::append(const char *s,uint32_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
205 by Brian Aker
uint32 -> uin32_t
386
bool String::append_with_prefill(const char *s,uint32_t arg_length,
387
		 uint32_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
205 by Brian Aker
uint32 -> uin32_t
403
uint32_t String::numchars()
1 by brian
clean slate
404
{
405
  return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
406
}
407
205 by Brian Aker
uint32 -> uin32_t
408
int String::charpos(int i,uint32_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
205 by Brian Aker
uint32 -> uin32_t
415
int String::strstr(const String &s,uint32_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
205 by Brian Aker
uint32 -> uin32_t
446
int String::strrstr(const String &s,uint32_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
205 by Brian Aker
uint32 -> uin32_t
478
bool String::replace(uint32_t offset,uint32_t arg_length,const String &to)
1 by brian
clean slate
479
{
480
  return replace(offset,arg_length,to.ptr(),to.length());
481
}
482
205 by Brian Aker
uint32 -> uin32_t
483
bool String::replace(uint32_t offset,uint32_t arg_length,
484
                     const char *to, uint32_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
      {
205 by Brian Aker
uint32 -> uin32_t
500
	if (realloc(str_length+(uint32_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
    }
205 by Brian Aker
uint32 -> uin32_t
509
    str_length+=(uint32_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
{
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).
563
  uint32_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
205 by Brian Aker
uint32 -> uin32_t
569
String *copy_if_not_alloced(String *to,String *from,uint32_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
205 by Brian Aker
uint32 -> uin32_t
618
uint32_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,
482 by Brian Aker
Remove uint.
620
                        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.
621
                        const CHARSET_INFO * const from_cs,
482 by Brian Aker
Remove uint.
622
                        const char *from, uint32_t from_length,
623
                        uint32_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
{
482 by Brian Aker
Remove uint.
628
  uint32_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;
654
    uint32_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
      */
664
      uint32_t pad_length= to_cs->mbminlen - from_offset;
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
779.3.10 by Monty Taylor
Turned on -Wshadow.
736
void String::append_identifier(const char *name, uint32_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
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
791
void String::q_append(const uint32_t n)
792
{
793
  int4store(Ptr + str_length, n);
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
}
806
void String::q_append(const char *data, uint32_t data_len)
807
{
808
  memcpy(Ptr + str_length, data, data_len);
809
  str_length += data_len;
810
}
811
812
void String::write_at_position(int position, uint32_t value)
813
{
814
  int4store(Ptr + position,value);
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
822
} /* namespace drizzled */
823
824
bool operator==(const drizzled::String &s1, const drizzled::String &s2)
825
{
826
  return stringcmp(&s1,&s2) == 0;
827
}
828
829
bool operator!=(const drizzled::String &s1, const drizzled::String &s2)
830
{
831
  return !(s1 == s2);
832
}
833