00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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,
00113 NULL,
00114 NULL
00115 }
00116 DRIZZLE_DECLARE_PLUGIN_END;