Drizzled Public API Documentation

size.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 MySQL
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; either version 2 of the License, or
00009  *  (at your option) any later version.
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 
00022 #include <config.h>
00023 #include <drizzled/field/size.h>
00024 #include <drizzled/error.h>
00025 #include <drizzled/table.h>
00026 #include <drizzled/session.h>
00027 #include <drizzled/internal/my_sys.h>
00028 
00029 #include <math.h>
00030 
00031 #include <algorithm>
00032 
00033 using namespace std;
00034 
00035 namespace drizzled
00036 {
00037 
00038 namespace field
00039 {
00040 
00041 /****************************************************************************
00042   Field type Size int (8 bytes)
00043  ****************************************************************************/
00044 
00045 Size::Size(unsigned char *ptr_arg, uint32_t len_arg,
00046            unsigned char *null_ptr_arg,
00047            unsigned char null_bit_arg,
00048            enum utype unireg_check_arg,
00049            const char *field_name_arg) :
00050   Field_num(ptr_arg,
00051             len_arg,
00052             null_ptr_arg,
00053             null_bit_arg,
00054             unireg_check_arg,
00055             field_name_arg,
00056             0, false, true)
00057 {
00058   flags|= UNSIGNED_FLAG;
00059 }
00060 
00061 Size::Size(uint32_t len_arg,bool maybe_null_arg,
00062            const char *field_name_arg,
00063            bool unsigned_arg) :
00064   Field_num((unsigned char*) 0,
00065             len_arg, maybe_null_arg ? (unsigned char*) "": 0,
00066             0,
00067             NONE,
00068             field_name_arg,
00069             0,
00070             0,
00071             unsigned_arg)
00072 {
00073   flags|= UNSIGNED_FLAG;
00074   assert(unsigned_arg);
00075 }
00076 
00077 int Size::store(const char *from,uint32_t len, const CHARSET_INFO * const cs)
00078 {
00079   int error= 0;
00080   char *end;
00081   uint64_t tmp;
00082 
00083   ASSERT_COLUMN_MARKED_FOR_WRITE;
00084 
00085   tmp= cs->cset->strntoull10rnd(cs, from, len, false, &end,&error);
00086   if (error == MY_ERRNO_ERANGE)
00087   {
00088     set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00089     error= 1;
00090   }
00091   else if (getTable()->in_use->count_cuted_fields && check_int(cs, from, len, end, error))
00092   {
00093     error= 1;
00094   }
00095   else
00096   {
00097     error= 0;
00098   }
00099 
00100   int64_tstore(ptr,tmp);
00101 
00102   return error;
00103 }
00104 
00105 
00106 int Size::store(double nr)
00107 {
00108   int error= 0;
00109   int64_t res;
00110 
00111   ASSERT_COLUMN_MARKED_FOR_WRITE;
00112 
00113   nr= rint(nr);
00114 
00115   if (nr <= (double) INT64_MIN)
00116   {
00117     res= INT64_MIN;
00118     error= (nr < (double) INT64_MIN);
00119   }
00120   else if (nr >= (double) (uint64_t) INT64_MAX)
00121   {
00122     res= INT64_MAX;
00123     error= (nr > (double) INT64_MAX);
00124   }
00125   else
00126   {
00127     res=(int64_t) nr;
00128   }
00129 
00130   if (error)
00131   {
00132     set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00133     return 0;
00134   }
00135 
00136   int64_tstore(ptr, res);
00137 
00138   return error;
00139 }
00140 
00141 
00142 int Size::store(int64_t nr, bool arg)
00143 {
00144   int error= 0;
00145 
00146   ASSERT_COLUMN_MARKED_FOR_WRITE;
00147 
00148   if (not arg and nr < 0)
00149   {
00150     set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00151     return 0;
00152   }
00153 
00154   int64_tstore(ptr,nr);
00155 
00156   return error;
00157 }
00158 
00159 
00160 double Size::val_real(void) const
00161 {
00162   int64_t j;
00163 
00164   ASSERT_COLUMN_MARKED_FOR_READ;
00165 
00166   int64_tget(j,ptr);
00167 
00168   return (double) j;
00169 }
00170 
00171 
00172 int64_t Size::val_int(void) const
00173 {
00174   int64_t j;
00175 
00176   ASSERT_COLUMN_MARKED_FOR_READ;
00177 
00178   int64_tget(j,ptr);
00179 
00180   return j;
00181 }
00182 
00183 
00184 String *Size::val_str(String *val_buffer, String *) const
00185 {
00186   const CHARSET_INFO * const cs= &my_charset_bin;
00187   uint32_t length;
00188   uint32_t mlength= max(field_length+1,22*cs->mbmaxlen);
00189   val_buffer->alloc(mlength);
00190   char *to=(char*) val_buffer->ptr();
00191   int64_t j;
00192 
00193   ASSERT_COLUMN_MARKED_FOR_READ;
00194 
00195   int64_tget(j,ptr);
00196 
00197   length=(uint32_t) (cs->cset->int64_t10_to_str)(cs,to,mlength, -10, j);
00198   val_buffer->length(length);
00199 
00200   return val_buffer;
00201 }
00202 
00203 int Size::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
00204 {
00205   int64_t a,b;
00206 
00207   int64_tget(a,a_ptr);
00208   int64_tget(b,b_ptr);
00209 
00210   return (a < b) ? -1 : (a > b) ? 1 : 0;
00211 }
00212 
00213 void Size::sort_string(unsigned char *to,uint32_t )
00214 {
00215 #ifdef WORDS_BIGENDIAN
00216   {
00217     to[0] = (char) (ptr[0] ^ 128);    /* Revers signbit */
00218     to[1]   = ptr[1];
00219     to[2]   = ptr[2];
00220     to[3]   = ptr[3];
00221     to[4]   = ptr[4];
00222     to[5]   = ptr[5];
00223     to[6]   = ptr[6];
00224     to[7]   = ptr[7];
00225   }
00226 #else
00227   {
00228     to[0] = (char) (ptr[7] ^ 128);    /* Revers signbit */
00229     to[1]   = ptr[6];
00230     to[2]   = ptr[5];
00231     to[3]   = ptr[4];
00232     to[4]   = ptr[3];
00233     to[5]   = ptr[2];
00234     to[6]   = ptr[1];
00235     to[7]   = ptr[0];
00236   }
00237 #endif
00238 }
00239 
00240 
00241 void Size::sql_type(String &res) const
00242 {
00243   const CHARSET_INFO * const cs=res.charset();
00244   res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), "unsigned integer"));
00245 }
00246 
00247 
00248 unsigned char *Size::pack(unsigned char* to, const unsigned char *from, uint32_t, bool)
00249 {
00250   int64_t val;
00251 
00252   int64_tget(val, from);
00253   int64_tstore(to, val);
00254 
00255   return to + sizeof(val);
00256 }
00257 
00258 
00259 const unsigned char *Size::unpack(unsigned char* to, const unsigned char *from, uint32_t, bool)
00260 {
00261   int64_t val;
00262 
00263   int64_tget(val, from);
00264   int64_tstore(to, val);
00265 
00266   return from + sizeof(val);
00267 }
00268 
00269 } /* namespace field */
00270 } /* namespace drizzled */