Drizzled Public API Documentation

hex_functions.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/charset.h>
23 #include <drizzled/function/str/strfunc.h>
24 #include <drizzled/internal/m_string.h>
25 #include <drizzled/plugin/function.h>
26 #include <drizzled/util/convert.h>
27 
28 using namespace drizzled;
29 
31 {
32  String tmp_value;
33 public:
35  const char *func_name() const { return "hex"; }
36  String *val_str(String *);
37  void fix_length_and_dec()
38  {
39  collation.set(default_charset());
40  decimals=0;
41  max_length=args[0]->max_length*2*collation.collation->mbmaxlen;
42  }
43 
44  bool check_argument_count(int n) { return n == 1; }
45 };
46 
48 {
49  String tmp_value;
50 public:
52  {
53  /* there can be bad hex strings */
54  maybe_null= 1;
55  }
56  const char *func_name() const { return "unhex"; }
57  String *val_str(String *);
58  void fix_length_and_dec()
59  {
60  collation.set(&my_charset_bin);
61  decimals=0;
62  max_length=(1+args[0]->max_length)/2;
63  }
64  bool check_argument_count(int n) { return n == 1; }
65 };
66 
70 static int hexchar_to_int(char c)
71 {
72  if (c <= '9' && c >= '0')
73  return c-'0';
74  c|=32;
75  if (c <= 'f' && c >= 'a')
76  return c-'a'+10;
77  return -1;
78 }
79 
81 {
82  String *res;
83  assert(fixed == 1);
84  if (args[0]->result_type() != STRING_RESULT)
85  {
86  uint64_t dec;
87  char ans[65],*ptr;
88  /* Return hex of unsigned int64_t value */
89  if (args[0]->result_type() == REAL_RESULT ||
90  args[0]->result_type() == DECIMAL_RESULT)
91  {
92  double val= args[0]->val_real();
93  if ((val <= (double) INT64_MIN) ||
94  (val >= (double) (uint64_t) UINT64_MAX))
95  dec= ~(int64_t) 0;
96  else
97  dec= (uint64_t) (val + (val > 0 ? 0.5 : -0.5));
98  }
99  else
100  dec= (uint64_t) args[0]->val_int();
101 
102  if ((null_value= args[0]->null_value))
103  return 0;
104  ptr= internal::int64_t2str(dec,ans,16);
105  str->copy(ans,(uint32_t) (ptr-ans),default_charset());
106  return str;
107  }
108 
109  /* Convert given string to a hex string, character by character */
110  res= args[0]->val_str(str);
111  if (!res)
112  {
113  null_value=1;
114  return 0;
115  }
116  null_value=0;
117  tmp_value.alloc(res->length()*2+1);
118  tmp_value.length(res->length()*2);
119 
120  (void) drizzled_string_to_hex((char*) tmp_value.ptr(), res->ptr(),
121  res->length());
122  return &tmp_value;
123 }
124 
128 {
129  const char *from, *end;
130  char *to;
131  String *res;
132  uint32_t length;
133  assert(fixed == 1);
134 
135  res= args[0]->val_str(str);
136  if (!res)
137  {
138  null_value=1;
139  return 0;
140  }
141  tmp_value.alloc(length= (1+res->length())/2);
142 
143  from= res->ptr();
144  null_value= 0;
145  tmp_value.length(length);
146  to= (char*) tmp_value.ptr();
147  if (res->length() % 2)
148  {
149  int hex_char;
150  *to++= hex_char= hexchar_to_int(*from++);
151  if ((null_value= (hex_char == -1)))
152  return 0;
153  }
154  for (end=res->ptr()+res->length(); from < end ; from+=2, to++)
155  {
156  int hex_char;
157  *to= (hex_char= hexchar_to_int(from[0])) << 4;
158  if ((null_value= (hex_char == -1)))
159  return 0;
160  *to|= hex_char= hexchar_to_int(from[1]);
161  if ((null_value= (hex_char == -1)))
162  return 0;
163  }
164  return &tmp_value;
165 }
166 
167 plugin::Create_function<HexFunction> *hex_function= NULL;
168 plugin::Create_function<UnHexFunction> *unhex_function= NULL;
169 
170 static int initialize(drizzled::module::Context &context)
171 {
172  hex_function= new plugin::Create_function<HexFunction>("hex");
173  unhex_function= new plugin::Create_function<UnHexFunction>("unhex");
174  context.add(hex_function);
175  context.add(unhex_function);
176  return 0;
177 }
178 
179 DRIZZLE_DECLARE_PLUGIN
180 {
181  DRIZZLE_VERSION_ID,
182  "hex_functions",
183  "1.0",
184  "Stewart Smith",
185  N_("HEX and UNHEX functions"),
186  PLUGIN_LICENSE_GPL,
187  initialize,
188  NULL,
189  NULL
190 }
191 DRIZZLE_DECLARE_PLUGIN_END;
TODO: Rename this file - func.h is stupid.
bool check_argument_count(int n)
bool check_argument_count(int n)
String * val_str(String *)
String * val_str(String *)