Drizzled Public API Documentation

trim.cc

00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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;                          /* Default value. */
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;                          /* Default value. */
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;                          /* Default value. */
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     // Handle character set for args[1] and args[0].
00217     // Note that we pass args[1] as the first item, and args[0] as the second.
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 } /* namespace drizzled */