Skip to content

Commit

Permalink
Runtime: Add a last_error function to the miniz bindings
Browse files Browse the repository at this point in the history
This is a bit questionable, but without it there's no way to actually test the error messages (since Lua doesn't have access to the archive userdata, and it likely shouldn't). The map is just to guard against multithreaded access even if I don't really consider this supported...

The previous approach of hardcoding errors doesn't work reliably.
  • Loading branch information
rdw-software committed Jun 17, 2023
1 parent 38b514a commit 404956f
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
20 changes: 19 additions & 1 deletion Runtime/Bindings/lminiz.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "lminiz.hpp"

#include <unordered_map>
#include <string>

extern "C" {
#include "luv.h"

Expand Down Expand Up @@ -38,6 +41,18 @@ static int lmz_check_compression_level(lua_State* L, int index) {
return level;
}

static std::unordered_map<lua_State*, std::string> error_messages;
static int lmz_last_error(lua_State* L) {
auto iter = error_messages.find(L);
if(iter == error_messages.end()) {
lua_pushnil(L);
} else {
lua_pushstring(L, iter->second.c_str());
error_messages.erase(iter);
}
return 1;
}

static int lmz_reader_init(lua_State* L) {
const char* path = luaL_checkstring(L, 1);
mz_uint32 flags = luaL_optinteger(L, 2, 0);
Expand All @@ -55,8 +70,10 @@ static int lmz_reader_init(lua_State* L) {
archive->m_pIO_opaque = zip;
if(!mz_zip_reader_init(archive, size, flags)) {
lua_pushnil(L);
const char* error_string = mz_zip_get_error_string(mz_zip_get_last_error(archive));
error_messages[L] = error_string;
lua_pushfstring(L, "Failed to initialize miniz reader for archive %s (Last error: %s)", path,
mz_zip_get_error_string(mz_zip_get_last_error(archive)));
error_string);
return 2;
}
return 1;
Expand Down Expand Up @@ -474,6 +491,7 @@ static const luaL_Reg lminiz_f[] = {
{ "version", lmz_version },
{ "new_deflator", lmz_deflator_init },
{ "new_inflator", lmz_inflator_init },
{ "last_error", lmz_last_error },
{ NULL, NULL }
};

Expand Down
22 changes: 17 additions & 5 deletions Tests/BDD/miniz-library.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ describe("miniz", function()
"uncompress",
"new_deflator",
"new_inflator",
"last_error",
}

it("should export all miniz functions", function()
Expand Down Expand Up @@ -169,12 +170,23 @@ describe("miniz", function()

describe("new_reader", function()
it("should fail if an invalid file path was passed", function()
assertFailure(
function()
return miniz.new_reader("asdf-does-not-exist.zip")
end,
"Failed to initialize miniz reader for archive asdf-does-not-exist.zip (Last error: failed finding central directory)"
local success, failureMessage = miniz.new_reader("asdf-does-not-exist.zip")
-- Can't use assertFailure here because the message is only available after new_reader exits
assertNil(success)
assertEquals(
failureMessage,
format(
"Failed to initialize miniz reader for archive asdf-does-not-exist.zip (Last error: %s)",
miniz.last_error()
)
)
end)
end)

describe("last_error", function()
it("should return nil if no error has been set", function()
-- Technically, an error may have been set (and not cleared) by a previous test, but that's a no-no and should be caught
assertNil(miniz.last_error())
end)
end)
end)

0 comments on commit 404956f

Please sign in to comment.