码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-01-31 00:32:06      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:zlib


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

比较简单的数据压库就是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 XuLidong
		static 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 ~= "" then
		print("XXXXXXXXXXXXXXXXX compress", zipData)
	else
		print("XXXXXXXXXXXXXXXXX error")
	end
	local str = ZipUtils.decompress(zipData)
	if str ~= "" then
		print("XXXXXXXXXXXXXXXXX decompress", str)
	else
		print("XXXXXXXXXXXXXXXXX error")
	end	



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

标签:zlib

原文地址:http://blog.csdn.net/xufeng0991/article/details/43319039

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!