使用zlib压缩解压并导出lua接口

来源:互联网 发布:iphone效果器软件 编辑:程序博客网 时间:2024/06/05 21:14


网络游戏在前后端交换的过程中,有可能会有大量的数据,比如说游戏回放功能,这时最好是将数据压缩一下。

比较简单的数据压库就是zlib了。

zlib官方文档,常用的函数都在这里了,解释很详细。


一  C++功能实现部分


下面将代码贴上来。

在ZipUtils中添加下面三个函数:

// ZipUtils.h

 <pre name="code" class="cpp">typedef struct{unsigned str_size;unsigned buf_size;char data[];// 柔性数组}CompressedData;class ZipUtils {    public:// add by XuLidongstatic void testFun();static unsigned getCompressBound(unsigned len);static bool compressString(const char* str,CompressedData* pdata);static bool decompressString(CompressedData* pdata, char* str);};


用到了柔性数组,不动的可以参考我的另一篇文章

下面是相应的实现:


// ZipUtils.cpp

#include <zlib.h>#include <stdlib.h>#include "ZipUtils.h"int test1(){char text[] = "zlib compress and uncompress test\nxulidong_china@163.com\n2012-11-05\n";  uLong tlen = strlen(text) + 1;  /* 需要把字符串的结束符'\0'也一并处理 */  char* buf = NULL;  uLong blen;  /* 计算缓冲区大小,并为其分配内存 */  blen = compressBound(tlen); /* 压缩后的长度是不会超过blen的 */printf("compress str_size:%d, buf_size:%d\n", tlen, blen);if((buf = (char*)malloc(sizeof(char) * blen)) == NULL)  {  printf("no enough memory!\n");  return -1;  }  /* 压缩 */  if(compress((Bytef*)buf, &blen, (const Bytef*)text, tlen) != Z_OK)  {  printf("compress failed!\n");  return -1;  }  /* 解压缩 */printf("uncompress str_size:%d, buf_size:%d\n", tlen, blen);if(uncompress((Bytef*)text, &tlen, (const Bytef*)buf, blen) != Z_OK)  {printf("uncompress failed!\n");  return -1;  }  /* 打印结果,并释放内存 */  printf("%s", text);  if(buf != NULL)  {  free(buf);  buf = NULL;}}void test2(){const char* str="abcdefg 中文字符可以吗 ? 》 , >\ ";unsigned len = strlen(str) + 1;unsigned long blen = compressBound(len);CompressedData* pdata = (CompressedData*)malloc(sizeof(CompressedData) + blen * sizeof(char));pdata->str_size = len;pdata->buf_size = blen;ZipUtils::compressString(str, pdata);char* ustr = (char*)malloc(len);memset(ustr, 0, len);ZipUtils::decompressString(pdata, ustr);free(ustr);}void ZipUtils::testFun(){//test1();test2();}unsigned ZipUtils::getCompressBound(unsigned len){return (unsigned)compressBound((unsigned long)len);}bool ZipUtils::compressString(const char* str, CompressedData* pdata){printf("compress string:%s\n", str);int res = compress((Bytef*)pdata->data, (unsigned long*)&(pdata->buf_size), (const Bytef*)str, (unsigned long)pdata->str_size);if( res != Z_OK){  printf("compress failed, error code:%d\n", res);  return false;  } printf("string size %d, buffer size: %d\n", pdata->str_size, pdata->buf_size);return true;}bool ZipUtils::decompressString(CompressedData* pdata, char* str){printf("string size %d, buffer size: %d\n", pdata->str_size, pdata->buf_size);int res = uncompress((Bytef*)str, (unsigned long *)&(pdata->str_size), (const Bytef *)pdata->data, (unsigned long)pdata->buf_size);if(res != Z_OK)  {  printf("uncompress failed, error code:%d\n", res);  return false;  }  printf("uncompress string:%s\n", str);return true;}


二 C++导出到Lua接口

// ZipUtilsLua.h

#include "tolua++.h"#include "tolua_event.h"#include "lauxlib.h"int tolua_ZipUtils_open(lua_State *L);


// ZipUtilsLua.cpp

#include "support/zip_support/ZipUtils.h"#include <string>#include "tolua++.h"#include "tolua_event.h"#include "lauxlib.h"using namespace cocos2d;int TOLUA_API luaCopressString(lua_State *L){size_t slen = 0;const char *str = lua_tolstring(L, 1, &slen);unsigned blen = ZipUtils::getCompressBound((unsigned long)slen);CompressedData* pdata = (CompressedData*)malloc(sizeof(CompressedData) + blen * sizeof(char));pdata->str_size = slen;pdata->buf_size = blen;if(ZipUtils::compressString(str, pdata)){lua_pushlstring(L, (char*)pdata, pdata->buf_size+sizeof(CompressedData));printf("sizeof=%d", sizeof(CompressedData));}else{lua_pushstring(L, "");}free(pdata);return 1;}int TOLUA_API luaDecopressString(lua_State *L){const char *strBuf = lua_tostring(L, 1);CompressedData* pdata = (CompressedData*)strBuf;unsigned slen = pdata->str_size;unsigned blen = pdata->buf_size;char* str = (char*)malloc(pdata->str_size * sizeof(char));if(ZipUtils::decompressString(pdata, str)){lua_pushlstring(L, str, slen);}else{lua_pushstring(L, "");}free(str);return 1;}int TOLUA_API luaTestFun(lua_State *L){ZipUtils::testFun();return 1;}static luaL_Reg ziplib[] = {{"compress", luaCopressString},{"decompress", luaDecopressString},{"testFun", luaTestFun},{NULL, NULL}};// 函数名必须为luaopen_xxx,其中xxx表示library名称,Lua代码require "xxx"需要与之对应。int luaopen_ZipUtils(lua_State* L){const char* libName = "ZipUtils";luaL_register(L, libName, ziplib);// 调用方式libName.函数名return 1;}int tolua_ZipUtils_open(lua_State *L){luaopen_ZipUtils(L);return 1;}


注册代码:

    // register lua engine    CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();    CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);    <span style="font-family: Arial, Helvetica, sans-serif;">tolua_ZipUtils_open</span><span style="font-family: Arial, Helvetica, sans-serif;">(pEngine->getLuaStack()->getLuaState());</span>

三 Lua中调用

require ("ZipUtils")local string = "hello, world"local zipData = ZipUtils.compress(string)if c ~= "" thenprint("XXXXXXXXXXXXXXXXX compress", zipData)elseprint("XXXXXXXXXXXXXXXXX error")endlocal str = ZipUtils.decompress(zipData)if str ~= "" thenprint("XXXXXXXXXXXXXXXXX decompress", str)elseprint("XXXXXXXXXXXXXXXXX error")end



0 0
原创粉丝点击