00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <drizzled/function/str/trim.h>
00023
00024 namespace drizzled
00025 {
00026
00027 String *Item_func_ltrim::val_str(String *str)
00028 {
00029 assert(fixed == 1);
00030 char buff[MAX_FIELD_WIDTH], *ptr, *end;
00031 String tmp(buff,sizeof(buff),system_charset_info);
00032 String *res, *remove_str;
00033 uint32_t remove_length;
00034
00035 res= args[0]->val_str(str);
00036 if ((null_value=args[0]->null_value))
00037 return 0;
00038 remove_str= &remove;
00039 if (arg_count == 2)
00040 {
00041 remove_str= args[1]->val_str(&tmp);
00042 if ((null_value= args[1]->null_value))
00043 return 0;
00044 }
00045
00046 if ((remove_length= remove_str->length()) == 0 ||
00047 remove_length > res->length())
00048 return res;
00049
00050 ptr= (char*) res->ptr();
00051 end= ptr+res->length();
00052 if (remove_length == 1)
00053 {
00054 char chr=(*remove_str)[0];
00055 while (ptr != end && *ptr == chr)
00056 ptr++;
00057 }
00058 else
00059 {
00060 const char *r_ptr=remove_str->ptr();
00061 end-=remove_length;
00062 while (ptr <= end && !memcmp(ptr, r_ptr, remove_length))
00063 ptr+=remove_length;
00064 end+=remove_length;
00065 }
00066 if (ptr == res->ptr())
00067 return res;
00068 tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
00069 return &tmp_value;
00070 }
00071
00072 String *Item_func_rtrim::val_str(String *str)
00073 {
00074 assert(fixed == 1);
00075 char buff[MAX_FIELD_WIDTH], *ptr, *end;
00076 String tmp(buff, sizeof(buff), system_charset_info);
00077 String *res, *remove_str;
00078 uint32_t remove_length;
00079
00080 res= args[0]->val_str(str);
00081 if ((null_value=args[0]->null_value))
00082 return 0;
00083 remove_str= &remove;
00084 if (arg_count == 2)
00085 {
00086 remove_str= args[1]->val_str(&tmp);
00087 if ((null_value= args[1]->null_value))
00088 return 0;
00089 }
00090
00091 if ((remove_length= remove_str->length()) == 0 ||
00092 remove_length > res->length())
00093 return res;
00094
00095 ptr= (char*) res->ptr();
00096 end= ptr+res->length();
00097 char *p=ptr;
00098 uint32_t l;
00099 if (remove_length == 1)
00100 {
00101 char chr=(*remove_str)[0];
00102 if (use_mb(res->charset()))
00103 {
00104 while (ptr < end)
00105 {
00106 if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l,p=ptr;
00107 else ++ptr;
00108 }
00109 ptr=p;
00110 }
00111 while (ptr != end && end[-1] == chr)
00112 end--;
00113 }
00114 else
00115 {
00116 const char *r_ptr=remove_str->ptr();
00117 if (use_mb(res->charset()))
00118 {
00119 loop:
00120 while (ptr + remove_length < end)
00121 {
00122 if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
00123 else ++ptr;
00124 }
00125 if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
00126 {
00127 end-=remove_length;
00128 ptr=p;
00129 goto loop;
00130 }
00131 }
00132 else
00133 {
00134 while (ptr + remove_length <= end &&
00135 !memcmp(end-remove_length, r_ptr, remove_length))
00136 end-=remove_length;
00137 }
00138 }
00139 if (end == res->ptr()+res->length())
00140 return res;
00141 tmp_value.set(*res,0,(uint) (end-res->ptr()));
00142 return &tmp_value;
00143 }
00144
00145
00146 String *Item_func_trim::val_str(String *str)
00147 {
00148 assert(fixed == 1);
00149 char buff[MAX_FIELD_WIDTH], *ptr, *end;
00150 const char *r_ptr;
00151 String tmp(buff, sizeof(buff), system_charset_info);
00152 String *res, *remove_str;
00153 uint32_t remove_length;
00154
00155 res= args[0]->val_str(str);
00156 if ((null_value=args[0]->null_value))
00157 return 0;
00158 remove_str= &remove;
00159 if (arg_count == 2)
00160 {
00161 remove_str= args[1]->val_str(&tmp);
00162 if ((null_value= args[1]->null_value))
00163 return 0;
00164 }
00165
00166 if ((remove_length= remove_str->length()) == 0 ||
00167 remove_length > res->length())
00168 return res;
00169
00170 ptr= (char*) res->ptr();
00171 end= ptr+res->length();
00172 r_ptr= remove_str->ptr();
00173 while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
00174 ptr+=remove_length;
00175 if (use_mb(res->charset()))
00176 {
00177 char *p=ptr;
00178 uint32_t l;
00179 loop:
00180 while (ptr + remove_length < end)
00181 {
00182 if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
00183 else ++ptr;
00184 }
00185 if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
00186 {
00187 end-=remove_length;
00188 ptr=p;
00189 goto loop;
00190 }
00191 ptr=p;
00192 }
00193 else
00194 {
00195 while (ptr + remove_length <= end &&
00196 !memcmp(end-remove_length,r_ptr,remove_length))
00197 end-=remove_length;
00198 }
00199 if (ptr == res->ptr() && end == ptr+res->length())
00200 return res;
00201 tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
00202 return &tmp_value;
00203 }
00204
00205 void Item_func_trim::fix_length_and_dec()
00206 {
00207 max_length= args[0]->max_length;
00208 if (arg_count == 1)
00209 {
00210 collation.set(args[0]->collation);
00211 remove.set_charset(collation.collation);
00212 remove.set_ascii(" ",1);
00213 }
00214 else
00215 {
00216
00217
00218 if (agg_arg_charsets(collation, &args[1], 2, MY_COLL_CMP_CONV, -1))
00219 return;
00220 }
00221 }
00222
00223 void Item_func_trim::print(String *str)
00224 {
00225 if (arg_count == 1)
00226 {
00227 Item_func::print(str);
00228 return;
00229 }
00230 str->append(Item_func_trim::func_name());
00231 str->append('(');
00232 str->append(mode_name());
00233 str->append(' ');
00234 args[1]->print(str);
00235 str->append(STRING_WITH_LEN(" from "));
00236 args[0]->print(str);
00237 str->append(')');
00238 }
00239
00240 }