Drizzled Public API Documentation

uncompress.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/error.h>
23 #include <drizzled/function/str/strfunc.h>
24 #include <drizzled/session.h>
25 #include <drizzled/system_variables.h>
26 #include <plugin/compression/uncompress.h>
27 
28 #include <zlib.h>
29 #include <string>
30 
31 using namespace std;
32 using namespace drizzled;
33 
35 {
36  assert(fixed == 1);
37  String *res= args[0]->val_str(str);
38  ulong new_size;
39  int err;
40  drizzled::error_t code;
41 
42  if (!res)
43  goto err;
44  null_value= 0;
45  if (res->empty())
46  return res;
47 
48  /* If length is less than 4 bytes, data is corrupt */
49  if (res->length() <= 4)
50  {
51  push_warning_printf(&getSession(), DRIZZLE_ERROR::WARN_LEVEL_ERROR,
52  ER_ZLIB_Z_DATA_ERROR,
53  ER(ER_ZLIB_Z_DATA_ERROR));
54  goto err;
55  }
56 
57  /* Size of uncompressed data is stored as first 4 bytes of field */
58  new_size= uint4korr(res->ptr()) & 0x3FFFFFFF;
59  if (new_size > getSession().variables.max_allowed_packet)
60  {
61  push_warning_printf(&getSession(), DRIZZLE_ERROR::WARN_LEVEL_ERROR,
62  ER_TOO_BIG_FOR_UNCOMPRESS,
63  ER(ER_TOO_BIG_FOR_UNCOMPRESS),
64  getSession().variables.max_allowed_packet);
65  goto err;
66  }
67 
68  buffer.realloc(new_size);
69 
70  if ((err= uncompress((Byte*)buffer.ptr(), &new_size,
71  ((const Bytef*)res->ptr())+4,res->length())) == Z_OK)
72  {
73  buffer.length((uint32_t) new_size);
74  return &buffer;
75  }
76 
77  code= ((err == Z_BUF_ERROR) ? ER_ZLIB_Z_BUF_ERROR :
78  ((err == Z_MEM_ERROR) ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_DATA_ERROR));
79  push_warning(&getSession(), DRIZZLE_ERROR::WARN_LEVEL_ERROR, code, ER(code));
80 
81 err:
82  null_value= 1;
83  return 0;
84 }
85