[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