~ubuntu-branches/ubuntu/saucy/drizzle/saucy-proposed

« back to all changes in this revision

Viewing changes to drizzled/sql_string.h

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-03-18 12:12:31 UTC
  • Revision ID: james.westby@ubuntu.com-20100318121231-k6g1xe6cshbwa0f8
Tags: upstream-2010.03.1347
ImportĀ upstreamĀ versionĀ 2010.03.1347

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#ifndef DRIZZLED_SQL_STRING_H
 
21
#define DRIZZLED_SQL_STRING_H
 
22
 
 
23
/* This file is originally from the mysql distribution. Coded by monty */
 
24
 
 
25
#include <drizzled/common.h>
 
26
#include <cassert>
 
27
#include <cstdlib>
 
28
#include <cstring>
 
29
#include <string>
 
30
 
 
31
#ifndef NOT_FIXED_DEC
 
32
#define NOT_FIXED_DEC                   (uint8_t)31
 
33
#endif
 
34
 
 
35
namespace drizzled
 
36
{
 
37
 
 
38
class String;
 
39
 
 
40
extern String my_empty_string;
 
41
extern const String my_null_string;
 
42
namespace memory { class Root; }
 
43
typedef struct charset_info_st CHARSET_INFO;
 
44
 
 
45
std::string String_to_std_string(String const& s);
 
46
String* set_String_from_std_string(String* s, std::string const& cs);
 
47
 
 
48
int sortcmp(const String *a,const String *b, const CHARSET_INFO * const cs);
 
49
int stringcmp(const String *a,const String *b);
 
50
String *copy_if_not_alloced(String *a,String *b,uint32_t arg_length);
 
51
uint32_t well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
 
52
                                 char *to, uint32_t to_length,
 
53
                                 const CHARSET_INFO * const from_cs,
 
54
                                 const char *from, uint32_t from_length,
 
55
                                 uint32_t nchars,
 
56
                                 const char **well_formed_error_pos,
 
57
                                 const char **cannot_convert_error_pos,
 
58
                                 const char **from_end_pos);
 
59
 
 
60
 
 
61
class String
 
62
{
 
63
  char *Ptr;
 
64
  uint32_t str_length,Alloced_length;
 
65
  bool alloced;
 
66
  const CHARSET_INFO *str_charset;
 
67
 
 
68
public:
 
69
  String();
 
70
  String(uint32_t length_arg);
 
71
  String(const char *str, const CHARSET_INFO * const cs);
 
72
  String(const char *str, uint32_t len, const CHARSET_INFO * const cs);
 
73
  String(char *str, uint32_t len, const CHARSET_INFO * const cs);
 
74
  String(const String &str);
 
75
 
 
76
  static void *operator new(size_t size, memory::Root *mem_root);
 
77
  static void operator delete(void *, size_t)
 
78
  { }
 
79
  static void operator delete(void *, memory::Root *)
 
80
  { }
 
81
  ~String();
 
82
 
 
83
  inline void set_charset(const CHARSET_INFO * const charset_arg)
 
84
  { str_charset= charset_arg; }
 
85
  inline const CHARSET_INFO *charset() const { return str_charset; }
 
86
  inline uint32_t length() const { return str_length;}
 
87
  inline uint32_t alloced_length() const { return Alloced_length;}
 
88
  inline char& operator [] (uint32_t i) const { return Ptr[i]; }
 
89
  inline void length(uint32_t len) { str_length=len ; }
 
90
  inline bool is_empty() { return (str_length == 0); }
 
91
  inline void mark_as_const() { Alloced_length= 0;}
 
92
  inline char *ptr() { return Ptr; }
 
93
  inline const char *ptr() const { return Ptr; }
 
94
  inline char *c_ptr()
 
95
  {
 
96
    if (str_length == Alloced_length)
 
97
      (void) realloc(str_length);
 
98
    else
 
99
      Ptr[str_length]= 0;
 
100
 
 
101
    return Ptr;
 
102
  }
 
103
  inline char *c_ptr_quick()
 
104
  {
 
105
    if (Ptr && str_length < Alloced_length)
 
106
      Ptr[str_length]=0;
 
107
    return Ptr;
 
108
  }
 
109
  inline char *c_ptr_safe()
 
110
  {
 
111
    if (Ptr && str_length < Alloced_length)
 
112
      Ptr[str_length]=0;
 
113
    else
 
114
      (void) realloc(str_length);
 
115
    return Ptr;
 
116
  }
 
117
  inline char *c_str()
 
118
  {
 
119
    if (Ptr && str_length < Alloced_length)
 
120
      Ptr[str_length]=0;
 
121
    else
 
122
      (void) realloc(str_length);
 
123
    return Ptr;
 
124
  }
 
125
  void append_identifier(const char *name, uint32_t length);
 
126
 
 
127
  void set(String &str,uint32_t offset,uint32_t arg_length)
 
128
  {
 
129
    assert(&str != this);
 
130
    free();
 
131
    Ptr= str.ptr()+offset; str_length=arg_length; alloced=0;
 
132
    if (str.Alloced_length)
 
133
      Alloced_length=str.Alloced_length-offset;
 
134
    else
 
135
      Alloced_length=0;
 
136
    str_charset=str.str_charset;
 
137
  }
 
138
  inline void set(char *str,uint32_t arg_length, const CHARSET_INFO * const cs)
 
139
  {
 
140
    free();
 
141
    Ptr= str; str_length=Alloced_length=arg_length ; alloced=0;
 
142
    str_charset=cs;
 
143
  }
 
144
  inline void set(const char *str,uint32_t arg_length, const CHARSET_INFO * const cs)
 
145
  {
 
146
    free();
 
147
    Ptr= const_cast<char*>(str);
 
148
    str_length=arg_length; Alloced_length=0 ; alloced=0;
 
149
    str_charset=cs;
 
150
  }
 
151
  bool set_ascii(const char *str, uint32_t arg_length);
 
152
  inline void set_quick(char *str,uint32_t arg_length, const CHARSET_INFO * const cs)
 
153
  {
 
154
    if (!alloced)
 
155
    {
 
156
      Ptr= str; str_length= Alloced_length= arg_length;
 
157
    }
 
158
    str_charset= cs;
 
159
  }
 
160
  bool set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs);
 
161
  bool set(int64_t num, const CHARSET_INFO * const cs)
 
162
  { return set_int(num, false, cs); }
 
163
  bool set(uint64_t num, const CHARSET_INFO * const cs)
 
164
  { return set_int(static_cast<int64_t>(num), true, cs); }
 
165
  bool set_real(double num,uint32_t decimals, const CHARSET_INFO * const cs);
 
166
 
 
167
  /*
 
168
    PMG 2004.11.12
 
169
    This is a method that works the same as perl's "chop". It simply
 
170
    drops the last character of a string. This is useful in the case
 
171
    of the federated storage handler where I'm building a unknown
 
172
    number, list of values and fields to be used in a sql insert
 
173
    statement to be run on the remote server, and have a comma after each.
 
174
    When the list is complete, I "chop" off the trailing comma
 
175
 
 
176
    ex.
 
177
      String stringobj;
 
178
      stringobj.append("VALUES ('foo', 'fi', 'fo',");
 
179
      stringobj.chop();
 
180
      stringobj.append(")");
 
181
 
 
182
    In this case, the value of string was:
 
183
 
 
184
    VALUES ('foo', 'fi', 'fo',
 
185
    VALUES ('foo', 'fi', 'fo'
 
186
    VALUES ('foo', 'fi', 'fo')
 
187
 
 
188
  */
 
189
  inline void chop()
 
190
  {
 
191
    Ptr[str_length--]= '\0';
 
192
  }
 
193
 
 
194
  inline void free()
 
195
  {
 
196
    if (alloced)
 
197
    {
 
198
      alloced=0;
 
199
      Alloced_length=0;
 
200
      ::free(Ptr);
 
201
      Ptr=0;
 
202
      str_length=0;                             /* Safety */
 
203
    }
 
204
  }
 
205
  inline bool alloc(uint32_t arg_length)
 
206
  {
 
207
    if (arg_length < Alloced_length)
 
208
      return 0;
 
209
    return real_alloc(arg_length);
 
210
  }
 
211
  bool real_alloc(uint32_t arg_length);                 // Empties old string
 
212
  bool realloc(uint32_t arg_length);
 
213
  inline void shrink(uint32_t arg_length)               // Shrink buffer
 
214
  {
 
215
    if (arg_length < Alloced_length)
 
216
    {
 
217
      char *new_ptr;
 
218
      if (!(new_ptr= reinterpret_cast<char*>(::realloc(Ptr,arg_length))))
 
219
      {
 
220
        Alloced_length = 0;
 
221
        real_alloc(arg_length);
 
222
      }
 
223
      else
 
224
      {
 
225
        Ptr=new_ptr;
 
226
        Alloced_length=arg_length;
 
227
      }
 
228
    }
 
229
  }
 
230
  bool is_alloced() { return alloced; }
 
231
  inline String& operator = (const String &s)
 
232
  {
 
233
    if (&s != this)
 
234
    {
 
235
      /*
 
236
        It is forbidden to do assignments like
 
237
        some_string = substring_of_that_string
 
238
       */
 
239
      assert(!s.uses_buffer_owned_by(this));
 
240
      free();
 
241
      Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
 
242
      alloced=0;
 
243
    }
 
244
    return *this;
 
245
  }
 
246
 
 
247
  bool copy();                                  // Alloc string if not alloced
 
248
  bool copy(const String &s);                   // Allocate new string
 
249
  bool copy(const char *s,uint32_t arg_length, const CHARSET_INFO * const cs);  // Allocate new string
 
250
  static bool needs_conversion(uint32_t arg_length,
 
251
                               const CHARSET_INFO * const cs_from, const CHARSET_INFO * const cs_to,
 
252
                               uint32_t *offset);
 
253
  bool set_or_copy_aligned(const char *s, uint32_t arg_length, const CHARSET_INFO * const cs);
 
254
  bool copy(const char*s,uint32_t arg_length, const CHARSET_INFO * const csfrom,
 
255
            const CHARSET_INFO * const csto, uint32_t *errors);
 
256
  bool append(const String &s);
 
257
  bool append(const char *s);
 
258
  bool append(const char *s,uint32_t arg_length);
 
259
  bool append(const char *s,uint32_t arg_length, const CHARSET_INFO * const cs);
 
260
  bool append_with_prefill(const char *s, uint32_t arg_length,
 
261
                           uint32_t full_length, char fill_char);
 
262
  int strstr(const String &search,uint32_t offset=0); // Returns offset to substring or -1
 
263
  int strrstr(const String &search,uint32_t offset=0); // Returns offset to substring or -1
 
264
  bool replace(uint32_t offset,uint32_t arg_length,const char *to,uint32_t length);
 
265
  bool replace(uint32_t offset,uint32_t arg_length,const String &to);
 
266
  inline bool append(char chr)
 
267
  {
 
268
    if (str_length < Alloced_length)
 
269
    {
 
270
      Ptr[str_length++]=chr;
 
271
    }
 
272
    else
 
273
    {
 
274
      if (realloc(str_length+1))
 
275
        return 1;
 
276
      Ptr[str_length++]=chr;
 
277
    }
 
278
    return 0;
 
279
  }
 
280
  friend int sortcmp(const String *a,const String *b, const CHARSET_INFO * const cs);
 
281
  friend int stringcmp(const String *a,const String *b);
 
282
  friend String *copy_if_not_alloced(String *a,String *b,uint32_t arg_length);
 
283
  uint32_t numchars();
 
284
  int charpos(int i,uint32_t offset=0);
 
285
 
 
286
  int reserve(uint32_t space_needed)
 
287
  {
 
288
    return realloc(str_length + space_needed);
 
289
  }
 
290
  int reserve(uint32_t space_needed, uint32_t grow_by);
 
291
 
 
292
  /*
 
293
    The following append operations do NOT check alloced memory
 
294
    q_*** methods writes values of parameters itself
 
295
    qs_*** methods writes string representation of value
 
296
  */
 
297
  void q_append(const char c);
 
298
  void q_append(const uint32_t n);
 
299
  void q_append(double d);
 
300
  void q_append(double *d);
 
301
  void q_append(const char *data, uint32_t data_len);
 
302
  void write_at_position(int position, uint32_t value);
 
303
 
 
304
  /* Inline (general) functions used by the protocol functions */
 
305
 
 
306
  inline char *prep_append(uint32_t arg_length, uint32_t step_alloc)
 
307
  {
 
308
    uint32_t new_length= arg_length + str_length;
 
309
    if (new_length > Alloced_length)
 
310
    {
 
311
      if (realloc(new_length + step_alloc))
 
312
        return 0;
 
313
    }
 
314
    uint32_t old_length= str_length;
 
315
    str_length+= arg_length;
 
316
    return Ptr+ old_length;                     /* Area to use */
 
317
  }
 
318
 
 
319
  inline bool append(const char *s, uint32_t arg_length, uint32_t step_alloc)
 
320
  {
 
321
    uint32_t new_length= arg_length + str_length;
 
322
    if (new_length > Alloced_length && realloc(new_length + step_alloc))
 
323
      return true;
 
324
    memcpy(Ptr+str_length, s, arg_length);
 
325
    str_length+= arg_length;
 
326
    return false;
 
327
  }
 
328
  void print(String *print);
 
329
 
 
330
  /* Swap two string objects. Efficient way to exchange data without memcpy. */
 
331
  void swap(String &s);
 
332
 
 
333
  inline bool uses_buffer_owned_by(const String *s) const
 
334
  {
 
335
    return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
 
336
  }
 
337
};
 
338
 
 
339
bool check_if_only_end_space(const CHARSET_INFO * const cs, char *str,
 
340
                             char *end);
 
341
 
 
342
} /* namespace drizzled */
 
343
 
 
344
bool operator==(const drizzled::String &s1, const drizzled::String &s2);
 
345
bool operator!=(const drizzled::String &s1, const drizzled::String &s2);
 
346
 
 
347
 
 
348
#endif /* DRIZZLED_SQL_STRING_H */