~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/my_decimal.h

  • Committer: Monty Taylor
  • Date: 2008-09-15 17:24:04 UTC
  • Revision ID: monty@inaugust.com-20080915172404-ygh6hiyu0q7qpa9x
Removed strndup calls.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
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
 
 */
 
1
/* Copyright (C) 2005-2006 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
19
15
 
20
16
/**
21
17
  @file
22
18
 
23
19
  It is interface module to fixed precision decimals library.
24
20
 
25
 
  Most functions use 'uint32_t mask' as parameter, if during operation error
 
21
  Most functions use 'uint mask' as parameter, if during operation error
26
22
  which fit in this mask is detected then it will be processed automatically
27
23
  here. (errors are E_DEC_* constants, see include/decimal.h)
28
24
 
32
28
#ifndef my_decimal_h
33
29
#define my_decimal_h
34
30
 
35
 
#ifdef __cplusplus
36
 
extern "C" {
37
 
#endif
38
 
 
 
31
C_MODE_START
39
32
#include <mystrings/decimal.h>
40
 
#include <mysys/my_time.h>
41
 
 
42
 
#ifdef __cplusplus
43
 
}
44
 
#endif
45
 
 
 
33
C_MODE_END
46
34
 
47
35
#define DECIMAL_LONGLONG_DIGITS 22
48
36
#define DECIMAL_LONG_DIGITS 10
77
65
#define DECIMAL_MAX_FIELD_SIZE DECIMAL_MAX_PRECISION
78
66
 
79
67
 
80
 
inline uint32_t my_decimal_size(uint32_t precision, uint32_t scale)
 
68
inline uint my_decimal_size(uint precision, uint scale)
81
69
{
82
70
  /*
83
71
    Always allocate more space to allow library to put decimal point
87
75
}
88
76
 
89
77
 
90
 
inline int my_decimal_int_part(uint32_t precision, uint32_t decimals)
 
78
inline int my_decimal_int_part(uint precision, uint decimals)
91
79
{
92
80
  return precision - ((decimals == DECIMAL_NOT_SPECIFIED) ? 0 : decimals);
93
81
}
113
101
    buf= buffer;
114
102
#if !defined (HAVE_purify) 
115
103
    /* Set buffer to 'random' value to find wrong buffer usage */
116
 
    for (uint32_t i= 0; i < DECIMAL_BUFF_LENGTH; i++)
 
104
    for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++)
117
105
      buffer[i]= i;
118
106
#endif
119
107
  }
125
113
 
126
114
  bool sign() const { return decimal_t::sign; }
127
115
  void sign(bool s) { decimal_t::sign= s; }
128
 
  uint32_t precision() const { return intg + frac; }
 
116
  uint precision() const { return intg + frac; }
129
117
};
130
118
 
 
119
#ifndef DRIZZLE_CLIENT
131
120
int decimal_operation_results(int result);
 
121
#else
 
122
inline int decimal_operation_results(int result)
 
123
{
 
124
  return result;
 
125
}
 
126
#endif /*DRIZZLE_CLIENT*/
132
127
 
133
128
inline
134
129
void max_my_decimal(my_decimal *to, int precision, int frac)
143
138
  max_my_decimal(to, DECIMAL_MAX_PRECISION, 0);
144
139
}
145
140
 
146
 
inline int check_result(uint32_t mask, int result)
 
141
inline int check_result(uint mask, int result)
147
142
{
148
143
  if (result & mask)
149
144
    decimal_operation_results(result);
150
145
  return result;
151
146
}
152
147
 
153
 
inline int check_result_and_overflow(uint32_t mask, int result, my_decimal *val)
 
148
inline int check_result_and_overflow(uint mask, int result, my_decimal *val)
154
149
{
155
150
  if (check_result(mask, result) & E_DEC_OVERFLOW)
156
151
  {
162
157
  return result;
163
158
}
164
159
 
165
 
inline uint32_t my_decimal_length_to_precision(uint32_t length, uint32_t scale,
 
160
inline uint my_decimal_length_to_precision(uint length, uint scale,
166
161
                                           bool unsigned_flag)
167
162
{
168
163
  return (uint) (length - (scale>0 ? 1:0) - (unsigned_flag ? 0:1));
169
164
}
170
165
 
171
 
inline uint32_t my_decimal_precision_to_length(uint32_t precision, uint8_t scale,
 
166
inline uint32_t my_decimal_precision_to_length(uint precision, uint8_t scale,
172
167
                                             bool unsigned_flag)
173
168
{
174
169
  set_if_smaller(precision, DECIMAL_MAX_PRECISION);
191
186
 
192
187
 
193
188
inline
194
 
int my_decimal_get_binary_size(uint32_t precision, uint32_t scale)
 
189
int my_decimal_get_binary_size(uint precision, uint scale)
195
190
{
196
191
  return decimal_bin_size((int)precision, (int)scale);
197
192
}
205
200
}
206
201
 
207
202
 
208
 
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
 
203
int my_decimal2binary(uint mask, const my_decimal *d, uchar *bin, int prec,
209
204
                      int scale);
210
205
 
211
206
 
212
207
inline
213
 
int binary2my_decimal(uint32_t mask, const unsigned char *bin, my_decimal *d, int prec,
 
208
int binary2my_decimal(uint mask, const uchar *bin, my_decimal *d, int prec,
214
209
                      int scale)
215
210
{
216
211
  return check_result(mask, bin2decimal(bin, (decimal_t*) d, prec, scale));
233
228
 
234
229
 
235
230
inline
236
 
int my_decimal_round(uint32_t mask, const my_decimal *from, int scale,
 
231
int my_decimal_round(uint mask, const my_decimal *from, int scale,
237
232
                     bool truncate, my_decimal *to)
238
233
{
239
234
  return check_result(mask, decimal_round((decimal_t*) from, to, scale,
242
237
 
243
238
 
244
239
inline
245
 
int my_decimal_floor(uint32_t mask, const my_decimal *from, my_decimal *to)
 
240
int my_decimal_floor(uint mask, const my_decimal *from, my_decimal *to)
246
241
{
247
242
  return check_result(mask, decimal_round((decimal_t*) from, to, 0, FLOOR));
248
243
}
249
244
 
250
245
 
251
246
inline
252
 
int my_decimal_ceiling(uint32_t mask, const my_decimal *from, my_decimal *to)
 
247
int my_decimal_ceiling(uint mask, const my_decimal *from, my_decimal *to)
253
248
{
254
249
  return check_result(mask, decimal_round((decimal_t*) from, to, 0, CEILING));
255
250
}
256
251
 
257
252
 
258
 
int my_decimal2string(uint32_t mask, const my_decimal *d, uint32_t fixed_prec,
259
 
                      uint32_t fixed_dec, char filler, String *str);
 
253
#ifndef DRIZZLE_CLIENT
 
254
int my_decimal2string(uint mask, const my_decimal *d, uint fixed_prec,
 
255
                      uint fixed_dec, char filler, String *str);
 
256
#endif
260
257
 
261
258
inline
262
 
int my_decimal2int(uint32_t mask, const my_decimal *d, bool unsigned_flag,
 
259
int my_decimal2int(uint mask, const my_decimal *d, bool unsigned_flag,
263
260
                   int64_t *l)
264
261
{
265
262
  my_decimal rounded;
272
269
 
273
270
 
274
271
inline
275
 
int my_decimal2double(uint32_t mask __attribute__((unused)), 
 
272
int my_decimal2double(uint mask __attribute__((unused)), 
276
273
                      const my_decimal *d, double *result)
277
274
{
278
275
  /* No need to call check_result as this will always succeed */
281
278
 
282
279
 
283
280
inline
284
 
int str2my_decimal(uint32_t mask, char *str, my_decimal *d, char **end)
 
281
int str2my_decimal(uint mask, char *str, my_decimal *d, char **end)
285
282
{
286
283
  return check_result_and_overflow(mask, string2decimal(str,(decimal_t*)d,end),
287
284
                                   d);
288
285
}
289
286
 
290
287
 
291
 
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
 
288
int str2my_decimal(uint mask, const char *from, uint length,
292
289
                   const CHARSET_INFO * charset, my_decimal *decimal_value);
293
290
 
294
291
#if defined(DRIZZLE_SERVER)
295
292
inline
296
 
int string2my_decimal(uint32_t mask, const String *str, my_decimal *d)
 
293
int string2my_decimal(uint mask, const String *str, my_decimal *d)
297
294
{
298
295
  return str2my_decimal(mask, str->ptr(), str->length(), str->charset(), d);
299
296
}
305
302
#endif /*defined(DRIZZLE_SERVER) */
306
303
 
307
304
inline
308
 
int double2my_decimal(uint32_t mask, double val, my_decimal *d)
 
305
int double2my_decimal(uint mask, double val, my_decimal *d)
309
306
{
310
307
  return check_result_and_overflow(mask, double2decimal(val, (decimal_t*)d), d);
311
308
}
312
309
 
313
310
 
314
311
inline
315
 
int int2my_decimal(uint32_t mask, int64_t i, bool unsigned_flag, my_decimal *d)
 
312
int int2my_decimal(uint mask, int64_t i, bool unsigned_flag, my_decimal *d)
316
313
{
317
314
  return check_result(mask, (unsigned_flag ?
318
315
                             uint64_t2decimal((uint64_t)i, d) :
333
330
 
334
331
 
335
332
inline
336
 
int my_decimal_add(uint32_t mask, my_decimal *res, const my_decimal *a,
 
333
int my_decimal_add(uint mask, my_decimal *res, const my_decimal *a,
337
334
                   const my_decimal *b)
338
335
{
339
336
  return check_result_and_overflow(mask,
343
340
 
344
341
 
345
342
inline
346
 
int my_decimal_sub(uint32_t mask, my_decimal *res, const my_decimal *a,
 
343
int my_decimal_sub(uint mask, my_decimal *res, const my_decimal *a,
347
344
                   const my_decimal *b)
348
345
{
349
346
  return check_result_and_overflow(mask,
353
350
 
354
351
 
355
352
inline
356
 
int my_decimal_mul(uint32_t mask, my_decimal *res, const my_decimal *a,
 
353
int my_decimal_mul(uint mask, my_decimal *res, const my_decimal *a,
357
354
                   const my_decimal *b)
358
355
{
359
356
  return check_result_and_overflow(mask,
363
360
 
364
361
 
365
362
inline
366
 
int my_decimal_div(uint32_t mask, my_decimal *res, const my_decimal *a,
 
363
int my_decimal_div(uint mask, my_decimal *res, const my_decimal *a,
367
364
                   const my_decimal *b, int div_scale_inc)
368
365
{
369
366
  return check_result_and_overflow(mask,
374
371
 
375
372
 
376
373
inline
377
 
int my_decimal_mod(uint32_t mask, my_decimal *res, const my_decimal *a,
 
374
int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
378
375
                   const my_decimal *b)
379
376
{
380
377
  return check_result_and_overflow(mask,
401
398
}
402
399
 
403
400
 
404
 
void my_decimal_trim(uint32_t *precision, uint32_t *scale);
 
401
void my_decimal_trim(uint32_t *precision, uint *scale);
405
402
 
406
403
 
407
404
#endif /*my_decimal_h*/