diff options
| author | Max Horn | 2005-04-22 17:40:09 +0000 | 
|---|---|---|
| committer | Max Horn | 2005-04-22 17:40:09 +0000 | 
| commit | 969ef3dac93a21d981e4cc2a8c81c0f03a834417 (patch) | |
| tree | 9240363f92815c7e92e53b0b42e8d553d4a478c3 | |
| parent | ca33ec4563e05b0940e44de78e0f52bbbf6bfe41 (diff) | |
| download | scummvm-rg350-969ef3dac93a21d981e4cc2a8c81c0f03a834417.tar.gz scummvm-rg350-969ef3dac93a21d981e4cc2a8c81c0f03a834417.tar.bz2 scummvm-rg350-969ef3dac93a21d981e4cc2a8c81c0f03a834417.zip | |
* Added new virtual base class 'Stream', ReadStream and
  WriteStream are now subclasses of it.
* Added new methods eos(), ioFailed(), clearIOFailed() to
  all streams. This allows better error checking.
* SaveFile classes take advantage of these new standard
  stream APIS
* Removed File::gets()
* Added SeekableReadStream::readLine() (replaces File::gets)
* Added WriteStream::writeString, for convenience
svn-id: r17752
| -rw-r--r-- | common/file.cpp | 65 | ||||
| -rw-r--r-- | common/file.h | 2 | ||||
| -rw-r--r-- | common/savefile.cpp | 12 | ||||
| -rw-r--r-- | common/savefile.h | 5 | ||||
| -rw-r--r-- | common/stream.cpp | 61 | ||||
| -rw-r--r-- | common/stream.h | 55 | ||||
| -rw-r--r-- | kyra/script.cpp | 5 | ||||
| -rw-r--r-- | saga/sprite.cpp | 2 | ||||
| -rw-r--r-- | scumm/util.h | 2 | ||||
| -rw-r--r-- | simon/saveload.cpp | 2 | ||||
| -rw-r--r-- | sound/softsynth/mt32.cpp | 2 | ||||
| -rw-r--r-- | sword2/function.cpp | 2 | 
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) { | 
