Lua: Zip create / enumerate

This commit is contained in:
Ilari Liusvaara 2013-12-16 16:13:13 +02:00
parent b9298b78b1
commit c9636bc63d
5 changed files with 230 additions and 0 deletions

View file

@ -13,6 +13,7 @@ extern lua_function_group lua_func_bit;
extern lua_function_group lua_func_misc;
extern lua_function_group lua_func_callback;
extern lua_function_group lua_func_load;
extern lua_function_group lua_func_zip;
void push_keygroup_parameters(lua_state& L, keyboard_key& p);
extern lua_render_context* lua_render_ctx;

101
lua.lyx
View file

@ -4003,6 +4003,107 @@ Returns random value from table <tab>.
\end_inset
\end_layout
\begin_layout Section
Table zip
\end_layout
\begin_layout Subsection
zip.create: Create a new zipfile
\end_layout
\begin_layout Itemize
Syntax: ZIPWRITER zip.create(string filename[, number compression])
\end_layout
\begin_layout Standard
Creates a new zipfile <filename>, with specified compression level <compression>
(default 9).
\end_layout
\begin_layout Subsection
zip.enumerate: Enumerate members in zipfile
\end_layout
\begin_layout Itemize
Syntax: Table zip.enumerate(string filename[, boolean invert])
\end_layout
\begin_layout Standard
Returns table of files in zip archive <filename>.
If <invert> is true, instead of returning array of names, returns table
with keys being member names and values being true.
\end_layout
\begin_layout Subsection
ZIPWRITER:commit: Finish creating ZIP file.
\end_layout
\begin_layout Itemize
Syntax: none ZIPWRITER:commit()
\end_layout
\begin_layout Standard
Closes the ZIP archive.
Nothing more can be written.
\end_layout
\begin_layout Subsection
ZIPWRITER:rollback: Delete the ZIP file being creted
\end_layout
\begin_layout Itemize
Syntax: none ZIPWRITER:rollback()
\end_layout
\begin_layout Standard
Deletes the newly written ZIP archive.
Nothing more can be written.
\end_layout
\begin_layout Subsection
ZIPWRITER:create_file: Start writing a new member
\end_layout
\begin_layout Itemize
Syntax: none ZIPWRITER:create_file(string filename)
\end_layout
\begin_layout Standard
Starts writing a new member <filename> in ZIP file.
If member is open, it is closed.
\end_layout
\begin_layout Subsection
ZIPWRITER:close_file: Close member
\end_layout
\begin_layout Itemize
Syntax: none ZIPWRITER:close_file()
\end_layout
\begin_layout Standard
Closes member in ZIP file.
\end_layout
\begin_layout Subsection
ZIPWRITER:write: Write data
\end_layout
\begin_layout Itemize
Syntax none ZIPWRITER:write(string data)
\end_layout
\begin_layout Standard
Writes data <data> into ZIP file (binary mode).
\end_layout
\begin_layout Standard
\begin_inset Newpage pagebreak
\end_inset
\end_layout
\begin_layout Section

BIN
lua.pdf

Binary file not shown.

View file

@ -28,6 +28,7 @@ lua_function_group lua_func_bit;
lua_function_group lua_func_misc;
lua_function_group lua_func_callback;
lua_function_group lua_func_load;
lua_function_group lua_func_zip;
namespace
{
@ -441,6 +442,7 @@ void init_lua() throw()
lsnes_lua_state.add_function_group(lua_func_load);
lsnes_lua_state.add_function_group(lua_func_callback);
lsnes_lua_state.add_function_group(lua_func_misc);
lsnes_lua_state.add_function_group(lua_func_zip);
} catch(std::exception& e) {
messages << "Can't initialize Lua." << std::endl;
fatal_error();

126
src/lua/zip.cpp Normal file
View file

@ -0,0 +1,126 @@
#include "library/zip.hpp"
#include "lua/internal.hpp"
namespace
{
class lua_zip_writer
{
public:
lua_zip_writer(lua_state& L, const std::string& filename, unsigned compression);
~lua_zip_writer()
{
if(w) delete w;
}
int commit(lua_state& L, const std::string& fname)
{
if(!w)
throw std::runtime_error("Zip writer already finished");
if(file_open)
w->close_file();
file_open = NULL;
w->commit();
delete w;
w = NULL;
}
int rollback(lua_state& L, const std::string& fname)
{
if(!w)
throw std::runtime_error("Zip writer already finished");
delete w;
w = NULL;
}
int close_file(lua_state& L, const std::string& fname)
{
if(!w)
throw std::runtime_error("Zip writer already finished");
if(!file_open)
throw std::runtime_error("Zip writer doesn't have file open");
w->close_file();
file_open = NULL;
}
int create_file(lua_state& L, const std::string& fname)
{
if(!w)
throw std::runtime_error("Zip writer already finished");
std::string filename = L.get_string(2, "ZIPWRITER::create_file");
if(file_open) {
w->close_file();
file_open = NULL;
}
file_open = &w->create_file(filename);
}
int write(lua_state& L, const std::string& fname)
{
if(!w)
throw std::runtime_error("Zip writer already finished");
if(!file_open)
throw std::runtime_error("Zip writer doesn't have file open");
std::string _data = L.get_string(2, "ZIPWRITER::write");
std::vector<char> data(_data.length());
std::copy(_data.begin(), _data.end(), data.begin());
file_open->write(&data[0], data.size());
}
std::string print()
{
return file;
}
private:
zip_writer* w;
std::ostream* file_open;
std::string file;
};
}
DECLARE_LUACLASS(lua_zip_writer, "ZIPWRITER");
namespace
{
lua_zip_writer::lua_zip_writer(lua_state& L, const std::string& filename, unsigned compression)
{
file = filename;
w = new zip_writer(filename, compression);
file_open = NULL;
objclass<lua_zip_writer>().bind_multi(L, {
{"commit", &lua_zip_writer::commit},
{"rollback", &lua_zip_writer::rollback},
{"close_file", &lua_zip_writer::close_file},
{"create_file", &lua_zip_writer::create_file},
{"write", &lua_zip_writer::write}
});
}
function_ptr_luafun lua_zip(lua_func_zip, "zip.create", [](lua_state& L,
const std::string& fname) -> int {
unsigned compression = 9;
std::string filename = L.get_string(1, fname.c_str());
L.get_numeric_argument<unsigned>(2, compression, fname.c_str());
if(compression < 0)
compression = 0;
if(compression > 9)
compression = 9;
lua_class<lua_zip_writer>::create(L, filename, compression);
return 1;
});
function_ptr_luafun lua_enumerate_zip(lua_func_zip, "zip.enumerate", [](lua_state& L,
const std::string& fname) -> int {
std::string filename = L.get_string(1, fname.c_str());
bool invert = false;
if(L.type(2) != LUA_TNONE && L.type(2) != LUA_TNIL)
invert = L.toboolean(2);
zip_reader r(filename);
L.newtable();
size_t idx = 1;
for(auto i : r) {
if(invert) {
L.pushlstring(i);
L.pushboolean(true);
} else {
L.pushnumber(idx++);
L.pushlstring(i);
}
L.rawset(-3);
}
return 1;
});
}