aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/file.cpp65
-rw-r--r--common/file.h2
-rw-r--r--common/savefile.cpp12
-rw-r--r--common/savefile.h5
-rw-r--r--common/stream.cpp61
-rw-r--r--common/stream.h55
-rw-r--r--kyra/script.cpp5
-rw-r--r--saga/sprite.cpp2
-rw-r--r--scumm/util.h2
-rw-r--r--simon/saveload.cpp2
-rw-r--r--sound/softsynth/mt32.cpp2
-rw-r--r--sword2/function.cpp2
12 files changed, 126 insertions, 89 deletions
diff --git a/common/file.cpp b/common/file.cpp
index f3241cdf6e..85cd75fd51 100644
--- a/common/file.cpp
+++ b/common/file.cpp
@@ -278,68 +278,3 @@ uint32 File::write(const void *ptr, uint32 len) {
return len;
}
-
-#define LF 0x0A
-#define CR 0x0D
-
-char *File::gets(void *ptr, uint32 len) {
- char *ptr2 = (char *)ptr;
- char *res = ptr2;
- uint32 read_chars = 1;
-
- if (_handle == NULL) {
- error("File::gets: File is not open!");
- return 0;
- }
-
- if (len == 0 || !ptr)
- return NULL;
-
- // We don't include the newline character(s) in the buffer, and we
- // always terminate it - we never read more than len-1 characters.
-
- // EOF is treated as a line break, unless it was the first character
- // that was read.
-
- // 0 is treated as a line break, even though it should never occur in
- // a text file.
-
- // DOS and Windows use CRLF line breaks
- // Unix and OS X use LF line breaks
- // Macintosh before OS X uses CR line breaks
-
- bool first = true;
-
- while (read_chars < len) {
- int c = getc(_handle);
-
- if (c == EOF) {
- if (first)
- return NULL;
- break;
- }
-
- first = false;
-
- if (c == 0)
- break;
-
- if (c == LF)
- break;
-
- if (c == CR) {
- c = getc(_handle);
- // Don't use ungetc() here. It might be slightly more
- // elegant, but PalmOS doesn't have it.
- if (c != LF && c != EOF)
- fseek(_handle, -1, SEEK_CUR);
- break;
- }
-
- *ptr2++ = (char) c;
- read_chars++;
- }
-
- *ptr2 = 0;
- return res;
-}
diff --git a/common/file.h b/common/file.h
index 803d0d5905..cda98bac10 100644
--- a/common/file.h
+++ b/common/file.h
@@ -66,6 +66,7 @@ public:
bool isOpen() const;
bool ioFailed() const;
void clearIOFailed();
+ bool eos() const { return eof(); }
bool eof() const;
uint32 pos() const;
uint32 size() const;
@@ -73,7 +74,6 @@ public:
void seek(int32 offs, int whence = SEEK_SET);
uint32 read(void *ptr, uint32 size);
uint32 write(const void *ptr, uint32 size);
- char *gets(void *ptr, uint32 size);
};
#endif
diff --git a/common/savefile.cpp b/common/savefile.cpp
index 02234a9a78..aa6e54b9f1 100644
--- a/common/savefile.cpp
+++ b/common/savefile.cpp
@@ -73,8 +73,10 @@ public:
::fclose(fh);
}
- bool readingFailed() const { return ferror(fh) != 0; }
- bool writingFailed() const { return ferror(fh) != 0; }
+ bool eos() const { return feof(fh) != 0; }
+ bool ioFailed() const { return ferror(fh) != 0; }
+ void clearIOFailed() { clearerr(fh); }
+
bool isOpen() const { return fh != 0; }
uint32 read(void *buf, uint32 cnt) {
@@ -101,8 +103,10 @@ public:
::gzclose(fh);
}
- bool readingFailed() const { return _ioError; }
- bool writingFailed() const { return _ioError; }
+ bool eos() const { return gzeof(fh) != 0; }
+ bool ioFailed() const { return _ioError; }
+ void clearIOFailed() { _ioError = false; }
+
bool isOpen() const { return fh != 0; }
uint32 read(void *buf, uint32 cnt) {
diff --git a/common/savefile.h b/common/savefile.h
index 2431dba53a..4b4771daa9 100644
--- a/common/savefile.h
+++ b/common/savefile.h
@@ -40,9 +40,6 @@
class InSaveFile : public Common::ReadStream {
public:
virtual ~InSaveFile() {}
-
- virtual bool readingFailed() const { return false; }
- //bool eof() const;
};
/**
@@ -55,8 +52,6 @@ public:
class OutSaveFile : public Common::WriteStream {
public:
virtual ~OutSaveFile() {}
-
- virtual bool writingFailed() const { return false; }
};
/**
diff --git a/common/stream.cpp b/common/stream.cpp
index 62b045fd0d..a9d5793be3 100644
--- a/common/stream.cpp
+++ b/common/stream.cpp
@@ -21,9 +21,13 @@
#include "stdafx.h"
#include "common/stream.h"
+#include "common/str.h"
namespace Common {
+void WriteStream::writeString(const String &str) {
+ write(str.c_str(), str.size());
+}
void MemoryReadStream::seek(int32 offs, int whence) {
// Pre-Condition
@@ -48,5 +52,62 @@ void MemoryReadStream::seek(int32 offs, int whence) {
assert(_pos <= _bufSize);
}
+#define LF 0x0A
+#define CR 0x0D
+
+char *SeekableReadStream::readLine(char *buf, size_t bufSize) {
+ assert(buf && bufSize > 0);
+ char *p = buf;
+ size_t len = 0;
+ char c;
+
+ if (buf == 0 || bufSize == 0 || eos()) {
+ return 0;
+ }
+
+ // We don't include the newline character(s) in the buffer, and we
+ // always terminate it - we never read more than len-1 characters.
+
+ // EOF is treated as a line break, unless it was the first character
+ // that was read.
+
+ // 0 is treated as a line break, even though it should never occur in
+ // a text file.
+
+ // DOS and Windows use CRLF line breaks
+ // Unix and OS X use LF line breaks
+ // Macintosh before OS X uses CR line breaks
+
+
+ c = readByte();
+ if (eos() || ioFailed()) {
+ return 0;
+ }
+
+ while (!eos() && len + 1 < bufSize) {
+
+ if (ioFailed())
+ return 0;
+
+ if (c == 0 || c == LF)
+ break;
+
+ if (c == CR) {
+ c = readByte();
+ if (c != LF && !eos())
+ seek(-1, SEEK_CUR);
+ break;
+ }
+
+ *p++ = c;
+ len++;
+
+ c = readByte();
+ }
+
+ *p = 0;
+ return buf;
+}
+
} // End of namespace Common
diff --git a/common/stream.h b/common/stream.h
index ac0fa18296..7079d8472b 100644
--- a/common/stream.h
+++ b/common/stream.h
@@ -28,10 +28,38 @@
namespace Common {
+class String;
+
+/**
+ * Virtual base class for both ReadStream and WriteStream.
+ */
+class Stream {
+public:
+ /**
+ * Returns true if the end of the stream has been reached.
+ */
+ virtual bool eos() const = 0;
+
+ /**
+ * Returns true if any I/O failure occured.
+ * This flag is never cleared automatically. In order to clear it,
+ * client code has to call clearIOFailed() explicitly.
+ *
+ * @todo Instead of returning a plain bool, maybe we should define
+ * a list of error codes which can be returned here.
+ */
+ virtual bool ioFailed() const { return false; }
+
+ /**
+ * Reset the I/O error status.
+ */
+ virtual void clearIOFailed() {}
+};
+
/**
* Generic interface for a writable data stream.
*/
-class WriteStream {
+class WriteStream : virtual public Stream {
public:
/**
* Write data into the stream. Subclasses must implement this
@@ -90,13 +118,15 @@ public:
void writeSint32BE(int32 value) {
writeUint32BE((uint32)value);
}
+
+ void writeString(const String &str);
};
/**
* Generic interface for a readable data stream.
*/
-class ReadStream {
+class ReadStream : virtual public Stream {
public:
/**
* Read data from the stream. Subclasses must implement this
@@ -175,11 +205,22 @@ public:
class SeekableReadStream : public ReadStream {
public:
- virtual bool eof() const = 0;
virtual uint32 pos() const = 0;
virtual uint32 size() const = 0;
virtual void seek(int32 offs, int whence = SEEK_SET) = 0;
+
+ /**
+ * Read one line of text from a CR or CR/LF terminated plain text file.
+ * This method is a rough analog of the (f)gets function.
+ *
+ * @param buf the buffer to store into
+ * @param size the size of the buffer
+ * @return a pointer to the read string, or NULL if an error occured
+ * @note The line terminator (CR or CR/LF) is stripped and not inserted
+ * into the buffer.
+ */
+ virtual char *readLine(char *buf, size_t bufSize);
};
@@ -200,6 +241,10 @@ public:
void setStream(ReadStream *in) { _realStream = in; }
void setEnc(byte value) { _encbyte = value; }
+ virtual bool eos() const { return _realStream->eos(); }
+ virtual bool ioFailed() const { return _realStream->ioFailed(); }
+ virtual void clearIOFailed() { _realStream->clearIOFailed(); }
+
uint32 read(void *ptr, uint32 size) {
assert(_realStream);
uint32 len = _realStream->read(ptr, size);
@@ -249,7 +294,7 @@ public:
return len;
}
- bool eof() const { return _pos == _bufSize; }
+ bool eos() const { return _pos == _bufSize; }
uint32 pos() const { return _pos; }
uint32 size() const { return _bufSize; }
@@ -279,7 +324,7 @@ public:
return len;
}
- bool eof() const { return _pos == _bufSize; }
+ bool eos() const { return _pos == _bufSize; }
uint32 pos() const { return _pos; }
uint32 size() const { return _bufSize; }
};
diff --git a/kyra/script.cpp b/kyra/script.cpp
index ed071df14c..755ca58925 100644
--- a/kyra/script.cpp
+++ b/kyra/script.cpp
@@ -413,10 +413,7 @@ void VMContext::loadScript(const char* file) {
uint8 chunkName[sizeof("EMC2ORDR") + 1];
// so lets look for our chunks :)
- while(true) {
- if (script.eof()) {
- break;
- }
+ while (!script.eos()) {
// lets read only the first 4 chars
script.read(chunkName, sizeof(uint8) * 4);
chunkName[4] = '\0';
diff --git a/saga/sprite.cpp b/saga/sprite.cpp
index 36ed2cefc3..038e6ba001 100644
--- a/saga/sprite.cpp
+++ b/saga/sprite.cpp
@@ -402,7 +402,7 @@ void Sprite::decodeRLEBuffer(const byte *inputBuffer, size_t inLength, size_t ou
MemoryReadStream readS(inputBuffer, inLength);
- while (!readS.eof() && (outPointer < outPointerEnd)) {
+ while (!readS.eos() && (outPointer < outPointerEnd)) {
bg_runcount = readS.readByte();
fg_runcount = readS.readByte();
diff --git a/scumm/util.h b/scumm/util.h
index 48821755b1..4bef2ebe81 100644
--- a/scumm/util.h
+++ b/scumm/util.h
@@ -100,7 +100,7 @@ public:
bool openSubFile(const char *filename);
void close();
- bool eof() { return _stream->eof(); }
+ bool eof() { return _stream->eos(); }
uint32 pos() { return _stream->pos(); }
uint32 size() { return _stream->size(); }
void seek(int32 offs, int whence = SEEK_SET) { _stream->seek(offs, whence); }
diff --git a/simon/saveload.cpp b/simon/saveload.cpp
index 7892da4f46..658b4c5c6b 100644
--- a/simon/saveload.cpp
+++ b/simon/saveload.cpp
@@ -590,7 +590,7 @@ bool SimonEngine::load_game(uint slot) {
for (i = 0; i != 32; i++)
_bit_array[i] = f->readUint16BE();
- if (f->readingFailed()) {
+ if (f->ioFailed()) {
error("load failed");
}
diff --git a/sound/softsynth/mt32.cpp b/sound/softsynth/mt32.cpp
index 13502ed4df..75abaabbcc 100644
--- a/sound/softsynth/mt32.cpp
+++ b/sound/softsynth/mt32.cpp
@@ -90,7 +90,7 @@ public:
return file.read(in, size);
}
bool readLine(char *in, size_t size) {
- return file.gets(in, size) != NULL;
+ return file.readLine(in, size) != NULL;
}
bool readBit8u(MT32Emu::Bit8u *in) {
byte b = file.readByte();
diff --git a/sword2/function.cpp b/sword2/function.cpp
index 7e241ba094..a80ffa7f0b 100644
--- a/sword2/function.cpp
+++ b/sword2/function.cpp
@@ -3032,7 +3032,7 @@ int32 Logic::fnPlayCredits(int32 *params) {
}
char buffer[80];
- char *line = f.gets(buffer, sizeof(buffer));
+ char *line = f.readLine(buffer, sizeof(buffer));
if (!line || *line == 0) {
if (!hasCenterMark) {