[Scummvm-cvs-logs] SF.net SVN: scummvm:[39264] scummvm/branches/branch-0-13-0/backends/fs/ds

agent-q at users.sourceforge.net agent-q at users.sourceforge.net
Mon Mar 9 17:42:10 CET 2009


Revision: 39264
          http://scummvm.svn.sourceforge.net/scummvm/?rev=39264&view=rev
Author:   agent-q
Date:     2009-03-09 16:42:10 +0000 (Mon, 09 Mar 2009)

Log Message:
-----------
DS: Implement FileStream, and cache writes to improve performance.

Modified Paths:
--------------
    scummvm/branches/branch-0-13-0/backends/fs/ds/ds-fs.cpp
    scummvm/branches/branch-0-13-0/backends/fs/ds/ds-fs.h

Modified: scummvm/branches/branch-0-13-0/backends/fs/ds/ds-fs.cpp
===================================================================
--- scummvm/branches/branch-0-13-0/backends/fs/ds/ds-fs.cpp	2009-03-09 16:15:35 UTC (rev 39263)
+++ scummvm/branches/branch-0-13-0/backends/fs/ds/ds-fs.cpp	2009-03-09 16:42:10 UTC (rev 39264)
@@ -207,11 +207,11 @@
 }
 
 Common::SeekableReadStream *DSFileSystemNode::openForReading() {
-	return StdioStream::makeFromPath(getPath().c_str(), false);
+	return DSFileStream::makeFromPath(getPath().c_str(), false);
 }
 
 Common::WriteStream *DSFileSystemNode::openForWriting() {
-	return StdioStream::makeFromPath(getPath().c_str(), true);
+	return DSFileStream::makeFromPath(getPath().c_str(), true);
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -221,9 +221,8 @@
 GBAMPFileSystemNode::GBAMPFileSystemNode() {
 	_displayName = "mp:/";
 	_path = "mp:/";
-	_isValid = true;
+	_isValid = false;
 	_isDirectory = true;
-	_path = "mp:/";
 }
 
 GBAMPFileSystemNode::GBAMPFileSystemNode(const Common::String& path) {
@@ -314,9 +313,9 @@
 
 AbstractFSNode *GBAMPFileSystemNode::getChild(const Common::String& n) const {
 	if (_path.lastChar() == '\\') {
-		return new DSFileSystemNode(_path + n);
+		return new GBAMPFileSystemNode(_path + n);
 	} else {
-		return new DSFileSystemNode(_path + "\\" + n);
+		return new GBAMPFileSystemNode(_path + "\\" + n);
 	}
 
 	return NULL;
@@ -407,16 +406,113 @@
 //	consolePrintf("Opening: %s\n", getPath().c_str());
 
 	if (!strncmp(getPath().c_str(), "mp:/", 4)) {
-		return StdioStream::makeFromPath(getPath().c_str() + 3, false);
+		return DSFileStream::makeFromPath(getPath().c_str() + 3, false);
 	} else {
-		return StdioStream::makeFromPath(getPath().c_str(), false);
+		return DSFileStream::makeFromPath(getPath().c_str(), false);
 	}
 }
 
 Common::WriteStream *GBAMPFileSystemNode::openForWriting() {
-	return StdioStream::makeFromPath(getPath().c_str(), true);
+	return DSFileStream::makeFromPath(getPath().c_str(), true);
 }
 
+
+
+
+DSFileStream::DSFileStream(void *handle) : _handle(handle) {
+	assert(handle);
+	_writeBufferPos = 0;
+}
+
+DSFileStream::~DSFileStream() {
+	if (_writeBufferPos > 0) {
+		flush();
+	}
+	std_fclose((FILE *)_handle);
+}
+
+bool DSFileStream::err() const {
+	return std_ferror((FILE *)_handle) != 0;
+}
+
+void DSFileStream::clearErr() {
+	std_clearerr((FILE *)_handle);
+}
+
+bool DSFileStream::eos() const {
+	return std_feof((FILE *)_handle) != 0;
+}
+
+int32 DSFileStream::pos() const {
+	if (_writeBufferPos > 0) {
+		// Discard constness.  Bad, but I can't see another way.
+		((DSFileStream *) (this))->flush();
+	}
+	return std_ftell((FILE *)_handle);
+}
+
+int32 DSFileStream::size() const {
+	if (_writeBufferPos > 0) {
+		// Discard constness.  Bad, but I can't see another way.
+		((DSFileStream *) (this))->flush();
+	}
+	int32 oldPos = std_ftell((FILE *)_handle);
+	std_fseek((FILE *)_handle, 0, SEEK_END);
+	int32 length = std_ftell((FILE *)_handle);
+	std_fseek((FILE *)_handle, oldPos, SEEK_SET);
+
+	return length;
+}
+
+bool DSFileStream::seek(int32 offs, int whence) {
+	if (_writeBufferPos > 0) {
+		flush();
+	}
+	return std_fseek((FILE *)_handle, offs, whence) == 0;
+}
+
+uint32 DSFileStream::read(void *ptr, uint32 len) {
+	if (_writeBufferPos > 0) {
+		flush();
+	}
+	return std_fread((byte *)ptr, 1, len, (FILE *)_handle);
+}
+
+uint32 DSFileStream::write(const void *ptr, uint32 len) {
+	if (_writeBufferPos + len < WRITE_BUFFER_SIZE) {
+		memcpy(_writeBuffer + _writeBufferPos, ptr, len);
+		_writeBufferPos += len;
+	}
+	else
+	{
+		if (_writeBufferPos > 0) {
+			flush();
+		}
+		return std_fwrite(ptr, 1, len, (FILE *)_handle);
+	}
+}
+
+bool DSFileStream::flush() {
+
+	if (_writeBufferPos > 0) {
+		std_fwrite(_writeBuffer, 1, _writeBufferPos, (FILE *) _handle);
+		_writeBufferPos = 0;
+	}
+
+	return std_fflush((FILE *)_handle) == 0;
+}
+
+DSFileStream *DSFileStream::makeFromPath(const Common::String &path, bool writeMode) {
+	FILE *handle = std_fopen(path.c_str(), writeMode ? "wb" : "rb");
+
+	if (handle)
+		return new DSFileStream(handle);
+	return 0;
+}
+
+
+
+
 // Stdio replacements
 #define MAX_FILE_HANDLES 32
 

Modified: scummvm/branches/branch-0-13-0/backends/fs/ds/ds-fs.h
===================================================================
--- scummvm/branches/branch-0-13-0/backends/fs/ds/ds-fs.h	2009-03-09 16:15:35 UTC (rev 39263)
+++ scummvm/branches/branch-0-13-0/backends/fs/ds/ds-fs.h	2009-03-09 16:42:10 UTC (rev 39264)
@@ -168,6 +168,41 @@
 	DSSaveFile* sramFile;
 };
 
+
+class DSFileStream : public Common::SeekableReadStream, public Common::WriteStream, public Common::NonCopyable {
+protected:
+	static const int WRITE_BUFFER_SIZE = 512;
+
+	/** File handle to the actual file. */
+	void 	*_handle;
+
+	char	_writeBuffer[WRITE_BUFFER_SIZE];
+	int	_writeBufferPos;
+
+public:
+	/**
+	 * Given a path, invokes fopen on that path and wrap the result in a
+	 * StdioStream instance.
+	 */
+	static DSFileStream *makeFromPath(const Common::String &path, bool writeMode);
+
+	DSFileStream(void *handle);
+	virtual ~DSFileStream();
+
+	bool err() const;
+	void clearErr();
+	bool eos() const;
+
+	virtual uint32 write(const void *dataPtr, uint32 dataSize);
+	virtual bool flush();
+
+	virtual int32 pos() const;
+	virtual int32 size() const;
+	bool seek(int32 offs, int whence = SEEK_SET);
+	uint32 read(void *dataPtr, uint32 dataSize);
+};
+
+
 #undef stderr
 #undef stdout
 #undef stdin


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list