~drizzle-trunk/drizzle/development

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