Drizzled Public API Documentation

reverse_function.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  *  Copyright (C) 2010 Stewart Smith
00006  *
00007  *  This program is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; version 2 of the License.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #include <config.h>
00022 
00023 #include <drizzled/plugin/function.h>
00024 #include <drizzled/function/str/strfunc.h>
00025 #include <drizzled/charset_info.h>
00026 
00027 using namespace drizzled;
00028 
00029 class ReverseFunction :public Item_str_func
00030 {
00031   String tmp_value;
00032 public:
00033   ReverseFunction() :Item_str_func() {}
00034   String *val_str(String *);
00035   void fix_length_and_dec();
00036   const char *func_name() const { return "reverse"; }
00037 
00038   bool check_argument_count(int n)
00039   {
00040     return n == 1;
00041   }
00042 };
00043 
00044 String *ReverseFunction::val_str(String *str)
00045 {
00046   assert(fixed == 1);
00047   String *res = args[0]->val_str(str);
00048   char *ptr, *end, *tmp;
00049 
00050   if ((null_value=args[0]->null_value))
00051     return 0;
00052   /* An empty string is a special case as the string pointer may be null */
00053   if (!res->length())
00054     return &my_empty_string;
00055   if (tmp_value.alloced_length() < res->length() &&
00056       tmp_value.realloc(res->length()))
00057   {
00058     null_value= 1;
00059     return 0;
00060   }
00061   tmp_value.length(res->length());
00062   tmp_value.set_charset(res->charset());
00063   ptr= (char *) res->ptr();
00064   end= ptr + res->length();
00065   tmp= (char *) tmp_value.ptr() + tmp_value.length();
00066   if (use_mb(res->charset()))
00067   {
00068     register uint32_t l;
00069     while (ptr < end)
00070     {
00071       if ((l= my_ismbchar(res->charset(),ptr,end)))
00072       {
00073         tmp-= l;
00074         memcpy(tmp,ptr,l);
00075         ptr+= l;
00076       }
00077       else
00078         *--tmp= *ptr++;
00079     }
00080   }
00081   else
00082   {
00083     while (ptr < end)
00084       *--tmp= *ptr++;
00085   }
00086   return &tmp_value;
00087 }
00088 
00089 void ReverseFunction::fix_length_and_dec()
00090 {
00091   collation.set(args[0]->collation);
00092   max_length = args[0]->max_length;
00093 }
00094 
00095 plugin::Create_function<ReverseFunction> *reverse_function= NULL;
00096 
00097 static int initialize(drizzled::module::Context &context)
00098 {
00099   reverse_function= new plugin::Create_function<ReverseFunction>("reverse");
00100   context.add(reverse_function);
00101   return 0;
00102 }
00103 
00104 DRIZZLE_DECLARE_PLUGIN
00105 {
00106   DRIZZLE_VERSION_ID,
00107   "reverse_function",
00108   "1.0",
00109   "Stewart Smith",
00110   "reverses a string",
00111   PLUGIN_LICENSE_GPL,
00112   initialize, /* Plugin Init */
00113   NULL,   /* depends */
00114   NULL    /* config options */
00115 }
00116 DRIZZLE_DECLARE_PLUGIN_END;