Browse Source

Make most love.filesystem functions return nil, err instead of erroring (when used correctly)

Note that argument exceptions, for instance, are still thrown as errors.
Also fixes a potential uncaught exception with getSize being called for the optional
size arg in read, now it just uses the ALL constant instead.
File:read no longer opens and closes a file automagically (this was undocumented, and weird)

NOTE: the love.filesystem.lines iterator can still error, but this should only happen in
case there's something really, really wrong (otherwise love.filesystem.lines would've failed
already)
NOTE: love.filesystem.lines still errors, because otherwise you'd get weird errors from the for
loop (namely 'attempt to call nil value') instead of seeing anything useful
Bart van Strien 12 years ago
parent
commit
721d50c2ef

+ 4 - 9
src/modules/filesystem/physfs/File.cpp

@@ -155,10 +155,8 @@ FileData *File::read(int64 size)
 
 
 int64 File::read(void *dst, int64 size)
 int64 File::read(void *dst, int64 size)
 {
 {
-	bool isOpen = (file != 0);
-
-	if (!isOpen)
-		open(READ);
+	if (!file || mode != READ)
+		throw love::Exception("File is not opened for reading.");
 
 
 	int64 max = (int64)PHYSFS_fileLength(file);
 	int64 max = (int64)PHYSFS_fileLength(file);
 	size = (size == ALL) ? max : size;
 	size = (size == ALL) ? max : size;
@@ -168,16 +166,13 @@ int64 File::read(void *dst, int64 size)
 
 
 	int64 read = (int64)PHYSFS_read(file, dst, 1, (int) size);
 	int64 read = (int64)PHYSFS_read(file, dst, 1, (int) size);
 
 
-	if (!isOpen)
-		close();
-
 	return read;
 	return read;
 }
 }
 
 
 bool File::write(const void *data, int64 size)
 bool File::write(const void *data, int64 size)
 {
 {
-	if (file == 0)
-		throw love::Exception("Could not write to file. File not open.");
+	if (!file || (mode != WRITE && mode != APPEND))
+		throw love::Exception("File is not opened for writing.");
 
 
 	// Another clamp, for the time being.
 	// Another clamp, for the time being.
 	size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size;
 	size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size;

+ 17 - 7
src/modules/filesystem/physfs/wrap_File.cpp

@@ -24,6 +24,18 @@
 #include "common/Exception.h"
 #include "common/Exception.h"
 #include "common/int.h"
 #include "common/int.h"
 
 
+static int ioError(lua_State *L, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+
+	lua_pushnil(L);
+	lua_pushvfstring(L, fmt, args);
+
+	va_end(args);
+	return 2;
+}
+
 namespace love
 namespace love
 {
 {
 namespace filesystem
 namespace filesystem
@@ -65,7 +77,7 @@ int w_File_open(lua_State *L)
 	}
 	}
 	catch (love::Exception &e)
 	catch (love::Exception &e)
 	{
 	{
-		return luaL_error(L, "%s", e.what());
+		return ioError(L, "%s", e.what());
 	}
 	}
 
 
 	return 1;
 	return 1;
@@ -83,7 +95,7 @@ int w_File_read(lua_State *L)
 	File *file = luax_checkfile(L, 1);
 	File *file = luax_checkfile(L, 1);
 	Data *d = 0;
 	Data *d = 0;
 
 
-	int64 size = (int64)luaL_optnumber(L, 2, (lua_Number) file->getSize());
+	int64 size = (int64)luaL_optnumber(L, 2, File::ALL);
 
 
 	try
 	try
 	{
 	{
@@ -91,7 +103,7 @@ int w_File_read(lua_State *L)
 	}
 	}
 	catch (love::Exception &e)
 	catch (love::Exception &e)
 	{
 	{
-		return luaL_error(L, "%s", e.what());
+		return ioError(L, "%s", e.what());
 	}
 	}
 
 
 	lua_pushlstring(L, (const char *) d->getData(), d->getSize());
 	lua_pushlstring(L, (const char *) d->getData(), d->getSize());
@@ -104,8 +116,6 @@ int w_File_write(lua_State *L)
 {
 {
 	File *file = luax_checkfile(L, 1);
 	File *file = luax_checkfile(L, 1);
 	bool result;
 	bool result;
-	if (file->getMode() == File::CLOSED)
-		return luaL_error(L, "File is not open.");
 
 
 	if (lua_isstring(L, 2))
 	if (lua_isstring(L, 2))
 	{
 	{
@@ -115,7 +125,7 @@ int w_File_write(lua_State *L)
 		}
 		}
 		catch (love::Exception &e)
 		catch (love::Exception &e)
 		{
 		{
-			return luaL_error(L, "%s", e.what());
+			return ioError(L, "%s", e.what());
 		}
 		}
 
 
 	}
 	}
@@ -128,7 +138,7 @@ int w_File_write(lua_State *L)
 		}
 		}
 		catch (love::Exception &e)
 		catch (love::Exception &e)
 		{
 		{
-			return luaL_error(L, "%s", e.what());
+			return ioError(L, "%s", e.what());
 		}
 		}
 	}
 	}
 	else
 	else

+ 20 - 8
src/modules/filesystem/physfs/wrap_Filesystem.cpp

@@ -21,6 +21,18 @@
 // LOVE
 // LOVE
 #include "wrap_Filesystem.h"
 #include "wrap_Filesystem.h"
 
 
+static int ioError(lua_State *L, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+
+	lua_pushnil(L);
+	lua_pushvfstring(L, fmt, args);
+
+	va_end(args);
+	return 2;
+}
+
 namespace love
 namespace love
 {
 {
 namespace filesystem
 namespace filesystem
@@ -113,7 +125,7 @@ int w_newFile(lua_State *L)
 		catch (love::Exception &e)
 		catch (love::Exception &e)
 		{
 		{
 			t->release();
 			t->release();
-			return luaL_error(L, "%s", e.what());
+			return ioError(L, "%s", e.what());
 		}
 		}
 	}
 	}
 
 
@@ -141,7 +153,7 @@ int w_newFileData(lua_State *L)
 			}
 			}
 			catch (love::Exception &e)
 			catch (love::Exception &e)
 			{
 			{
-				return luaL_error(L, "%s", e.what());
+				return ioError(L, "%s", e.what());
 			}
 			}
 			luax_newtype(L, "FileData", FILESYSTEM_FILE_DATA_T, (void *) data);
 			luax_newtype(L, "FileData", FILESYSTEM_FILE_DATA_T, (void *) data);
 			return 1;
 			return 1;
@@ -249,11 +261,11 @@ int w_read(lua_State *L)
 	}
 	}
 	catch (love::Exception &e)
 	catch (love::Exception &e)
 	{
 	{
-		return luaL_error(L, "%s", e.what());
+		return ioError(L, "%s", e.what());
 	}
 	}
 
 
 	if (data == 0)
 	if (data == 0)
-		return luaL_error(L, "File could not be read.");
+		return ioError(L, "File could not be read.");
 
 
 	// Push the string.
 	// Push the string.
 	lua_pushlstring(L, (const char *) data->getData(), data->getSize());
 	lua_pushlstring(L, (const char *) data->getData(), data->getSize());
@@ -297,7 +309,7 @@ static int w_write_or_append(lua_State *L, File::Mode mode)
 	}
 	}
 	catch (love::Exception &e)
 	catch (love::Exception &e)
 	{
 	{
-		return luaL_error(L, "%s", e.what());
+		return ioError(L, "%s", e.what());
 	}
 	}
 
 
 	luax_pushboolean(L, true);
 	luax_pushboolean(L, true);
@@ -356,7 +368,7 @@ int w_load(lua_State *L)
 	}
 	}
 	catch (love::Exception &e)
 	catch (love::Exception &e)
 	{
 	{
-		return luaL_error(L, "%s", e.what());
+		return ioError(L, "%s", e.what());
 	}
 	}
 
 
 	int status = luaL_loadbuffer(L, (const char *)data->getData(), data->getSize(), ("@" + filename).c_str());
 	int status = luaL_loadbuffer(L, (const char *)data->getData(), data->getSize(), ("@" + filename).c_str());
@@ -407,12 +419,12 @@ int w_getSize(lua_State *L)
 	}
 	}
 	catch (love::Exception &e)
 	catch (love::Exception &e)
 	{
 	{
-		return luaL_error(L, "%s", e.what());
+		return ioError(L, "%s", e.what());
 	}
 	}
 
 
 	// Error on failure or if size does not fit into a double precision floating-point number.
 	// Error on failure or if size does not fit into a double precision floating-point number.
 	if (size == -1)
 	if (size == -1)
-		return luaL_error(L, "Could not determine file size.");
+		return ioError(L, "Could not determine file size.");
 	else if (size >= 0x20000000000000LL)
 	else if (size >= 0x20000000000000LL)
 		return luaL_error(L, "Size too large to fit into a Lua number!");
 		return luaL_error(L, "Size too large to fit into a Lua number!");