1. 程式人生 > >使用zlib壓縮解壓並匯出lua介面

使用zlib壓縮解壓並匯出lua介面

網路遊戲在前後端交換的過程中,有可能會有大量的資料,比如說遊戲回放功能,這時最好是將資料壓縮一下。

比較簡單的資料壓庫就是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\[email protected]\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了。 zlib官方文件,常用的函式都在這裡了,解釋很詳細。 一  C++功能實現部分 下面將程式碼貼上來。 在ZipUtils中新增下面三

使用 ZLib 壓縮/ ZIP 檔案

實際應用中有時候會遇到需要處理 ZIP 壓縮解壓的情況,這時候我們有大概三種選擇: 呼叫 rar.exe, unzip.exe 等 使用某現成庫 完全手寫 第一種雖然能完成任務,但是沒法知曉結果。曾經有人對說,可以抓命令列輸出結果來判斷……這種依靠介面文字來進行精確判斷的行為個人認為相當不靠

python專案1:自動刪除壓縮

目的:實現壓縮包的自動解壓及刪除。 思路:獲取壓縮包 > 解壓 > 刪除壓縮包 程式碼實現:此處程式碼實現前提為.py檔案和壓縮包在同一資料夾 # 匯入需要的包 import os import shutil import time # 定義查詢函式 def scan_file():

Unity3d生成壓縮後運行遊戲時找不到UnityPlayer.dll問題

具體問題:生成遊戲-壓縮-解壓-運行遊戲,然後提示找不到UnityPlayer.dll。 前提條件:計算機本身已經有UnityPlayer.dll檔案,但是莫名其妙找不到檔案。 嘗試: 按照網上教程,在sysWow64內已經放置UnityPlayer.dll檔案了,但是

python處理gz壓縮檔案,轉化為json

import requests import gzip import json # gz檔案地址 url='https://shilupan-basic-user-pro.oss-cn-shangha

Linux下使用zlib實現資料壓縮

1、背景 本文舉例說明了:專案過程中字串資料傳輸的場景下(檔名列表),如何使用資料壓縮減少頻寬的開銷; 2、相關知識 引用外部的一個手冊進行說明 3、實現方法 deflate壓縮實現,壓縮完成後會提示Z_STREAM_END int gzcompress(void *d

壓縮歸檔gzipzip2xzzip ar

源文件 文件夾 file 常用工具 壓縮文件 常用工具compress/uncompress.zgzip/gunzip.gzbzip2/bunzip2.bz2xz/unxz.xzzip/unzip.ziptar,cpio GZIP/GUNZIP/ZCAT,壓縮文件#gzip file 壓縮

ST MCU生成PDF+文件壓縮

需要 ren aud 文件 無奈 .com 導致 壓縮解壓 str 之前碰到過,STM32F407上做文件壓縮,無奈壓縮文件時,哈夫曼編碼需要耗費很大的RAM,導致失敗。後來在論壇壇主的幫助下,了解了LZ77壓縮。 今天看論壇的時候,了解到MCU上,用pdflib庫,可以做

Centos壓縮&

centos 解壓縮 centos中的文件壓縮與解壓用得頻率還是較大的,許多的壓縮軟件都是下載到linux系統上,然後解壓安裝,使用的是 tar 命令,這個命令又有主選項和輔助選項,這裏就來總結一下吧,以方便自己的使用。Tar語法:tar [主選項+輔選項] 文件或者目錄主選項:c 創建新的檔案文件。

今天聽說了一個壓縮整型的方式-group-varint

under -c 實現 聽說 text master share _id back p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Times; color: #9ea5b2

Linux基本命令—權限管理、文件搜索、幫助、壓縮、網絡通信

Linux基本命令—權限管理、文件搜索、幫助、壓縮解壓、網絡通信Linux權限管理命令文件搜索命令幫助命令壓縮解壓命令網絡通信指令 2017-11-12權限管理命令 chmod 改變文件或目錄權限; 格式:chmod [{ugo} {+-=} {rwx}] [文件或目錄];或 [mode=421]

Linux學習 - 壓縮命令

clas unzip 解包 col 語法 壓縮 linu style body 一、“ .gz ”壓縮文件   1 壓縮語法       gzip [文件]   2 解壓語法       gunzip [壓縮文件]   3 註       gzip只能壓縮文件     

Ubuntu 壓縮命令

file 我們 除了 常用 class AR 解壓命令 程序打包 num 壓縮解壓命令 在講 Linux 上的壓縮工具之前,有必要先了解一下常見常用的壓縮包文件格式。在 Windows 上最常見的不外乎這三種*.zip,*.rar,*.7z 後綴的壓縮文件,而在 Linux

C#實現多級子目錄Zip壓縮實例

rem zip https word nis lap line per except ? ?參考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重點: 實現多級子目錄的

Linux下包/打包,壓縮/命令

res file bzip2 lena dirname unzip bz2 裏的 dir .tar 解包:tar xvf FileName.tar 打包:tar cvf fileName.tar DirName tar.gz和.tgz 解壓:tar zxvf FileNam

php使用phar進行壓縮/

src RoCE ges iter size watermark text rect tex 修改配置文件:vim /usr/local/php/etc/php.ini [Phar] phar.readonly = Off 壓縮:a. 創建壓縮腳本:vim comp

tar壓縮/用法

格式:tar zcvf 壓縮後的路徑及包名 你要壓縮的檔案   z:gzip壓縮   c:建立壓縮包   v:顯示打包壓縮解壓過程   f:接著壓縮   t:檢視壓縮包內容   x:解壓   X:指定檔案列表形式排除不需要打包壓縮的檔案或目錄   -exclude:指定排除檔案或目錄不需要打包

Linux下常用壓縮命令

tar  解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是壓縮!) .gz 解壓1:gunzip FileName.gz 解壓2:g

004-linux常用命令-壓縮命令

壓縮解壓命令:gzip命令名稱:gzip命令英文原意:GNUzip命令所在路徑:/bin/gzip執行許可權:所有使用者語法:gzip [檔案]功能描述:壓縮檔案壓縮後文件格式:.gz   壓縮解壓命令:gunzip命令名稱:gunzip命令英文原意:GNUunzip命令所在路徑:/bin/gu

Keka for Mac(壓縮工具)中文破解版

這裡推薦一款非常實用的壓縮解壓工具Keka for Mac,全新版本的keka for mac 破解更換了新的logo,功能還是一樣的好用,keka for mac 中文版可以輕鬆幫你壓縮和解壓各種格式的檔案,親測好用。 keka for mac 破解教程 下載好Keka安裝包後,點選