Upgrade love.filesystem to use 64-bit numbers for dealing with file sizes, thus (hopefully) enabling lovers to work with very large files (based on Boolsheet's patch in issue #179)

This commit is contained in:
Bill Meltsner
2011-12-22 02:45:11 -06:00
parent ce682a45c6
commit 7378a90101
8 changed files with 65 additions and 49 deletions
+9 -8
View File
@@ -28,6 +28,7 @@
#include <common/Data.h>
#include <common/Object.h>
#include <common/StringMap.h>
#include <common/int.h>
namespace love
{
@@ -56,7 +57,7 @@ namespace filesystem
/**
* Used to indicate ALL data in a file.
**/
static const int ALL = -1;
static const int64 ALL = -1;
/**
* Destructor.
@@ -83,7 +84,7 @@ namespace filesystem
*
* @return The size of the file.
**/
virtual unsigned int getSize() = 0;
virtual int64 getSize() = 0;
/**
* Reads data from the file and allocates a Data object.
@@ -91,7 +92,7 @@ namespace filesystem
* @param size The number of bytes to attempt reading, or -1 for EOF.
* @return A newly allocated Data object.
**/
virtual Data * read(int size = ALL) = 0;
virtual Data * read(int64 size = ALL) = 0;
/**
* Reads data into the destination buffer.
@@ -100,7 +101,7 @@ namespace filesystem
* @param size The number of bytes to attempt reading.
* @return The number of bytes actually read.
**/
virtual int read(void * dst, int size) = 0;
virtual int64 read(void * dst, int64 size) = 0;
/**
* Writes data into the File.
@@ -109,7 +110,7 @@ namespace filesystem
* @param size The size of the buffer.
* @return True of success, false otherwise.
**/
virtual bool write(const void * data, int size) = 0;
virtual bool write(const void * data, int64 size) = 0;
/**
* Writes a Data object into the File.
@@ -118,7 +119,7 @@ namespace filesystem
* @param size The number of bytes to attempt writing, or -1 for everything.
* @return True of success, false otherwise.
**/
virtual bool write(const Data * data, int size = ALL) = 0;
virtual bool write(const Data * data, int64 size = ALL) = 0;
/**
* Checks whether we are currently at end-of-file.
@@ -132,7 +133,7 @@ namespace filesystem
*
* @return The current byte position in the File.
**/
virtual int tell() = 0;
virtual int64 tell() = 0;
/**
* Seeks to a certain position in the File.
@@ -140,7 +141,7 @@ namespace filesystem
* @param pos The byte position in the file.
* @return True on success, false otherwise.
**/
virtual bool seek(int pos) = 0;
virtual bool seek(uint64 pos) = 0;
/**
* Gets the current mode of the File.
+1 -1
View File
@@ -27,7 +27,7 @@ namespace love
{
namespace filesystem
{
FileData::FileData(int size, const std::string & filename)
FileData::FileData(unsigned int size, const std::string & filename)
: data(new char[size]), size(size), filename(filename)
{
if (filename.rfind('.') != std::string::npos)
+2 -2
View File
@@ -38,7 +38,7 @@ namespace filesystem
char * data;
// Size of the data.
int size;
unsigned int size;
// The filename used for error purposes.
std::string filename;
@@ -55,7 +55,7 @@ namespace filesystem
DECODE_MAX_ENUM
}; // Decoder
FileData(int size, const std::string & filename);
FileData(unsigned int size, const std::string & filename);
virtual ~FileData();
+14 -14
View File
@@ -92,30 +92,30 @@ namespace physfs
return true;
}
unsigned int File::getSize()
int64 File::getSize()
{
// If the file is closed, open it to
// check the size.
if (file == 0)
{
open(READ);
unsigned int size = (unsigned int)PHYSFS_fileLength(file);
int64 size = (int64)PHYSFS_fileLength(file);
close();
return size;
}
return (unsigned int)PHYSFS_fileLength(file);
return (int64)PHYSFS_fileLength(file);
}
Data * File::read(int size)
Data * File::read(int64 size)
{
bool isOpen = (file != 0);
if (!isOpen && !open(READ))
throw love::Exception("Could not read file %s.", filename.c_str());
int max = (int)PHYSFS_fileLength(file);
int64 max = (int64)PHYSFS_fileLength(file);
size = (size == ALL) ? max : size;
size = (size > max) ? max : size;
@@ -129,18 +129,18 @@ namespace physfs
return fileData;
}
int File::read(void * dst, int size)
int64 File::read(void * dst, int64 size)
{
bool isOpen = (file != 0);
if (!isOpen)
open(READ);
int max = (int)PHYSFS_fileLength(file);
int64 max = (int64)PHYSFS_fileLength(file);
size = (size == ALL) ? max : size;
size = (size > max) ? max : size;
int read = (int)PHYSFS_read(file, dst, 1, size);
int64 read = (int64)PHYSFS_read(file, dst, 1, size);
if (!isOpen)
close();
@@ -148,13 +148,13 @@ namespace physfs
return read;
}
bool File::write(const void * data, int size)
bool File::write(const void * data, int64 size)
{
if (file == 0)
throw love::Exception("Could not write to file. File not open.");
// Try to write.
int written = static_cast<int>(PHYSFS_write(file, data, 1, size));
int written = static_cast<int64>(PHYSFS_write(file, data, 1, size));
// Check that correct amount of data was written.
if (written != size)
@@ -163,7 +163,7 @@ namespace physfs
return true;
}
bool File::write(const Data * data, int size)
bool File::write(const Data * data, int64 size)
{
return write(data->getData(), (size == ALL) ? data->getSize() : size);
}
@@ -192,15 +192,15 @@ namespace physfs
return false;
}
int File::tell()
int64 File::tell()
{
if (file == 0)
return -1;
return (int)PHYSFS_tell(file);
return (int64)PHYSFS_tell(file);
}
bool File::seek(int pos)
bool File::seek(uint64 pos)
{
if (file == 0)
return false;
+7 -7
View File
@@ -67,14 +67,14 @@ namespace physfs
// Implements love::filesystem::File.
bool open(Mode mode);
bool close();
unsigned int getSize();
Data * read(int size = ALL);
int read(void * dst, int size);
bool write(const void * data, int size);
bool write(const Data * data, int size = ALL);
int64 getSize();
Data * read(int64 size = ALL);
int64 read(void * dst, int64 size);
bool write(const void * data, int64 size);
bool write(const Data * data, int64 size = ALL);
bool eof();
int tell();
bool seek(int pos);
int64 tell();
bool seek(uint64 pos);
Mode getMode();
std::string getFilename() const;
std::string getExtension() const;
+2 -2
View File
@@ -169,7 +169,7 @@ namespace physfs
return new File(filename);
}
FileData * Filesystem::newFileData(void * data, int size, const char * filename)
FileData * Filesystem::newFileData(void * data, unsigned int size, const char * filename)
{
FileData * fd = new FileData(size, std::string(filename));
@@ -315,7 +315,7 @@ namespace physfs
// Optionally, the caller can specify whether to read
// the whole file, or just a part of it.
int count = luaL_optint(L, 2, file->getSize());
int count = luaL_optint(L, 2, (lua_Integer)file->getSize()); // FIXME
// Read the data.
Data * data = file->read(count);
+3 -2
View File
@@ -30,6 +30,7 @@
// LOVE
#include <common/Module.h>
#include <common/config.h>
#include <common/int.h>
#include <filesystem/FileData.h>
#include "File.h"
@@ -153,7 +154,7 @@ namespace physfs
* @param size The size of the data.
* @param filename The full filename used to file type identification.
**/
FileData * newFileData(void * data, int size, const char * filename);
FileData * newFileData(void * data, unsigned int size, const char * filename);
/**
* Creates a new FileData object from base64 data.
@@ -261,7 +262,7 @@ namespace physfs
* Seek to a position within a file.
* @param pos The position to seek to.
**/
bool seek(File * file, int pos);
bool seek(File * file, uint64 pos);
/**
* This "native" method returns a table of all
+27 -13
View File
@@ -22,6 +22,7 @@
#include <common/Data.h>
#include <common/Exception.h>
#include <common/int.h>
namespace love
{
@@ -37,14 +38,14 @@ namespace physfs
int w_File_getSize(lua_State * L)
{
File * t = luax_checkfile(L, 1);
try
{
lua_pushinteger(L, t->getSize());
}
catch (Exception & e)
{
return luaL_error(L, e.what());
}
int64 size = t->getSize();
// Push nil on failure or if size does not fit into a double precision floating-point number.
if (size == -1 || size >= 0x20000000000000LL)
lua_pushnil(L);
else
lua_pushnumber(L, (lua_Number)size);
return 1;
}
@@ -79,10 +80,12 @@ namespace physfs
{
File * file = luax_checkfile(L, 1);
Data * d = 0;
int64 size = (int64)luaL_optnumber(L, 2, file->getSize());
try
{
d = file->read(luaL_optint(L, 2, file->getSize()));
d = file->read(size);
}
catch (Exception e)
{
@@ -136,22 +139,33 @@ namespace physfs
int w_File_eof(lua_State * L)
{
File * file = luax_checkfile(L, 1);
lua_pushboolean(L, file->eof() ? 1 : 0);
luax_pushboolean(L, file->eof());
return 1;
}
int w_File_tell(lua_State * L)
{
File * file = luax_checkfile(L, 1);
lua_pushinteger(L, file->tell());
int64 pos = file->tell();
// Push nil on failure or if pos does not fit into a double precision floating-point number.
if (pos == -1 || pos >= 0x20000000000000LL)
lua_pushnil(L);
else
lua_pushnumber(L, (lua_Number)pos);
return 1;
}
int w_File_seek(lua_State * L)
{
File * file = luax_checkfile(L, 1);
int pos = luaL_checkinteger(L, 2);
lua_pushboolean(L, file->seek(pos) ? 1 : 0);
lua_Number pos = luaL_checknumber(L, 2);
// Push false on negative and precision-problematic numbers.
// Better fail than seek to an unknown position.
if (pos < 0.0 || pos >= 9007199254740992.0)
luax_pushboolean(L, false);
else
luax_pushboolean(L, file->seek((uint64)pos));
return 1;
}