~drizzle-trunk/drizzle/development

574.3.5 by Lee
moving functions from item_strfunc to functions/str directory
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
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
20
#include "config.h"
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
21
670.1.20 by Monty Taylor
Renamed functions to function... everything else is singular.
22
#include <drizzled/function/str/trim.h>
574.3.5 by Lee
moving functions from item_strfunc to functions/str directory
23
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
24
namespace drizzled
25
{
26
574.3.5 by Lee
moving functions from item_strfunc to functions/str directory
27
String *Item_func_ltrim::val_str(String *str)
28
{
29
  assert(fixed == 1);
30
  char buff[MAX_FIELD_WIDTH], *ptr, *end;
31
  String tmp(buff,sizeof(buff),system_charset_info);
32
  String *res, *remove_str;
33
  uint32_t remove_length;
34
35
  res= args[0]->val_str(str);
36
  if ((null_value=args[0]->null_value))
37
    return 0;
38
  remove_str= &remove;                          /* Default value. */
39
  if (arg_count == 2)
40
  {
41
    remove_str= args[1]->val_str(&tmp);
42
    if ((null_value= args[1]->null_value))
43
      return 0;
44
  }
45
46
  if ((remove_length= remove_str->length()) == 0 ||
47
      remove_length > res->length())
48
    return res;
49
50
  ptr= (char*) res->ptr();
51
  end= ptr+res->length();
52
  if (remove_length == 1)
53
  {
54
    char chr=(*remove_str)[0];
55
    while (ptr != end && *ptr == chr)
56
      ptr++;
57
  }
58
  else
59
  {
60
    const char *r_ptr=remove_str->ptr();
61
    end-=remove_length;
62
    while (ptr <= end && !memcmp(ptr, r_ptr, remove_length))
63
      ptr+=remove_length;
64
    end+=remove_length;
65
  }
66
  if (ptr == res->ptr())
67
    return res;
68
  tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
69
  return &tmp_value;
70
}
71
72
String *Item_func_rtrim::val_str(String *str)
73
{
74
  assert(fixed == 1);
75
  char buff[MAX_FIELD_WIDTH], *ptr, *end;
76
  String tmp(buff, sizeof(buff), system_charset_info);
77
  String *res, *remove_str;
78
  uint32_t remove_length;
79
80
  res= args[0]->val_str(str);
81
  if ((null_value=args[0]->null_value))
82
    return 0;
83
  remove_str= &remove;                          /* Default value. */
84
  if (arg_count == 2)
85
  {
86
    remove_str= args[1]->val_str(&tmp);
87
    if ((null_value= args[1]->null_value))
88
      return 0;
89
  }
90
91
  if ((remove_length= remove_str->length()) == 0 ||
92
      remove_length > res->length())
93
    return res;
94
95
  ptr= (char*) res->ptr();
96
  end= ptr+res->length();
97
  char *p=ptr;
98
  register uint32_t l;
99
  if (remove_length == 1)
100
  {
101
    char chr=(*remove_str)[0];
102
    if (use_mb(res->charset()))
103
    {
104
      while (ptr < end)
105
      {
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
106
        if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l,p=ptr;
107
        else ++ptr;
574.3.5 by Lee
moving functions from item_strfunc to functions/str directory
108
      }
109
      ptr=p;
110
    }
111
    while (ptr != end  && end[-1] == chr)
112
      end--;
113
  }
114
  else
115
  {
116
    const char *r_ptr=remove_str->ptr();
117
    if (use_mb(res->charset()))
118
    {
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
119
loop:
574.3.5 by Lee
moving functions from item_strfunc to functions/str directory
120
      while (ptr + remove_length < end)
121
      {
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
122
        if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
123
        else ++ptr;
574.3.5 by Lee
moving functions from item_strfunc to functions/str directory
124
      }
125
      if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
126
      {
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
127
        end-=remove_length;
128
        ptr=p;
129
        goto loop;
574.3.5 by Lee
moving functions from item_strfunc to functions/str directory
130
      }
131
    }
132
    else
133
    {
134
      while (ptr + remove_length <= end &&
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
135
          !memcmp(end-remove_length, r_ptr, remove_length))
136
        end-=remove_length;
574.3.5 by Lee
moving functions from item_strfunc to functions/str directory
137
    }
138
  }
139
  if (end == res->ptr()+res->length())
140
    return res;
141
  tmp_value.set(*res,0,(uint) (end-res->ptr()));
142
  return &tmp_value;
143
}
144
145
146
String *Item_func_trim::val_str(String *str)
147
{
148
  assert(fixed == 1);
149
  char buff[MAX_FIELD_WIDTH], *ptr, *end;
150
  const char *r_ptr;
151
  String tmp(buff, sizeof(buff), system_charset_info);
152
  String *res, *remove_str;
153
  uint32_t remove_length;
154
155
  res= args[0]->val_str(str);
156
  if ((null_value=args[0]->null_value))
157
    return 0;
158
  remove_str= &remove;                          /* Default value. */
159
  if (arg_count == 2)
160
  {
161
    remove_str= args[1]->val_str(&tmp);
162
    if ((null_value= args[1]->null_value))
163
      return 0;
164
  }
165
166
  if ((remove_length= remove_str->length()) == 0 ||
167
      remove_length > res->length())
168
    return res;
169
170
  ptr= (char*) res->ptr();
171
  end= ptr+res->length();
172
  r_ptr= remove_str->ptr();
173
  while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
174
    ptr+=remove_length;
175
  if (use_mb(res->charset()))
176
  {
177
    char *p=ptr;
178
    register uint32_t l;
179
 loop:
180
    while (ptr + remove_length < end)
181
    {
182
      if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
183
      else ++ptr;
184
    }
185
    if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
186
    {
187
      end-=remove_length;
188
      ptr=p;
189
      goto loop;
190
    }
191
    ptr=p;
192
  }
193
  else
194
  {
195
    while (ptr + remove_length <= end &&
196
	   !memcmp(end-remove_length,r_ptr,remove_length))
197
      end-=remove_length;
198
  }
199
  if (ptr == res->ptr() && end == ptr+res->length())
200
    return res;
201
  tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
202
  return &tmp_value;
203
}
204
205
void Item_func_trim::fix_length_and_dec()
206
{
207
  max_length= args[0]->max_length;
208
  if (arg_count == 1)
209
  {
210
    collation.set(args[0]->collation);
211
    remove.set_charset(collation.collation);
212
    remove.set_ascii(" ",1);
213
  }
214
  else
215
  {
216
    // Handle character set for args[1] and args[0].
217
    // Note that we pass args[1] as the first item, and args[0] as the second.
218
    if (agg_arg_charsets(collation, &args[1], 2, MY_COLL_CMP_CONV, -1))
219
      return;
220
  }
221
}
222
223
void Item_func_trim::print(String *str, enum_query_type query_type)
224
{
225
  if (arg_count == 1)
226
  {
227
    Item_func::print(str, query_type);
228
    return;
229
  }
230
  str->append(Item_func_trim::func_name());
231
  str->append('(');
232
  str->append(mode_name());
233
  str->append(' ');
234
  args[1]->print(str, query_type);
235
  str->append(STRING_WITH_LEN(" from "));
236
  args[0]->print(str, query_type);
237
  str->append(')');
238
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
239
240
} /* namespace drizzled */