Skip to content

Commit 406ed5e

Browse files
committedSep 20, 2014
Add compression API
1 parent d6e28c1 commit 406ed5e

File tree

5 files changed

+65
-7
lines changed

5 files changed

+65
-7
lines changed
 

‎doc/lua_api.txt

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

‎src/script/lua_api/l_util.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2222
#include "common/c_converter.h"
2323
#include "common/c_content.h"
2424
#include "cpp_api/s_async.h"
25+
#include "serialization.h"
2526
#include "debug.h"
2627
#include "porting.h"
2728
#include "log.h"
@@ -283,6 +284,40 @@ int ModApiUtil::l_get_builtin_path(lua_State *L)
283284
return 1;
284285
}
285286

287+
// compress(data, method, level)
288+
int ModApiUtil::l_compress(lua_State *L)
289+
{
290+
size_t size;
291+
const char *data = luaL_checklstring(L, 1, &size);
292+
293+
int level = -1;
294+
if (!lua_isnone(L, 3) && !lua_isnil(L, 3))
295+
level = luaL_checknumber(L, 3);
296+
297+
std::ostringstream os;
298+
compressZlib(std::string(data, size), os, level);
299+
300+
std::string out = os.str();
301+
302+
lua_pushlstring(L, out.data(), out.size());
303+
return 1;
304+
}
305+
306+
// decompress(data, method)
307+
int ModApiUtil::l_decompress(lua_State *L)
308+
{
309+
size_t size;
310+
const char * data = luaL_checklstring(L, 1, &size);
311+
312+
std::istringstream is(std::string(data, size));
313+
std::ostringstream os;
314+
decompressZlib(is, os);
315+
316+
std::string out = os.str();
317+
318+
lua_pushlstring(L, out.data(), out.size());
319+
return 1;
320+
}
286321

287322
void ModApiUtil::Initialize(lua_State *L, int top)
288323
{
@@ -306,6 +341,9 @@ void ModApiUtil::Initialize(lua_State *L, int top)
306341
API_FCT(is_yes);
307342

308343
API_FCT(get_builtin_path);
344+
345+
API_FCT(compress);
346+
API_FCT(decompress);
309347
}
310348

311349
void ModApiUtil::InitializeAsync(AsyncEngine& engine)
@@ -325,5 +363,8 @@ void ModApiUtil::InitializeAsync(AsyncEngine& engine)
325363
ASYNC_API_FCT(is_yes);
326364

327365
ASYNC_API_FCT(get_builtin_path);
366+
367+
ASYNC_API_FCT(compress);
368+
ASYNC_API_FCT(decompress);
328369
}
329370

‎src/script/lua_api/l_util.h

+6
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ class ModApiUtil : public ModApiBase {
8181
// get_scriptdir()
8282
static int l_get_builtin_path(lua_State *L);
8383

84+
// compress(data, method, ...)
85+
static int l_compress(lua_State *L);
86+
87+
// decompress(data, method, ...)
88+
static int l_decompress(lua_State *L);
89+
8490
public:
8591
static void Initialize(lua_State *L, int top);
8692

‎src/serialization.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void zerr(int ret)
5353
}
5454
}
5555

56-
void compressZlib(SharedBuffer<u8> data, std::ostream &os)
56+
void compressZlib(SharedBuffer<u8> data, std::ostream &os, int level)
5757
{
5858
z_stream z;
5959
const s32 bufsize = 16384;
@@ -65,7 +65,7 @@ void compressZlib(SharedBuffer<u8> data, std::ostream &os)
6565
z.zfree = Z_NULL;
6666
z.opaque = Z_NULL;
6767

68-
ret = deflateInit(&z, -1);
68+
ret = deflateInit(&z, level);
6969
if(ret != Z_OK)
7070
throw SerializationError("compressZlib: deflateInit failed");
7171

@@ -94,13 +94,12 @@ void compressZlib(SharedBuffer<u8> data, std::ostream &os)
9494
}
9595

9696
deflateEnd(&z);
97-
9897
}
9998

100-
void compressZlib(const std::string &data, std::ostream &os)
99+
void compressZlib(const std::string &data, std::ostream &os, int level)
101100
{
102101
SharedBuffer<u8> databuf((u8*)data.c_str(), data.size());
103-
compressZlib(databuf, os);
102+
compressZlib(databuf, os, level);
104103
}
105104

106105
void decompressZlib(std::istream &is, std::ostream &os)

‎src/serialization.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
7878
Misc. serialization functions
7979
*/
8080

81-
void compressZlib(SharedBuffer<u8> data, std::ostream &os);
82-
void compressZlib(const std::string &data, std::ostream &os);
81+
void compressZlib(SharedBuffer<u8> data, std::ostream &os, int level = -1);
82+
void compressZlib(const std::string &data, std::ostream &os, int level = -1);
8383
void decompressZlib(std::istream &is, std::ostream &os);
8484

8585
// These choose between zlib and a self-made one according to version

4 commit comments

Comments
 (4)

4aiman commented on Oct 31, 2014

@4aiman
Contributor

What's the purpose of this addition?
(No offence, I really can't get it.)

ShadowNinja commented on Oct 31, 2014

@ShadowNinja
ContributorAuthor

@4aiman: It's for mods that write a lot of data to the disk (or network with LuaSocket, if the endoint supports it).
For example this can be used to compress WorldEdit schematics.

4aiman commented on Nov 5, 2014

@4aiman
Contributor

So, I can write a mod to compress some schematics and use those compressed files within another mod?

ShadowNinja commented on Nov 6, 2014

@ShadowNinja
ContributorAuthor

@4aiman: Yes, although you should provide an API for loading the schematics and not expose the underlying format.

Please sign in to comment.