Add compression API

This commit is contained in:
ShadowNinja 2014-09-14 17:42:08 -04:00
parent d6e28c19b5
commit 406ed5efac
5 changed files with 65 additions and 7 deletions

@ -1763,6 +1763,18 @@ minetest.deserialize(string) -> table
^ Example: deserialize('return { ["foo"] = "bar" }') -> {foo='bar'} ^ Example: deserialize('return { ["foo"] = "bar" }') -> {foo='bar'}
^ Example: deserialize('print("foo")') -> nil (function call fails) ^ Example: deserialize('print("foo")') -> nil (function call fails)
^ error:[string "print("foo")"]:1: attempt to call global 'print' (a nil value) ^ error:[string "print("foo")"]:1: attempt to call global 'print' (a nil value)
minetest.compress(data, method, ...) -> compressed_data
^ Compress a string of data.
^ `method` is a string identifying the compression method to be used.
^ Supported compression methods:
^ Deflate (zlib): "deflate"
^ `...` indicates method-specific arguments. Currently defined arguments are:
^ Deflate: `level` - Compression level, 0-9 or nil.
minetest.decompress(compressed_data, method, ...) -> data
^ Decompress a string of data (using ZLib).
^ See documentation on minetest.compress() for supported compression methods.
^ currently supported.
^ `...` indicates method-specific arguments. Currently, no methods use this.
minetest.is_protected(pos, name) -> bool minetest.is_protected(pos, name) -> bool
^ This function should be overridden by protection mods and should be used to ^ This function should be overridden by protection mods and should be used to
check if a player can interact at a position. check if a player can interact at a position.

@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common/c_converter.h" #include "common/c_converter.h"
#include "common/c_content.h" #include "common/c_content.h"
#include "cpp_api/s_async.h" #include "cpp_api/s_async.h"
#include "serialization.h"
#include "debug.h" #include "debug.h"
#include "porting.h" #include "porting.h"
#include "log.h" #include "log.h"
@ -283,6 +284,40 @@ int ModApiUtil::l_get_builtin_path(lua_State *L)
return 1; return 1;
} }
// compress(data, method, level)
int ModApiUtil::l_compress(lua_State *L)
{
size_t size;
const char *data = luaL_checklstring(L, 1, &size);
int level = -1;
if (!lua_isnone(L, 3) && !lua_isnil(L, 3))
level = luaL_checknumber(L, 3);
std::ostringstream os;
compressZlib(std::string(data, size), os, level);
std::string out = os.str();
lua_pushlstring(L, out.data(), out.size());
return 1;
}
// decompress(data, method)
int ModApiUtil::l_decompress(lua_State *L)
{
size_t size;
const char * data = luaL_checklstring(L, 1, &size);
std::istringstream is(std::string(data, size));
std::ostringstream os;
decompressZlib(is, os);
std::string out = os.str();
lua_pushlstring(L, out.data(), out.size());
return 1;
}
void ModApiUtil::Initialize(lua_State *L, int top) void ModApiUtil::Initialize(lua_State *L, int top)
{ {
@ -306,6 +341,9 @@ void ModApiUtil::Initialize(lua_State *L, int top)
API_FCT(is_yes); API_FCT(is_yes);
API_FCT(get_builtin_path); API_FCT(get_builtin_path);
API_FCT(compress);
API_FCT(decompress);
} }
void ModApiUtil::InitializeAsync(AsyncEngine& engine) void ModApiUtil::InitializeAsync(AsyncEngine& engine)
@ -325,5 +363,8 @@ void ModApiUtil::InitializeAsync(AsyncEngine& engine)
ASYNC_API_FCT(is_yes); ASYNC_API_FCT(is_yes);
ASYNC_API_FCT(get_builtin_path); ASYNC_API_FCT(get_builtin_path);
ASYNC_API_FCT(compress);
ASYNC_API_FCT(decompress);
} }

@ -81,6 +81,12 @@ private:
// get_scriptdir() // get_scriptdir()
static int l_get_builtin_path(lua_State *L); static int l_get_builtin_path(lua_State *L);
// compress(data, method, ...)
static int l_compress(lua_State *L);
// decompress(data, method, ...)
static int l_decompress(lua_State *L);
public: public:
static void Initialize(lua_State *L, int top); static void Initialize(lua_State *L, int top);

@ -53,7 +53,7 @@ void zerr(int ret)
} }
} }
void compressZlib(SharedBuffer<u8> data, std::ostream &os) void compressZlib(SharedBuffer<u8> data, std::ostream &os, int level)
{ {
z_stream z; z_stream z;
const s32 bufsize = 16384; const s32 bufsize = 16384;
@ -65,7 +65,7 @@ void compressZlib(SharedBuffer<u8> data, std::ostream &os)
z.zfree = Z_NULL; z.zfree = Z_NULL;
z.opaque = Z_NULL; z.opaque = Z_NULL;
ret = deflateInit(&z, -1); ret = deflateInit(&z, level);
if(ret != Z_OK) if(ret != Z_OK)
throw SerializationError("compressZlib: deflateInit failed"); throw SerializationError("compressZlib: deflateInit failed");
@ -94,13 +94,12 @@ void compressZlib(SharedBuffer<u8> data, std::ostream &os)
} }
deflateEnd(&z); deflateEnd(&z);
} }
void compressZlib(const std::string &data, std::ostream &os) void compressZlib(const std::string &data, std::ostream &os, int level)
{ {
SharedBuffer<u8> databuf((u8*)data.c_str(), data.size()); SharedBuffer<u8> databuf((u8*)data.c_str(), data.size());
compressZlib(databuf, os); compressZlib(databuf, os, level);
} }
void decompressZlib(std::istream &is, std::ostream &os) void decompressZlib(std::istream &is, std::ostream &os)

@ -78,8 +78,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
Misc. serialization functions Misc. serialization functions
*/ */
void compressZlib(SharedBuffer<u8> data, std::ostream &os); void compressZlib(SharedBuffer<u8> data, std::ostream &os, int level = -1);
void compressZlib(const std::string &data, std::ostream &os); void compressZlib(const std::string &data, std::ostream &os, int level = -1);
void decompressZlib(std::istream &is, std::ostream &os); void decompressZlib(std::istream &is, std::ostream &os);
// These choose between zlib and a self-made one according to version // These choose between zlib and a self-made one according to version