int w_read(lua_State *L) { const char *filename = luaL_checkstring(L, 1); int64 len = (int64) luaL_optinteger(L, 2, File::ALL); Data *data = 0; try { data = instance()->read(filename, len); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } if (data == 0) return luax_ioError(L, "File could not be read."); // Push the string. lua_pushlstring(L, (const char *) data->getData(), data->getSize()); // Push the size. lua_pushinteger(L, data->getSize()); // Lua has a copy now, so we can free it. data->release(); return 2; }
int w_File_tell(lua_State *L) { File *file = luax_checkfile(L, 1); int64 pos = file->tell(); // Push nil on failure or if pos does not fit into a double precision floating-point number. if (pos == -1) return luax_ioError(L, "Invalid position."); else if (pos >= 0x20000000000000LL) return luax_ioError(L, "Number is too large."); else lua_pushnumber(L, (lua_Number)pos); return 1; }
int w_load(lua_State *L) { std::string filename = std::string(luaL_checkstring(L, 1)); Data *data = 0; try { data = instance()->read(filename.c_str()); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } int status = luaL_loadbuffer(L, (const char *)data->getData(), data->getSize(), ("@" + filename).c_str()); data->release(); // Load the chunk, but don't run it. switch (status) { case LUA_ERRMEM: return luaL_error(L, "Memory allocation error: %s\n", lua_tostring(L, -1)); case LUA_ERRSYNTAX: return luaL_error(L, "Syntax error: %s\n", lua_tostring(L, -1)); default: // success return 1; } }
int w_newFile(lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *str = 0; File::Mode mode = File::MODE_CLOSED; if (lua_isstring(L, 2)) { str = luaL_checkstring(L, 2); if (!File::getConstant(str, mode)) return luaL_error(L, "Incorrect file open mode: %s", str); } File *t = instance()->newFile(filename); if (mode != File::MODE_CLOSED) { try { if (!t->open(mode)) throw love::Exception("Could not open file."); } catch (love::Exception &e) { t->release(); return luax_ioError(L, "%s", e.what()); } } luax_pushtype(L, FILESYSTEM_FILE_ID, t); t->release(); return 1; }
int w_newFileData(lua_State *L) { // Single argument: treat as filepath or File. if (lua_gettop(L) == 1) { // We don't use luax_getfiledata because we want to use an ioError. if (lua_isstring(L, 1)) luax_convobj(L, 1, "filesystem", "newFile"); // Get FileData from the File. if (luax_istype(L, 1, FILESYSTEM_FILE_ID)) { File *file = luax_checkfile(L, 1); FileData *data = 0; try { data = file->read(); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } luax_pushtype(L, FILESYSTEM_FILE_DATA_ID, data); data->release(); return 1; } else return luaL_argerror(L, 1, "filename or File expected"); } size_t length = 0; const char *str = luaL_checklstring(L, 1, &length); const char *filename = luaL_checkstring(L, 2); const char *decstr = lua_isstring(L, 3) ? lua_tostring(L, 3) : 0; FileData::Decoder decoder = FileData::FILE; if (decstr && !FileData::getConstant(decstr, decoder)) return luaL_error(L, "Invalid FileData decoder: %s", decstr); FileData *t = 0; switch (decoder) { case FileData::FILE: t = instance()->newFileData((void *)str, (int)length, filename); break; case FileData::BASE64: t = instance()->newFileData(str, filename); break; default: return luaL_error(L, "Invalid FileData decoder: %s", decstr); } luax_pushtype(L, FILESYSTEM_FILE_DATA_ID, t); t->release(); return 1; }
int w_File_write(lua_State *L) { File *file = luax_checkfile(L, 1); bool result = false; if (lua_isstring(L, 2)) { try { size_t datasize = 0; const char *data = lua_tolstring(L, 2, &datasize); if (!lua_isnoneornil(L, 3)) datasize = luaL_checkinteger(L, 3); result = file->write(data, datasize); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } } else if (luax_istype(L, 2, DATA_ID)) { try { love::Data *data = luax_totype<love::Data>(L, 2, DATA_ID); result = file->write(data, luaL_optinteger(L, 3, data->getSize())); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } } else { return luaL_argerror(L, 2, "string or data expected"); } luax_pushboolean(L, result); return 1; }
int w_File_getMode(lua_State *L) { File *file = luax_checkfile(L, 1); File::Mode mode = file->getMode(); const char *str = 0; if (!File::getConstant(mode, str)) return luax_ioError(L, "Unknown file mode."); lua_pushstring(L, str); return 1; }
int w_getSize(lua_State *L) { const char *filename = luaL_checkstring(L, 1); int64 size = -1; try { size = instance()->getSize(filename); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } // Error on failure or if size does not fit into a double precision floating-point number. if (size == -1) return luax_ioError(L, "Could not determine file size."); else if (size >= 0x20000000000000LL) return luax_ioError(L, "Size too large to fit into a Lua number!"); lua_pushnumber(L, (lua_Number) size); return 1; }
int w_File_getSize(lua_State *L) { File *t = luax_checkfile(L, 1); int64 size = -1; try { size = t->getSize(); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } // Push nil on failure or if size does not fit into a double precision floating-point number. if (size == -1) return luax_ioError(L, "Could not determine file size."); else if (size >= 0x20000000000000LL) return luax_ioError(L, "Size is too large."); lua_pushnumber(L, (lua_Number) size); return 1; }
int w_File_getBuffer(lua_State *L) { File *file = luax_checkfile(L, 1); int64 size = 0; File::BufferMode bufmode = file->getBuffer(size); const char *str = 0; if (!File::getConstant(bufmode, str)) return luax_ioError(L, "Unknown file buffer mode."); lua_pushstring(L, str); lua_pushnumber(L, (lua_Number) size); return 2; }
int w_File_flush(lua_State *L) { File *file = luax_checkfile(L, 1); bool success = false; try { success = file->flush(); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } luax_pushboolean(L, success); return 1; }
int w_getLastModified(lua_State *L) { const char *filename = luaL_checkstring(L, 1); int64 time = 0; try { time = instance()->getLastModified(filename); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } lua_pushnumber(L, static_cast<lua_Number>(time)); return 1; }
int w_getRealDirectory(lua_State *L) { const char *filename = luaL_checkstring(L, 1); std::string dir; try { dir = instance()->getRealDirectory(filename); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } lua_pushstring(L, dir.c_str()); return 1; }
int w_File_open(lua_State *L) { File *file = luax_checkfile(L, 1); const char *str = luaL_checkstring(L, 2); File::Mode mode; if (!File::getConstant(str, mode)) return luaL_error(L, "Incorrect file open mode: %s", str); try { luax_pushboolean(L, file->open(mode)); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } return 1; }
int w_File_read(lua_State *L) { File *file = luax_checkfile(L, 1); StrongRef<Data> d = nullptr; int64 size = (int64) luaL_optnumber(L, 2, (lua_Number) File::ALL); try { d.set(file->read(size), Acquire::NORETAIN); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } lua_pushlstring(L, (const char *) d->getData(), d->getSize()); lua_pushnumber(L, d->getSize()); return 2; }
int w_File_setBuffer(lua_State *L) { File *file = luax_checkfile(L, 1); const char *str = luaL_checkstring(L, 2); int64 size = (int64) luaL_optnumber(L, 3, 0.0); File::BufferMode bufmode; if (!File::getConstant(str, bufmode)) return luaL_error(L, "Incorrect file buffer mode: %s", str); bool success = false; try { success = file->setBuffer(bufmode, size); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } luax_pushboolean(L, success); return 1; }
static int w_write_or_append(lua_State *L, File::Mode mode) { const char *filename = luaL_checkstring(L, 1); const char *input = 0; size_t len = 0; if (luax_istype(L, 2, DATA_ID)) { love::Data *data = luax_totype<love::Data>(L, 2, DATA_ID); input = (const char *) data->getData(); len = data->getSize(); } else if (lua_isstring(L, 2)) input = lua_tolstring(L, 2, &len); else return luaL_argerror(L, 2, "string or Data expected"); // Get how much we should write. Length of string default. len = luaL_optinteger(L, 3, len); try { if (mode == File::MODE_APPEND) instance()->append(filename, (const void *) input, len); else instance()->write(filename, (const void *) input, len); } catch (love::Exception &e) { return luax_ioError(L, "%s", e.what()); } luax_pushboolean(L, true); return 1; }