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