Drizzled Public API Documentation

trim.cc
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, Inc.
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 #include <config.h>
21 
22 #include <drizzled/function/str/trim.h>
23 
24 namespace drizzled
25 {
26 
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 
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  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  {
106  if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l,p=ptr;
107  else ++ptr;
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  {
119 loop:
120  while (ptr + remove_length < end)
121  {
122  if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
123  else ++ptr;
124  }
125  if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
126  {
127  end-=remove_length;
128  ptr=p;
129  goto loop;
130  }
131  }
132  else
133  {
134  while (ptr + remove_length <= end &&
135  !memcmp(end-remove_length, r_ptr, remove_length))
136  end-=remove_length;
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 
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  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 
224 {
225  if (arg_count == 1)
226  {
227  Item_func::print(str);
228  return;
229  }
230  str->append(Item_func_trim::func_name(), strlen(Item_func_trim::func_name()));
231  str->append('(');
232  str->append(mode_name(), strlen(mode_name()));
233  str->append(' ');
234  args[1]->print(str);
235  str->append(STRING_WITH_LEN(" from "));
236  args[0]->print(str);
237  str->append(')');
238 }
239 
240 } /* namespace drizzled */