Browse Source

love.filesystem.mount can accept a Data object containing zipped data.

- Add mount(Data, archivename, mountpoint [, appendtopath]). 'archivename' must be a string that has not been used with mount before.
- Add mount(FileData, mountpoint [, appendtopath]). The file path of the FileData is used as the archive name.
- Add unmount(Data).
- unmount(archivename) also works.
Alex Szpakowski 7 years ago
parent
commit
640e8f0d2e

+ 2 - 0
src/modules/filesystem/Filesystem.h

@@ -135,7 +135,9 @@ public:
 	virtual const char *getSource() const = 0;
 	virtual const char *getSource() const = 0;
 
 
 	virtual bool mount(const char *archive, const char *mountpoint, bool appendToPath = false) = 0;
 	virtual bool mount(const char *archive, const char *mountpoint, bool appendToPath = false) = 0;
+	virtual bool mount(Data *data, const char *archivename, const char *mountpoint, bool appendToPath = false) = 0;
 	virtual bool unmount(const char *archive) = 0;
 	virtual bool unmount(const char *archive) = 0;
+	virtual bool unmount(Data *data) = 0;
 
 
 	/**
 	/**
 	 * Creates a new file.
 	 * Creates a new file.

+ 36 - 0
src/modules/filesystem/physfs/Filesystem.cpp

@@ -397,11 +397,33 @@ bool Filesystem::mount(const char *archive, const char *mountpoint, bool appendT
 	return PHYSFS_mount(realPath.c_str(), mountpoint, appendToPath) != 0;
 	return PHYSFS_mount(realPath.c_str(), mountpoint, appendToPath) != 0;
 }
 }
 
 
+bool Filesystem::mount(Data *data, const char *archivename, const char *mountpoint, bool appendToPath)
+{
+	if (!PHYSFS_isInit())
+		return false;
+
+	if (PHYSFS_mountMemory(data->getData(), data->getSize(), nullptr, archivename, mountpoint, appendToPath) != 0)
+	{
+		mountedData[archivename] = data;
+		return true;
+	}
+
+	return false;
+}
+
 bool Filesystem::unmount(const char *archive)
 bool Filesystem::unmount(const char *archive)
 {
 {
 	if (!PHYSFS_isInit() || !archive)
 	if (!PHYSFS_isInit() || !archive)
 		return false;
 		return false;
 
 
+	auto datait = mountedData.find(archive);
+
+	if (datait != mountedData.end() && PHYSFS_unmount(archive) != 0)
+	{
+		mountedData.erase(datait);
+		return true;
+	}
+
 	std::string realPath;
 	std::string realPath;
 	std::string sourceBase = getSourceBaseDirectory();
 	std::string sourceBase = getSourceBaseDirectory();
 
 
@@ -438,6 +460,20 @@ bool Filesystem::unmount(const char *archive)
 	return PHYSFS_unmount(realPath.c_str()) != 0;
 	return PHYSFS_unmount(realPath.c_str()) != 0;
 }
 }
 
 
+bool Filesystem::unmount(Data *data)
+{
+	for (const auto &datapair : mountedData)
+	{
+		if (datapair.second.get() == data)
+		{
+			std::string archive = datapair.first;
+			return unmount(archive.c_str());
+		}
+	}
+
+	return false;
+}
+
 love::filesystem::File *Filesystem::newFile(const char *filename) const
 love::filesystem::File *Filesystem::newFile(const char *filename) const
 {
 {
 	return new File(filename);
 	return new File(filename);

+ 37 - 31
src/modules/filesystem/physfs/Filesystem.h

@@ -24,6 +24,7 @@
 // STD
 // STD
 #include <cstdlib>
 #include <cstdlib>
 #include <cstring>
 #include <cstring>
+#include <map>
 
 
 // LOVE
 // LOVE
 #include "filesystem/Filesystem.h"
 #include "filesystem/Filesystem.h"
@@ -35,7 +36,7 @@ namespace filesystem
 namespace physfs
 namespace physfs
 {
 {
 
 
-class Filesystem : public love::filesystem::Filesystem
+class Filesystem final : public love::filesystem::Filesystem
 {
 {
 public:
 public:
 
 
@@ -43,54 +44,57 @@ public:
 	virtual ~Filesystem();
 	virtual ~Filesystem();
 
 
 	// Implements Module.
 	// Implements Module.
-	const char *getName() const;
+	const char *getName() const override;
 
 
-	void init(const char *arg0);
+	void init(const char *arg0) override;
 
 
-	void setFused(bool fused);
-	bool isFused() const;
+	void setFused(bool fused) override;
+	bool isFused() const override;
 
 
-	bool setupWriteDirectory();
+	bool setupWriteDirectory() override;
 
 
-	bool setIdentity(const char *ident, bool appendToPath = false);
-	const char *getIdentity() const;
+	bool setIdentity(const char *ident, bool appendToPath = false) override;
+	const char *getIdentity() const override;
 
 
-	bool setSource(const char *source);
+	bool setSource(const char *source) override;
 
 
-	const char *getSource() const;
+	const char *getSource() const override;
 
 
-	bool mount(const char *archive, const char *mountpoint, bool appendToPath = false);
-	bool unmount(const char *archive);
+	bool mount(const char *archive, const char *mountpoint, bool appendToPath = false) override;
+	bool mount(Data *data, const char *archivename, const char *mountpoint, bool appendToPath = false) override;
 
 
-	love::filesystem::File *newFile(const char *filename) const;
+	bool unmount(const char *archive) override;
+	bool unmount(Data *data) override;
 
 
-	const char *getWorkingDirectory();
-	std::string getUserDirectory();
-	std::string getAppdataDirectory();
-	const char *getSaveDirectory();
-	std::string getSourceBaseDirectory() const;
+	love::filesystem::File *newFile(const char *filename) const override;
 
 
-	std::string getRealDirectory(const char *filename) const;
+	const char *getWorkingDirectory() override;
+	std::string getUserDirectory() override;
+	std::string getAppdataDirectory() override;
+	const char *getSaveDirectory() override;
+	std::string getSourceBaseDirectory() const override;
 
 
-	bool getInfo(const char *filepath, Info &info) const;
+	std::string getRealDirectory(const char *filename) const override;
 
 
-	bool createDirectory(const char *dir);
+	bool getInfo(const char *filepath, Info &info) const override;
 
 
-	bool remove(const char *file);
+	bool createDirectory(const char *dir) override;
 
 
-	FileData *read(const char *filename, int64 size = File::ALL) const;
-	void write(const char *filename, const void *data, int64 size) const;
-	void append(const char *filename, const void *data, int64 size) const;
+	bool remove(const char *file) override;
 
 
-	void getDirectoryItems(const char *dir, std::vector<std::string> &items);
+	FileData *read(const char *filename, int64 size = File::ALL) const override;
+	void write(const char *filename, const void *data, int64 size) const override;
+	void append(const char *filename, const void *data, int64 size) const override;
 
 
-	void setSymlinksEnabled(bool enable);
-	bool areSymlinksEnabled() const;
+	void getDirectoryItems(const char *dir, std::vector<std::string> &items) override;
 
 
-	std::vector<std::string> &getRequirePath();
-	std::vector<std::string> &getCRequirePath();
+	void setSymlinksEnabled(bool enable) override;
+	bool areSymlinksEnabled() const override;
 
 
-	void allowMountingForPath(const std::string &path);
+	std::vector<std::string> &getRequirePath() override;
+	std::vector<std::string> &getCRequirePath() override;
+
+	void allowMountingForPath(const std::string &path) override;
 
 
 private:
 private:
 
 
@@ -123,6 +127,8 @@ private:
 
 
 	std::vector<std::string> allowedMountPaths;
 	std::vector<std::string> allowedMountPaths;
 
 
+	std::map<std::string, StrongRef<Data>> mountedData;
+
 }; // Filesystem
 }; // Filesystem
 
 
 } // physfs
 } // physfs

+ 33 - 4
src/modules/filesystem/wrap_Filesystem.cpp

@@ -116,7 +116,29 @@ int w_mount(lua_State *L)
 {
 {
 	std::string archive;
 	std::string archive;
 
 
-	if (luax_istype(L, 1, DroppedFile::type))
+	if (luax_istype(L, 1, Data::type))
+	{
+		Data *data = love::data::luax_checkdata(L, 1);
+		int startidx = 2;
+
+		if (luax_istype(L, 1, FileData::type) && !lua_isstring(L, 3))
+		{
+			FileData *filedata = luax_checkfiledata(L, 1);
+			archive = filedata->getFilename();
+			startidx = 2;
+		}
+		else
+		{
+			archive = luax_checkstring(L, 2);
+			startidx = 3;
+		}
+
+		const char *mountpoint = luaL_checkstring(L, startidx + 0);
+		bool append = luax_optboolean(L, startidx + 1, false);
+
+		luax_pushboolean(L, instance()->mount(data, archive.c_str(), mountpoint, append));
+	}
+	else if (luax_istype(L, 1, DroppedFile::type))
 	{
 	{
 		DroppedFile *file = luax_totype<DroppedFile>(L, 1);
 		DroppedFile *file = luax_totype<DroppedFile>(L, 1);
 		archive = file->getFilename();
 		archive = file->getFilename();
@@ -133,9 +155,16 @@ int w_mount(lua_State *L)
 
 
 int w_unmount(lua_State *L)
 int w_unmount(lua_State *L)
 {
 {
-	const char *archive = luaL_checkstring(L, 1);
-
-	luax_pushboolean(L, instance()->unmount(archive));
+	if (luax_istype(L, 1, Data::type))
+	{
+		Data *data = love::data::luax_checkdata(L, 1);
+		luax_pushboolean(L, instance()->unmount(data));
+	}
+	else
+	{
+		const char *archive = luaL_checkstring(L, 1);
+		luax_pushboolean(L, instance()->unmount(archive));
+	}
 	return 1;
 	return 1;
 }
 }