aboutsummaryrefslogtreecommitdiff
path: root/backends/fs/ds
diff options
context:
space:
mode:
authorMax Horn2009-03-19 09:51:40 +0000
committerMax Horn2009-03-19 09:51:40 +0000
commitb5bcc1a23af73761f6ff40f79db0a5beb8ae82f1 (patch)
tree6ddd0d5b8e01a63fdcbc1b1c9d1a1a0739a1966d /backends/fs/ds
parent8dc12da206cc850b3bd2bd456e4607ded695704d (diff)
downloadscummvm-rg350-b5bcc1a23af73761f6ff40f79db0a5beb8ae82f1.tar.gz
scummvm-rg350-b5bcc1a23af73761f6ff40f79db0a5beb8ae82f1.tar.bz2
scummvm-rg350-b5bcc1a23af73761f6ff40f79db0a5beb8ae82f1.zip
Merged Neil's NDS changes into trunk
svn-id: r39526
Diffstat (limited to 'backends/fs/ds')
-rw-r--r--backends/fs/ds/ds-fs.cpp114
-rw-r--r--backends/fs/ds/ds-fs.h36
2 files changed, 140 insertions, 10 deletions
diff --git a/backends/fs/ds/ds-fs.cpp b/backends/fs/ds/ds-fs.cpp
index 79f10fdb62..92bdba0650 100644
--- a/backends/fs/ds/ds-fs.cpp
+++ b/backends/fs/ds/ds-fs.cpp
@@ -197,11 +197,11 @@ AbstractFSNode* DSFileSystemNode::getParent() const {
}
Common::SeekableReadStream *DSFileSystemNode::createReadStream() {
- return StdioStream::makeFromPath(getPath().c_str(), false);
+ return DSFileStream::makeFromPath(getPath().c_str(), false);
}
Common::WriteStream *DSFileSystemNode::createWriteStream() {
- return StdioStream::makeFromPath(getPath().c_str(), true);
+ return DSFileStream::makeFromPath(getPath().c_str(), true);
}
//////////////////////////////////////////////////////////////////////////
@@ -211,9 +211,8 @@ Common::WriteStream *DSFileSystemNode::createWriteStream() {
GBAMPFileSystemNode::GBAMPFileSystemNode() {
_displayName = "mp:/";
_path = "mp:/";
- _isValid = true;
+ _isValid = false;
_isDirectory = true;
- _path = "mp:/";
}
GBAMPFileSystemNode::GBAMPFileSystemNode(const Common::String& path) {
@@ -283,9 +282,9 @@ GBAMPFileSystemNode::GBAMPFileSystemNode(const GBAMPFileSystemNode* node) {
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;
@@ -376,16 +375,113 @@ Common::SeekableReadStream *GBAMPFileSystemNode::createReadStream() {
// 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::createWriteStream() {
- 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
diff --git a/backends/fs/ds/ds-fs.h b/backends/fs/ds/ds-fs.h
index beea422a14..c8bf7d6cf2 100644
--- a/backends/fs/ds/ds-fs.h
+++ b/backends/fs/ds/ds-fs.h
@@ -27,7 +27,6 @@
#include "common/fs.h"
#include "zipreader.h"
#include "ramsave.h"
-#include "scummconsole.h"
#include "fat/gba_nds_fat.h"
#include "backends/fs/abstract-fs.h"
@@ -168,6 +167,41 @@ struct fileHandle {
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