2014-01-21 19 views
0

我正在嘗試爲MySQL創建2個UDF,這些UDF將壓縮和解壓縮數據,以便將其存儲在數據庫中。從這個網站,我已經創建了一個成功的壓縮功能,然後在鄉親們一些幫助解壓縮數據:zlib和MySQL UDFs

#include "string.h" 
#include "stdio.h" 
#include "mysql/mysql.h" 
#include "zlib.h" 
#include "stdlib.h" 

int main() 
{ 


const char *istream = "test sentence"; 
ulong srcLen = strlen(istream)+1; 
ulong destLen = compressBound(srcLen); 
char* ostream = malloc(destLen); 
int res = compress(ostream, &destLen, istream, srcLen); 
if (res == Z_OK) printf("%s\n", ostream); 
else printf("%i", res); 


const char *data = ostream; 
ulong size = strlen(data) + 1; 
char *ret = malloc(size); 
unsigned long new_size; 

int rez; 
//int i = 0; 
int sz = 8*size; 
new_size = sz = sz + 8 - (sz % 8); 
for(;;) 
{ 
    //fprintf(stderr,"%d[u]: %d\n",++i,(int)sz); 
     ret = realloc(ret,sz); 
     rez = uncompress(ret, &new_size, data, new_size); 
     if(Z_BUF_ERROR == rez){ 
     sz*=2; 
     new_size = sz; 
     continue; 
    } 
    break; 
} 
if(Z_OK==rez){ 
ret = realloc(ret,new_size + 8 - (new_size % 8)); 
printf("%s\n", ret); 
} 
else printf("%i", rez); 



return 0; 
} 

它的工作原理就像一個魅力,所以後來我試圖重建它在2個UDF的MySQL的形式。 壓縮功能:

#include "string.h" 
#include "stdio.h" 
#include "mysql/mysql.h" 
#include "zlib.h" 
#include "stdlib.h" 
my_bool CompFunc_init(UDF_INIT *initid, UDF_ARGS *args, char *msg) 
{ 
if (args->arg_count != 1) 
{ 
    memcpy(msg, "Missing message argument.", 26); 
    return 1; 
} 
if (args->arg_type[0] != STRING_RESULT) 
{ 
    args->arg_type = STRING_RESULT; 
} 
initid->ptr = malloc(compressBound(strlen(args->args[0])) + 1); 
return 0; 
} 
char *CompFunc(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, my_bool *is_null, my_bool *error) 
{ 
const char *istream = args->args[0]; 
ulong srcLen = strlen(istream)+1; 
ulong destLen = compressBound(srcLen); 
int res = compress(initid->ptr, &destLen, istream, srcLen); 
if (res == Z_OK) { 
    *length = destLen; 
    sprintf(result,"%s", initid->ptr); 
    return result; 
} 
else { sprintf(result, "%i", res); return result;} 
} 
void CompFunc_deinit(UDF_INIT *initid) 
{ 
free(initid->ptr); 
} 

解壓功能:

#include "string.h" 
#include "stdio.h" 
#include "mysql/mysql.h" 
#include "zlib.h" 
#include "stdlib.h" 

my_bool UCompFunc_init(UDF_INIT *initid, UDF_ARGS *args, char *msg) 
{ 
if (args->arg_count != 1) 
{ 
    memcpy(msg, "Missing message argument.", 26); 
    return 1; 
} 
if (args->arg_type[0] != STRING_RESULT) 
{ 
    args->arg_type = STRING_RESULT; 
} 
initid->ptr = malloc(strlen(args->args[0]) + 1); 
return 0; 
} 
char *UCompFunc(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, my_bool *is_null, my_bool *error) 
{ 
const char *data = args->args[0]; 
ulong size = strlen(data) + 1; 
unsigned long new_size; 

int rez; 
//int i = 0; 
int sz = 8*size; 
new_size = sz = sz + 8 - (sz % 8); 
for(;;) 
{ 
    //fprintf(stderr,"%d[u]: %d\n",++i,(int)sz); 
     initid->ptr = realloc(initid->ptr,sz); 
     rez = uncompress(initid->ptr, &new_size, data, new_size); 
     if(Z_BUF_ERROR == rez){ 
     sz*=2; 
     new_size = sz; 
     continue; 
    } 
    break; 
} 
if(Z_OK==rez) initid->ptr = realloc(initid->ptr,new_size + 8 - (new_size % 8)); 
else { sprintf(result, "%i", rez); return result;} 
*length = new_size; 
sprintf(result,"%s", initid->ptr); 
return result; 
} 
void UCompFunc_deinit(UDF_INIT *initid) 
{ 
free(initid->ptr); 
} 

壓縮UDF似乎能正常工作,但解壓UDF將不會返回解壓縮的文本,但Z_BUF_ERROR的錯誤,這意味着有輸入緩衝區有問題!有誰能指出我的錯誤嗎?

回答

0
  • 您不能使用strlen()來獲取壓縮數據的長度。它不會被零終止,而且很可能在其中包含零。即使壓縮數據很長,strlen()的結果也可能是非常小的數字。壓縮數據的長度在compress()的第二個參數中返回。你應該使用它。
  • 經過sz = 8*whatever,您可以放心,sz % 8爲零。
  • 重新分配輸出緩衝區並每次重試整個解壓縮都是浪費時間。您應該使用inflateInit(),inflate()inflateEnd()函數,以便儘可能多地解壓縮到可用緩衝區中,然後重新分配。
  • 更好的辦法是將未壓縮的長度與壓縮數據一起發送,這樣你只需要進行一次分配。
  • uncompress()的第四個參數必須是壓縮數據的長度。不重複輸出緩衝區的長度。
  • 如果返回uncompress(),您仍然處於無限循環中,您如何返回Z_BUF_ERROR

底線:根據文檔使用uncompress()