Add compression API 1633/head
authorShadowNinja <shadowninja@minetest.net>
Sun, 14 Sep 2014 21:42:08 +0000 (17:42 -0400)
committerShadowNinja <shadowninja@minetest.net>
Sat, 20 Sep 2014 18:02:54 +0000 (14:02 -0400)
doc/lua_api.txt
src/script/lua_api/l_util.cpp
src/script/lua_api/l_util.h
src/serialization.cpp
src/serialization.h

index 37477b60a30ca0bceb393d9eae920061e93ec07f..805b63f6a404b9dae729b5fe3926a18c1a57ddba 100644 (file)
@@ -1763,6 +1763,18 @@ minetest.deserialize(string) -> table
 ^ Example: deserialize('return { ["foo"] = "bar" }') -> {foo='bar'}
 ^ Example: deserialize('print("foo")') -> nil (function call fails)
   ^ 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
 ^ This function should be overridden by protection mods and should be used to
   check if a player can interact at a position.
index 57db632c9c9fe6526dae0e2e728b21b6985009cf..dda5b5abfca4c1ffbd0efbce57c3c611066de817 100644 (file)
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "common/c_converter.h"
 #include "common/c_content.h"
 #include "cpp_api/s_async.h"
+#include "serialization.h"
 #include "debug.h"
 #include "porting.h"
 #include "log.h"
@@ -283,6 +284,40 @@ int ModApiUtil::l_get_builtin_path(lua_State *L)
        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)
 {
@@ -306,6 +341,9 @@ void ModApiUtil::Initialize(lua_State *L, int top)
        API_FCT(is_yes);
 
        API_FCT(get_builtin_path);
+
+       API_FCT(compress);
+       API_FCT(decompress);
 }
 
 void ModApiUtil::InitializeAsync(AsyncEngine& engine)
@@ -325,5 +363,8 @@ void ModApiUtil::InitializeAsync(AsyncEngine& engine)
        ASYNC_API_FCT(is_yes);
 
        ASYNC_API_FCT(get_builtin_path);
+
+       ASYNC_API_FCT(compress);
+       ASYNC_API_FCT(decompress);
 }
 
index cfdeea1e8618b73c66523a80e43b98814fe05be9..e824323815430b300e79d602be8eb4c6a0460232 100644 (file)
@@ -81,6 +81,12 @@ private:
        // get_scriptdir()
        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:
        static void Initialize(lua_State *L, int top);
 
index 118bad467c91e880a3a1cecb0e9ed77dd678c65c..c0fbe10e23335fb9cc8f2031dd8637e0cec548a3 100644 (file)
@@ -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;
        const s32 bufsize = 16384;
@@ -65,7 +65,7 @@ void compressZlib(SharedBuffer<u8> data, std::ostream &os)
        z.zfree = Z_NULL;
        z.opaque = Z_NULL;
 
-       ret = deflateInit(&z, -1);
+       ret = deflateInit(&z, level);
        if(ret != Z_OK)
                throw SerializationError("compressZlib: deflateInit failed");
        
@@ -94,13 +94,12 @@ void compressZlib(SharedBuffer<u8> data, std::ostream &os)
        }
 
        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());
-       compressZlib(databuf, os);
+       compressZlib(databuf, os, level);
 }
 
 void decompressZlib(std::istream &is, std::ostream &os)
index 86da31486f2fffd8e6504a06122d0f1dfa15d5b4..41a5054555119e8cf370f00ddb8cefe0e8a3f973 100644 (file)
@@ -78,8 +78,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        Misc. serialization functions
 */
 
-void compressZlib(SharedBuffer<u8> data, std::ostream &os);
-void compressZlib(const std::string &data, std::ostream &os);
+void compressZlib(SharedBuffer<u8> data, std::ostream &os, int level = -1);
+void compressZlib(const std::string &data, std::ostream &os, int level = -1);
 void decompressZlib(std::istream &is, std::ostream &os);
 
 // These choose between zlib and a self-made one according to version