/* * Baltisot * Copyright (C) 1999-2008 Nicolas "Pixel" Noble * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "LuaHandle.h" LuaInput::LuaInput(Input * h) : LuaHandle(h) { } LuaOutput::LuaOutput(Output * h) : LuaHandle(h) { } LuaBuffer::LuaBuffer(Buffer * h) : LuaHandle(h) { } LuaHandleLua::LuaHandleLua(HandleLua * h) : LuaHandle(h) { } LuaHandle::LuaHandle(Handle * _h) : h(_h) { } class sLuaHandle : public Base { public: static int newinput(lua_State * L); static int newoutput(lua_State * L); static int newbuffer(lua_State * L); static int newhandlelua(lua_State * L); static int read(lua_State * L); static int readstring(lua_State * L); static int readU8(lua_State * L); static int readU16(lua_State * L); static int readU32(lua_State * L); static int readFloat(lua_State * L); static int readDouble(lua_State * L); static int readfile(lua_State * L); static int write(lua_State * L); static int writestring(lua_State * L); static int writeU8(lua_State * L); static int writeU16(lua_State * L); static int writeU32(lua_State * L); static int writeFloat(lua_State * L); static int writeDouble(lua_State * L); static int copyfrom(lua_State * L); static int copyto(lua_State * L); static int isclosed(lua_State * L); static int isnonblock(lua_State * L); static int canread(lua_State * L); static int canwrite(lua_State * L); static int canseek(lua_State * L); static int canwatch(lua_State * L); static int setnonblock(lua_State * L); static int tell(lua_State * L); static int getname(lua_State * L); static int getsize(lua_State * L); static int getmodif(lua_State * L); static int close(lua_State * L); static int flush(lua_State * L); static int seek(lua_State * L); static int setz(lua_State * L); static int bindex(lua_State * L); static int bnewindex(lua_State * L); static int bseek(lua_State * L); static int btell(lua_State * L); static int breset(lua_State * L); static int exists(lua_State * L); static int get_nb_handles(lua_State * L); static int get_nb_input(lua_State * L); static int get_nb_output(lua_State * L); static int get_nb_buffer(lua_State * L); static int zlib_inflate(lua_State * L); static int zlib_deflate(lua_State * L); #ifdef HAVE_UCL static int ucl_compress(lua_State * L); static int ucl_decompress(lua_State * L); static int ucl_overlap(lua_State * L); #endif static int archive(lua_State * L); static int user2table(lua_State * L); static int adler32(lua_State * L); static int crc32(lua_State * L); private: static int read(lua_State * L, int); static int write(lua_State * L, int); static int copy(lua_State * L, int); static int getcaps(lua_State * L, int); static int action(lua_State * L, int); enum { U8, U16, U32, R_FLOAT, R_DOUBLE, }; enum { from, to }; enum { capisclosed, capisnonblock, capcanread, capcanwrite, capcanseek, capcanwatch }; enum { Asetnonblock, Atell, Agetname, Agetsize, Agetmodif, Aclose, Aflush }; }; void LuaInput::pushconstruct(Lua * L) { L->declarefunc("Input", sLuaHandle::newinput); } void LuaOutput::pushconstruct(Lua * L) { L->declarefunc("Output", sLuaHandle::newoutput); } void LuaBuffer::pushconstruct(Lua * L) { L->declarefunc("Buffer", sLuaHandle::newbuffer); } void LuaHandleLua::pushconstruct(Lua * L) { L->declarefunc("HandleLua", sLuaHandle::newhandlelua); } int sLuaHandle::newinput(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); if ((n != 1) || !L->isstring()) { L->error("Incorrect arguments to constructor `Input'"); } LuaInput i(new Input(L->tostring())); i.pushdestruct(L); return 1; } int sLuaHandle::newoutput(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); if ((n != 1) || !L->isstring()) { L->error("Incorrect arguments to constructor `Input'"); } LuaOutput o(new Output(L->tostring())); o.pushdestruct(L); return 1; } int sLuaHandle::newbuffer(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); bool seekable = false; if ((n > 1) || ((n == 1) && (!L->isboolean()))) { L->error("Incorrect arguments to constructor `Buffer'"); } if (n == 1) seekable = L->toboolean(); LuaBuffer o(new Buffer(seekable)); o.pushdestruct(L); return 1; } int sLuaHandle::newhandlelua(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); if ((n != 1) || !L->istable()) { L->error("Incorrect arguments to constructor `HandleLua'"); } LuaHandleLua o(new HandleLua(L)); o.pushdestruct(L); return 1; } int sLuaHandle::read(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(), i; size_t t; ssize_t r; Handle * h; Byte * b; bool has_userdata = false; bool wants_userdata = false; if (n == 1) { return readstring(__L); } if (((n < 2) && (n > 3)) || !L->isnumber() || ((n == 3) && (!L->isuserdata(3) || !L->isboolean(3)))) { L->error("Incorrect arguments to method `Headle::read'"); } t = L->tonumber(2); if ((n == 3) && L->isuserdata(3)) { has_userdata = true; b = (Byte *) L->touserdata(3); } else if ((n == 3) && L->toboolean(3)) { wants_userdata = true; b = (Byte *) L->newuser(t); } else { b = (Byte *) malloc(t); } h = L->recast(1); r = h->read(b, t); if (has_userdata || wants_userdata) { L->push((lua_Number) r); return wants_userdata ? 2 : 1; } L->newtable(); for (i = 0; i < r; i++) { L->push((lua_Number) i); L->push((lua_Number) b[i]); L->settable(); } free(b); L->push((lua_Number) r); return 2; } int sLuaHandle::readstring(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Handle * h; String r; if (n != 1) { L->error("Incorrect arguments to method `Headle::readstring'"); } h = L->recast(); (*h) >> r; L->push(r); return 1; } int sLuaHandle::readfile(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Handle * h; Byte * buf; if (n != 1) { L->error("Incorrect arguments to method `Headle::readfile'"); } h = L->recast(); if (h->GetSize() < 0) return 0; h->seek(0); buf = (Byte *) malloc(h->GetSize()); h->read(buf, h->GetSize()); L->push((char *) buf, h->GetSize()); free(buf); return 1; } #define MAXCHUNKSIZE 65536 int sLuaHandle::adler32(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Handle * h; Byte * buf; ssize_t tg, blk; if (n != 1) { L->error("Incorrect arguments to function `adler32'"); } h = L->recast(); tg = h->GetSize(); if (tg < 0) return 0; h->seek(0); buf = (Byte *) malloc(MAXCHUNKSIZE); Uint32 adler = ::adler32(0L, Z_NULL, 0); while (tg > 0) { blk = MIN(MAXCHUNKSIZE, tg); h->read(buf, blk); tg -= blk; adler = ::adler32(adler, buf, blk); } free(buf); L->push((lua_Number) adler); return 1; } int sLuaHandle::crc32(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Handle * h; Byte * buf; ssize_t tg, blk; if (n != 1) { L->error("Incorrect arguments to function `crc32'"); } h = L->recast(); tg = h->GetSize(); if (tg < 0) return 0; h->seek(0); buf = (Byte *) malloc(MAXCHUNKSIZE); Uint32 crc = ::crc32(0L, Z_NULL, 0); while (tg > 0) { blk = MIN(MAXCHUNKSIZE, tg); h->read(buf, blk); tg -= blk; crc = ::crc32(crc, buf, blk); } free(buf); L->push((lua_Number) crc); return 1; } int sLuaHandle::readU8(lua_State * L) { return read(L, U8); } int sLuaHandle::readU16(lua_State * L) { return read(L, U16); } int sLuaHandle::readU32(lua_State * L) { return read(L, U32); } int sLuaHandle::readFloat(lua_State * L) { return read(L, R_FLOAT); } int sLuaHandle::readDouble(lua_State * L) { return read(L, R_DOUBLE); } int sLuaHandle::write(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(), i; size_t t; ssize_t r; Handle * h; Byte * b; bool has_userdata = false; if ((n == 2) && L->isstring()) { return writestring(__L); } if ((n != 3) || !L->isnumber(3) || !(L->istable(2) || L->isuserdata(2))) { L->error("Incorrect arguments to method `Headle::write'"); } t = L->tonumber(3); if (L->isuserdata(2)) { b = (Byte *) L->touserdata(2); has_userdata = true; } else { b = (Byte *) malloc(t); } h = L->recast(1); if (!has_userdata) { for (i = 0; i < t; i++) { L->push((lua_Number) i); L->gettable(2); b[i] = L->tonumber(); L->pop(); } } r = h->write(b, t); if (!has_userdata) free(b); L->push((lua_Number) r); return 1; } int sLuaHandle::writestring(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Handle * h; String r; if ((n != 2) || !L->isstring()) { L->error("Incorrect arguments to method `Headle::writestring'"); } h = L->recast(); r = L->tostring(); (*h) << r; return 0; } int sLuaHandle::writeU8(lua_State * L) { return write(L, U8); } int sLuaHandle::writeU16(lua_State * L) { return write(L, U16); } int sLuaHandle::writeU32(lua_State * L) { return write(L, U32); } int sLuaHandle::writeFloat(lua_State * L) { return write(L, R_FLOAT); } int sLuaHandle::writeDouble(lua_State * L) { return write(L, R_DOUBLE); } int sLuaHandle::read(lua_State * __L, int t) { Lua * L = Lua::find(__L); int n = L->gettop(); lua_Number r; Handle * h; if (n != 1) { L->error("Incorrect arguments to method `Headle::readUx'"); } h = L->recast(); switch (t) { case U8: r = h->readU8(); break; case U16: r = h->readU16(); break; case U32: r = h->readU32(); break; case R_FLOAT: r = h->readFloat(); break; case R_DOUBLE: r = h->readDouble(); break; } L->push(r); return 1; } int sLuaHandle::write(lua_State * __L, int t) { Lua * L = Lua::find(__L); int n = L->gettop(); lua_Number r; Handle * h; if ((n != 2) || !L->isnumber()) { L->error("Incorrect arguments to method `Headle::writeUx'"); } h = L->recast(); r = L->tonumber(); switch (t) { case U8: h->writeU8(r); break; case U16: h->writeU16(r); break; case U32: h->writeU32(r); break; case R_FLOAT: h->writeFloat(r); break; case R_DOUBLE: h->writeDouble(r); break; } return 0; } int sLuaHandle::copyfrom(lua_State * L) { return copy(L, from); } int sLuaHandle::copyto(lua_State * L) { return copy(L, to); } int sLuaHandle::copy(lua_State * __L, int dir) { Lua * L = Lua::find(__L); int n = L->gettop(); lua_Number r; Handle * s, * d; if ((n < 2) || (n > 3) || ((n == 3) && !L->isnumber(3))) { L->error("Incorrect arguments to function `handlecopy'"); } s = L->recast(1); d = L->recast(2); if (n == 3) { r = L->tonumber(); } else { r = -1; } if (dir == from) { SWAP(s, d); } s->copyto(d, r); return 0; } int sLuaHandle::isclosed(lua_State * L) { return getcaps(L, capisclosed); } int sLuaHandle::isnonblock(lua_State * L) { return getcaps(L, capisnonblock); } int sLuaHandle::canread(lua_State * L) { return getcaps(L, capcanread); } int sLuaHandle::canwrite(lua_State * L) { return getcaps(L, capcanwrite); } int sLuaHandle::canseek(lua_State * L) { return getcaps(L, capcanseek); } int sLuaHandle::canwatch(lua_State * L) { return getcaps(L, capcanwatch); } int sLuaHandle::getcaps(lua_State * __L, int cap) { Lua * L = Lua::find(__L); int n = L->gettop(); bool r; Handle * h; if (n != 1) { L->error("Incorrect arguments to method `Handle::getcaps'"); } h = L->recast(); switch (cap) { case capisclosed: r = h->IsClosed(); break; case capisnonblock: r = h->IsNonBlock(); break; case capcanread: r = h->CanRead(); break; case capcanwrite: r = h->CanWrite(); break; case capcanseek: r = h->CanSeek(); break; case capcanwatch: r = h->CanWatch(); break; } L->push(r); return 1; } int sLuaHandle::setnonblock(lua_State * L) { return action(L, Asetnonblock); } int sLuaHandle::tell(lua_State * L) { return action(L, Atell); } int sLuaHandle::getname(lua_State * L) { return action(L, Agetname); } int sLuaHandle::getsize(lua_State * L) { return action(L, Agetsize); } int sLuaHandle::getmodif(lua_State * L) { return action(L, Agetmodif); } int sLuaHandle::close(lua_State * L) { return action(L, Aclose); } int sLuaHandle::flush(lua_State * L) { return action(L, Aflush); } int sLuaHandle::action(lua_State * __L, int act) { Lua * L = Lua::find(__L); int n = L->gettop(); int r = 1; Handle * h; if (n != 1) { L->error("Incorrect arguments to method `Handle::action'"); } h = L->recast(); switch (act) { case Asetnonblock: r = 0; h->SetNonBlock(); break; case Atell: L->push((lua_Number) h->tell()); break; case Agetname: L->push(h->GetName()); break; case Agetsize: L->push((lua_Number) h->GetSize()); break; case Agetmodif: L->push((lua_Number) h->GetModif()); break; case Aclose: r = 0; h->close(); break; case Aflush: r = 0; h->Flush(); break; } return r; } int sLuaHandle::setz(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); int z = 9; Handle * h; if ((n < 1) || (n > 2) || ((n == 2) && !L->isnumber(2))) { L->error("Incorrect arguments to method `Handle::setz'"); } h = L->recast(); if (n == 2) { z = L->tonumber(2); } h->SetZ(z); return 0; } int sLuaHandle::get_nb_handles(lua_State * __L) { Lua * L = Lua::find(__L); L->push((lua_Number) Handle::GetNbHandles()); return 1; } int sLuaHandle::get_nb_input(lua_State * __L) { Lua * L = Lua::find(__L); L->push((lua_Number) Input::GetNbInput()); return 1; } int sLuaHandle::get_nb_output(lua_State * __L) { Lua * L = Lua::find(__L); L->push((lua_Number) Output::GetNbOutput()); return 1; } int sLuaHandle::get_nb_buffer(lua_State * __L) { Lua * L = Lua::find(__L); L->push((lua_Number) Buffer::GetNbBuffer()); return 1; } int sLuaHandle::zlib_inflate(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Handle * s, * d; int r; if (n != 2) { L->error("Incorrect arguments to method `Handle::zlib_inflate'"); } s = L->recast(1); d = L->recast(2); r = Handle::zlib_inflate(s, d); L->push((lua_Number) r); return 1; } int sLuaHandle::zlib_deflate(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Handle * s, * d; int r; if (n != 2) { L->error("Incorrect arguments to method `Handle::zlib_deflate'"); } s = L->recast(1); d = L->recast(2); r = Handle::zlib_deflate(s, d); L->push((lua_Number) r); return 1; } #ifdef HAVE_UCL int sLuaHandle::ucl_compress(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Handle * s, * d; int r, l = -1; if (!((n >= 2) && (n <= 3))) { L->error("Incorrect arguments to method `Handle::ucl_compress'"); } s = L->recast(1); d = L->recast(2); if (n == 3) { l = L->tonumber(3); } r = Handle::ucl_compress(s, d); L->push((lua_Number) r); return 1; } int sLuaHandle::ucl_decompress(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Handle * s, * d; int r, l, l_in = -1; if (!((n >= 3) && (n <= 4)) || (!L->isnumber(3))) { L->error("Incorrect arguments to method `Handle::ucl_decompress'"); } s = L->recast(1); d = L->recast(2); l = L->tonumber(3); if (n == 4) { l_in = L->tonumber(4); } r = Handle::ucl_decompress(s, d, l, l_in); L->push((lua_Number) r); return 1; } int sLuaHandle::ucl_overlap(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Handle * s, * d; int r, l, l_in = -1; if (!((n >= 2) && (n <= 3)) || (!L->isnumber(2))) { L->error("Incorrect arguments to method `Handle::ucl_overlap'"); } s = L->recast(1); l = L->tonumber(2); if (n == 3) { l_in = L->tonumber(3); } r = Handle::ucl_overlap(s, l, l_in); L->push((lua_Number) r); return 1; } #endif int sLuaHandle::archive(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); if ((n != 1) || !L->isstring(1)) { L->error("Archive needs exactly one string argument."); } new Archive(L->tostring(1)); return 0; } int sLuaHandle::user2table(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Byte * buf; ssize_t count, i; if ((n != 2) || !L->isuserdata(1) || !L->isnumber(2)) { L->error("user2table needs exactly two arguments."); } buf = (Byte *) L->touserdata(1); count = L->tonumber(2); L->newtable(); for (i = 0; i < count; i++) { L->push((lua_Number) buf[i]); L->rawseti(i); } return 1; } int sLuaHandle::seek(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); off_t off; int wheel; Handle * h; if ((n < 2) || (n > 3) || !L->isnumber(2) || ((n == 3) && !L->isnumber(3))) { L->error("Incorrect arguments to method `Handle::seek'"); } h = L->recast(); off = L->tonumber(2); if (n == 3) { wheel = L->tonumber(3); } else { wheel = SEEK_SET; } L->push((lua_Number) h->seek(off, wheel)); return 1; } int sLuaHandle::bindex(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); const Buffer * b; if (n != 2) { L->error("Inconsistant call to metamethod Buffer::index"); } if (!L->isnumber()) { L->push(); return 1; } b = L->recast(); L->push((lua_Number) (*b)[L->tonumber()]); return 1; } int sLuaHandle::bnewindex(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Buffer * b; if (n != 3) { L->error("Inconsistant call to metamethod Buffer::newindex"); } if (!L->isnumber(2)) { L->settable(1, true); return 0; } if (!L->isnumber(3)) { L->error("Can't write a non-number to buffer"); } b = L->recast(); (*b)[L->tonumber(2)] = L->tonumber(3); return 0; } int sLuaHandle::btell(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Buffer * h; if (n != 1) { L->error("Incorrect arguments to method `Buffer::wtell'"); } h = L->recast(); L->push((lua_Number) h->wtell()); return 1; } int sLuaHandle::bseek(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); off_t off; int wheel; Buffer * h; if ((n < 2) || (n > 3) || !L->isnumber(2) || ((n == 3) && !L->isnumber(3))) { L->error("Incorrect arguments to method `Buffer::wseek'"); } h = L->recast(); off = L->tonumber(2); if (n == 3) { wheel = L->tonumber(3); } else { wheel = SEEK_SET; } L->push((lua_Number) h->wseek(off, wheel)); return 1; } int sLuaHandle::breset(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); Buffer * h; if (n != 1) { L->error("Incorrect arguments to method `Buffer::reset'"); } h = L->recast(); h->reset(); return 0; } int sLuaHandle::exists(lua_State * __L) { Lua * L = Lua::find(__L); int n = L->gettop(); bool r = true; if ((n != 1) || !(L->isstring(1))) { L->error("Incorrect arguments to function exists"); } try { LuaInput i(new Input(L->tostring())); i.pushdestruct(L); } catch (IOGeneral &) { L->push(); r = false; } return 1; } void LuaInput::pushmembers(Lua * L) { LuaHandle::pushmembers(L); L->push("__handletype"); L->push("Input"); L->settable(-3, true); } void LuaOutput::pushmembers(Lua * L) { LuaHandle::pushmembers(L); L->push("__handletype"); L->push("Output"); L->settable(-3, true); } void LuaBuffer::pushmembers(Lua * L) { LuaHandle::pushmembers(L); pushmeta(L, "__index", sLuaHandle::bindex); pushmeta(L, "__newindex", sLuaHandle::bnewindex); pushit(L, "wtell", sLuaHandle::btell); pushit(L, "wseek", sLuaHandle::bseek); pushit(L, "reset", sLuaHandle::breset); L->push("__handletype"); L->push("Buffer"); L->settable(-3, true); } void LuaHandleLua::pushmembers(Lua * L) { LuaHandle::pushmembers(L); L->push("__handletype"); L->push("HandleLua"); L->settable(-3, true); } void LuaHandle::pushmembers(Lua * L) { pushme(L, h, "Handle"); pushit(L, "read", sLuaHandle::read); pushit(L, "write", sLuaHandle::write); pushit(L, "readstring", sLuaHandle::readstring); pushit(L, "writestring", sLuaHandle::writestring); pushit(L, "readfile", sLuaHandle::readfile); pushit(L, "readU8", sLuaHandle::readU8); pushit(L, "readU16", sLuaHandle::readU16); pushit(L, "readU32", sLuaHandle::readU32); pushit(L, "readFloat", sLuaHandle::readFloat); pushit(L, "readDouble", sLuaHandle::readDouble); pushit(L, "writeU8", sLuaHandle::writeU8); pushit(L, "writeU16", sLuaHandle::writeU16); pushit(L, "writeU32", sLuaHandle::writeU32); pushit(L, "writeFloat", sLuaHandle::writeFloat); pushit(L, "writeDouble", sLuaHandle::writeDouble); pushit(L, "copyfrom", sLuaHandle::copyfrom); pushit(L, "copyto", sLuaHandle::copyto); pushit(L, "isclosed", sLuaHandle::isclosed); pushit(L, "isnonblock", sLuaHandle::isnonblock); pushit(L, "canread", sLuaHandle::canread); pushit(L, "canwrite", sLuaHandle::canwrite); pushit(L, "canseek", sLuaHandle::canseek); pushit(L, "canwatch", sLuaHandle::canwatch); pushit(L, "setnonblock", sLuaHandle::setnonblock); pushit(L, "tell", sLuaHandle::tell); pushit(L, "getname", sLuaHandle::getname); pushit(L, "getsize", sLuaHandle::getsize); pushit(L, "getmodif", sLuaHandle::getmodif); pushit(L, "close", sLuaHandle::close); pushit(L, "flush", sLuaHandle::flush); pushit(L, "seek", sLuaHandle::seek); pushit(L, "setz", sLuaHandle::setz); } void LuaHandle::pushconstruct(Lua * L) { L->declarefunc("handlecopy", sLuaHandle::copyfrom); L->declarefunc("exists", sLuaHandle::exists); L->push("SEEK_SET"); L->push((lua_Number) SEEK_SET); L->settable(LUA_GLOBALSINDEX); L->push("SEEK_CUR"); L->push((lua_Number) SEEK_CUR); L->settable(LUA_GLOBALSINDEX); L->push("SEEK_END"); L->push((lua_Number) SEEK_END); L->settable(LUA_GLOBALSINDEX); L->push("HANDLELUAREFS"); L->newtable(); L->settable(LUA_REGISTRYINDEX); L->declarefunc("get_nb_handles", sLuaHandle::get_nb_handles); L->declarefunc("get_nb_input", sLuaHandle::get_nb_input); L->declarefunc("get_nb_output", sLuaHandle::get_nb_output); L->declarefunc("get_nb_buffer", sLuaHandle::get_nb_buffer); L->declarefunc("zlib_inflate", sLuaHandle::zlib_inflate); L->declarefunc("zlib_deflate", sLuaHandle::zlib_deflate); #ifdef HAVE_UCL L->declarefunc("ucl_compress", sLuaHandle::ucl_compress); L->declarefunc("ucl_decompress", sLuaHandle::ucl_decompress); L->declarefunc("ucl_overlap", sLuaHandle::ucl_overlap); #endif L->declarefunc("Archive", sLuaHandle::archive); L->declarefunc("user2table", sLuaHandle::user2table); L->declarefunc("adler32", sLuaHandle::adler32); L->declarefunc("crc32", sLuaHandle::crc32); } HandleLua::HandleLua(Lua * L, int i) : Handle(-1), L(L) { L->copy(i); L->push("HANDLELUAREFS"); L->gettable(LUA_REGISTRYINDEX); L->insert(-2); ref = L->ref(); L->pop(); } HandleLua::~HandleLua() { GetObj(); L->push("predestroy"); L->gettable(); if (!L->isnil()) { L->call(0, 0); } else { L->pop(); } L->push("HANDLELUAREFS"); L->gettable(LUA_REGISTRYINDEX); L->unref(ref); L->pop(); } void HandleLua::GetObj() const { L->push("HANDLELUAREFS"); L->gettable(LUA_REGISTRYINDEX); L->rawgeti(ref); L->remove(-2); } bool HandleLua::CanRead() const { bool r = false; GetObj(); L->push("canread"); L->gettable(); if (L->isnil()) { L->pop(); L->pop(); return false; } L->insert(-2); L->call(1, 1); r = L->toboolean(); L->pop(); L->pop(); return r; } bool HandleLua::CanWrite() const { bool r = false; GetObj(); L->push("canwrite"); L->gettable(); if (L->isnil()) { L->pop(); L->pop(); return false; } L->insert(-2); L->call(1, 1); r = L->toboolean(); L->pop(); L->pop(); return r; } bool HandleLua::CanSeek() const { bool r = false; GetObj(); L->push("canseek"); L->gettable(); if (L->isnil()) { L->pop(); L->pop(); return false; } L->insert(-2); L->call(1, 1); r = L->toboolean(); L->pop(); L->pop(); return r; } bool HandleLua::CanWatch() const { bool r = false; GetObj(); L->push("canwatch"); L->gettable(); if (L->isnil()) { L->pop(); L->pop(); return false; } L->insert(-2); L->call(1, 1); r = L->toboolean(); L->pop(); L->pop(); return r; } String HandleLua::GetName() const { String r; GetObj(); L->push("getname"); L->gettable(); if (L->isnil()) { L->pop(); L->pop(); return "LuaHandleNoName"; } L->insert(-2); L->call(1, 1); r = L->tostring(); L->pop(); L->pop(); return r; } off_t HandleLua::tell() const { lua_Number r; GetObj(); L->push("tell"); L->gettable(); if (L->isnil()) { L->pop(); L->pop(); return -1; } L->insert(-2); L->call(1, 1); r = L->tonumber(); L->pop(); L->pop(); return r; } ssize_t HandleLua::GetSize() const { lua_Number r; GetObj(); L->push("getsize"); L->gettable(); if (L->isnil()) { L->pop(); L->pop(); return -1; } L->insert(-2); L->call(1, 1); r = L->tonumber(); L->pop(); L->pop(); return r; } time_t HandleLua::GetModif() const { lua_Number r; GetObj(); L->push("getmodif"); L->gettable(); if (L->isnil()) { L->pop(); L->pop(); return 0; } L->insert(-2); L->call(1, 1); r = L->tonumber(); L->pop(); L->pop(); return r; } void HandleLua::Flush() { GetObj(); L->push("flush"); L->gettable(); if (L->isnil()) { L->pop(); return; } L->insert(-2); L->call(1, 0); L->pop(); } off_t HandleLua::seek(off_t offset, int wheel) throw (GeneralException) { off_t r = -1; GetObj(); L->push("seek"); L->gettable(); if (L->isnil()) { L->pop(); throw GeneralException("This HandleLua doesn't have any seek method (or can't seek maybe)."); } L->insert(-2); L->push((lua_Number) offset); L->push((lua_Number) wheel); L->call(3, 1); r = L->tonumber(); L->pop(); L->pop(); return r; } ssize_t HandleLua::read(void * buf, size_t count) throw (GeneralException) { ssize_t r = -1; GetObj(); L->push("read"); L->gettable(); if (L->isnil()) { L->pop(); throw GeneralException("This HandleLua doesn't have any read method (or can't read maybe)."); } L->insert(-2); L->push(buf); L->push((lua_Number) count); L->call(3, 2); r = L->tonumber(-2); if (L->istable()) { int i; Byte * b = (Byte *) buf; for (i = 0; i < r; i++) { L->push((lua_Number) i); L->gettable(); b[i] = L->tonumber(); L->pop(); } } L->pop(); L->pop(); L->pop(); return r; } ssize_t HandleLua::write(const void * buf, size_t count) throw (GeneralException) { ssize_t r = -1; GetObj(); L->push("write"); L->gettable(); if (L->isnil()) { L->pop(); throw GeneralException("This HandleLua doesn't have any write method (or can't write maybe)."); } L->insert(-2); L->push(buf); L->push((lua_Number) count); L->call(3, 1); r = L->tonumber(); L->pop(); L->pop(); return r; }