00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <drizzled/error.h>
00023 #include <drizzled/function/str/strfunc.h>
00024 #include <drizzled/session.h>
00025
00026 #include <plugin/compression/uncompress.h>
00027
00028 #include <zlib.h>
00029 #include <string>
00030
00031 using namespace std;
00032 using namespace drizzled;
00033
00034 String *Item_func_uncompress::val_str(String *str)
00035 {
00036 assert(fixed == 1);
00037 String *res= args[0]->val_str(str);
00038 ulong new_size;
00039 int err;
00040 drizzled::error_t code;
00041
00042 if (!res)
00043 goto err;
00044 null_value= 0;
00045 if (res->is_empty())
00046 return res;
00047
00048
00049 if (res->length() <= 4)
00050 {
00051 push_warning_printf(&getSession(), DRIZZLE_ERROR::WARN_LEVEL_ERROR,
00052 ER_ZLIB_Z_DATA_ERROR,
00053 ER(ER_ZLIB_Z_DATA_ERROR));
00054 goto err;
00055 }
00056
00057
00058 new_size= uint4korr(res->ptr()) & 0x3FFFFFFF;
00059 if (new_size > getSession().variables.max_allowed_packet)
00060 {
00061 push_warning_printf(&getSession(), DRIZZLE_ERROR::WARN_LEVEL_ERROR,
00062 ER_TOO_BIG_FOR_UNCOMPRESS,
00063 ER(ER_TOO_BIG_FOR_UNCOMPRESS),
00064 getSession().variables.max_allowed_packet);
00065 goto err;
00066 }
00067
00068 if (buffer.realloc((uint32_t)new_size))
00069 goto err;
00070
00071 if ((err= uncompress((Byte*)buffer.ptr(), &new_size,
00072 ((const Bytef*)res->ptr())+4,res->length())) == Z_OK)
00073 {
00074 buffer.length((uint32_t) new_size);
00075 return &buffer;
00076 }
00077
00078 code= ((err == Z_BUF_ERROR) ? ER_ZLIB_Z_BUF_ERROR :
00079 ((err == Z_MEM_ERROR) ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_DATA_ERROR));
00080 push_warning(&getSession(), DRIZZLE_ERROR::WARN_LEVEL_ERROR, code, ER(code));
00081
00082 err:
00083 null_value= 1;
00084 return 0;
00085 }
00086