~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/compress/compressudf.cc

  • Committer: Stewart Smith
  • Date: 2009-01-12 05:43:13 UTC
  • mto: (784.1.4 for-brian)
  • mto: This revision was merged to the branch mainline in revision 785.
  • Revision ID: stewart@flamingspork.com-20090112054313-edk6kpf4l6kpz4j7
fix archive_basic for drizzle

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
15
 
 
16
#include <drizzled/server_includes.h>
 
17
#include <drizzled/sql_udf.h>
 
18
#include <drizzled/item/func.h>
 
19
#include <drizzled/function/str/strfunc.h>
 
20
#include <drizzled/error.h>
 
21
#include <drizzled/sql_error.h>
 
22
#include <drizzled/current_session.h>
 
23
#include <zlib.h>
 
24
 
 
25
class Item_func_compress: public Item_str_func
 
26
{
 
27
  String buffer;
 
28
public:
 
29
  Item_func_compress():Item_str_func(){}
 
30
  void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;}
 
31
  const char *func_name() const{return "compress";}
 
32
  String *val_str(String *) ;
 
33
};
 
34
 
 
35
String *Item_func_compress::val_str(String *str)
 
36
{
 
37
  int err= Z_OK, code;
 
38
  ulong new_size;
 
39
  String *res;
 
40
  Byte *body;
 
41
  char *tmp, *last_char;
 
42
  assert(fixed == 1);
 
43
 
 
44
  if (!(res= args[0]->val_str(str)))
 
45
  {
 
46
    null_value= 1;
 
47
    return 0;
 
48
  }
 
49
  null_value= 0;
 
50
  if (res->is_empty()) return res;
 
51
 
 
52
  /*
 
53
    Citation from zlib.h (comment for compress function):
 
54
 
 
55
    Compresses the source buffer into the destination buffer.  sourceLen is
 
56
    the byte length of the source buffer. Upon entry, destLen is the total
 
57
    size of the destination buffer, which must be at least 0.1% larger than
 
58
    sourceLen plus 12 bytes.
 
59
    We assume here that the buffer can't grow more than .25 %.
 
60
  */
 
61
  new_size= res->length() + res->length() / 5 + 12;
 
62
 
 
63
  // Check new_size overflow: new_size <= res->length()
 
64
  if (((uint32_t) (new_size+5) <= res->length()) ||
 
65
      buffer.realloc((uint32_t) new_size + 4 + 1))
 
66
  {
 
67
    null_value= 1;
 
68
    return 0;
 
69
  }
 
70
 
 
71
  body= ((Byte*)buffer.ptr()) + 4;
 
72
 
 
73
  // As far as we have checked res->is_empty() we can use ptr()
 
74
  if ((err= compress(body, &new_size,
 
75
                     (const Bytef*)res->ptr(), res->length())) != Z_OK)
 
76
  {
 
77
    code= err==Z_MEM_ERROR ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_BUF_ERROR;
 
78
    push_warning(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
79
                 code, ER(code));
 
80
    null_value= 1;
 
81
    return 0;
 
82
  }
 
83
 
 
84
  tmp= (char*)buffer.ptr(); // int4store is a macro; avoid side effects
 
85
  int4store(tmp, res->length() & 0x3FFFFFFF);
 
86
 
 
87
  /* This is to ensure that things works for CHAR fields, which trim ' ': */
 
88
  last_char= ((char*)body)+new_size-1;
 
89
  if (*last_char == ' ')
 
90
  {
 
91
    *++last_char= '.';
 
92
    new_size++;
 
93
  }
 
94
 
 
95
  buffer.length((uint32_t)new_size + 4);
 
96
  return &buffer;
 
97
}
 
98
 
 
99
 
 
100
Item_func* create_compressudf_item(MEM_ROOT* m)
 
101
{
 
102
  return  new (m) Item_func_compress();
 
103
}
 
104
 
 
105
static struct udf_func compressudf = {
 
106
  { C_STRING_WITH_LEN("compress") },
 
107
  create_compressudf_item
 
108
};
 
109
 
 
110
static int compressudf_plugin_init(void *p)
 
111
{
 
112
  udf_func **f = (udf_func**) p;
 
113
 
 
114
  *f= &compressudf;
 
115
 
 
116
  return 0;
 
117
}
 
118
 
 
119
static int compressudf_plugin_deinit(void *p)
 
120
{
 
121
  udf_func *udff = (udf_func *) p;
 
122
  (void)udff;
 
123
  return 0;
 
124
}
 
125
 
 
126
mysql_declare_plugin(compress)
 
127
{
 
128
  DRIZZLE_UDF_PLUGIN,
 
129
  "compress",
 
130
  "1.0",
 
131
  "Stewart Smith",
 
132
  "UDF for compress()",
 
133
  PLUGIN_LICENSE_GPL,
 
134
  compressudf_plugin_init, /* Plugin Init */
 
135
  compressudf_plugin_deinit, /* Plugin Deinit */
 
136
  NULL,   /* status variables */
 
137
  NULL,   /* system variables */
 
138
  NULL    /* config options */
 
139
}
 
140
mysql_declare_plugin_end;