mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
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:
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user