From 4bb596792005f3a696a29fdd038809133bfb8119 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 26 Oct 2018 19:14:36 -0700 Subject: GLK: More glk stream functions --- engines/gargoyle/glk.cpp | 8 ++- engines/gargoyle/streams.cpp | 123 +++++++++++++++++++++++++++++++++++++++++++ engines/gargoyle/streams.h | 16 ++++++ 3 files changed, 145 insertions(+), 2 deletions(-) (limited to 'engines') diff --git a/engines/gargoyle/glk.cpp b/engines/gargoyle/glk.cpp index 2f26aee5c4..35b8563e1a 100644 --- a/engines/gargoyle/glk.cpp +++ b/engines/gargoyle/glk.cpp @@ -673,8 +673,12 @@ glui32 Glk::glk_get_buffer_stream_uni(strid_t str, glui32 *buf, glui32 len) { } glui32 Glk::glk_get_line_stream_uni(strid_t str, glui32 *buf, glui32 len) { - // TODO - return 0; + if (str) { + return str->getLineUni(buf, len); + } else { + warning("get_line_stream_uni: invalid ref"); + return -1; + } } strid_t Glk::glk_stream_open_file_uni(frefid_t fileref, FileMode fmode, glui32 rock) { diff --git a/engines/gargoyle/streams.cpp b/engines/gargoyle/streams.cpp index 42b89eb673..1942ddf94d 100644 --- a/engines/gargoyle/streams.cpp +++ b/engines/gargoyle/streams.cpp @@ -444,6 +444,60 @@ glui32 MemoryStream::getBufferUni(glui32 *buf, glui32 len) { return len; } +glui32 MemoryStream::getLineUni(glui32 *ubuf, glui32 len) { + bool gotNewline; + int lx; + + if (!_readable || len == 0) + return 0; + + len -= 1; // for the terminal null + if (!_unicode) { + if (_bufPtr >= _bufEnd) { + len = 0; + } else { + if ((char *)_bufPtr + len > (char *)_bufEnd) { + lx = ((char *)_bufPtr + len) - (char *)_bufEnd; + if (lx < (int)len) + len -= lx; + else + len = 0; + } + } + gotNewline = false; + for (lx = 0; lx < (int)len && !gotNewline; lx++) { + ubuf[lx] = ((unsigned char *)_bufPtr)[lx]; + gotNewline = (ubuf[lx] == '\n'); + } + ubuf[lx] = '\0'; + _bufPtr = ((unsigned char *)_bufPtr) + lx; + } else { + if (_bufPtr >= _bufEnd) { + len = 0; + } else { + if ((glui32 *)_bufPtr + len > (glui32 *)_bufEnd) { + lx = ((glui32 *)_bufPtr + len) - (glui32 *)_bufEnd; + if (lx < (int)len) + len -= lx; + else + len = 0; + } + } + gotNewline = false; + for (lx = 0; lx < (int)len && !gotNewline; lx++) { + glui32 ch; + ch = ((glui32 *)_bufPtr)[lx]; + ubuf[lx] = ch; + gotNewline = (ch == '\n'); + } + ubuf[lx] = '\0'; + _bufPtr = ((glui32 *)_bufPtr) + lx; + } + + _readCount += lx; + return lx; +} + /*--------------------------------------------------------------------------*/ FileStream::FileStream(Streams *streams, uint32 rock, bool unicode) : @@ -795,6 +849,75 @@ glui32 FileStream::getBufferUni(glui32 *buf, glui32 len) { } } +glui32 FileStream::getLineUni(glui32 *ubuf, glui32 len) { + bool gotNewline; + int lx; + + if (!_readable || len == 0) + return 0; + + ensureOp(filemode_Read); + if (!_unicode) { + len -= 1; // for the terminal null + gotNewline = false; + for (lx = 0; lx < (int)len && !gotNewline; lx++) { + int res; + glui32 ch; + res = _inFile->readByte(); + if (res == -1) + break; + ch = (res & 0xFF); + _readCount++; + ubuf[lx] = ch; + gotNewline = (ch == '\n'); + } + ubuf[lx] = '\0'; + return lx; + } else if (_textFile) { + len -= 1; /* for the terminal null */ + gotNewline = false; + for (lx = 0; lx < (int)len && !gotNewline; lx++) { + glui32 ch; + ch = getCharUtf8(); + if (ch == -1) + break; + _readCount++; + ubuf[lx] = ch; + gotNewline = (ch == '\n'); + } + ubuf[lx] = '\0'; + return lx; + } else { + len -= 1; // for the terminal null + gotNewline = false; + for (lx = 0; lx < (int)len && !gotNewline; lx++) { + int res; + glui32 ch; + res = _inFile->readByte(); + if (res == -1) + break; + ch = (res & 0xFF); + res = _inFile->readByte(); + if (res == -1) + break; + ch = (ch << 8) | (res & 0xFF); + res = _inFile->readByte(); + if (res == -1) + break; + ch = (ch << 8) | (res & 0xFF); + res = _inFile->readByte(); + if (res == -1) + break; + ch = (ch << 8) | (res & 0xFF); + _readCount++; + ubuf[lx] = ch; + gotNewline = (ch == '\n'); + } + ubuf[lx] = '\0'; + return lx; + } +} + /*--------------------------------------------------------------------------*/ Streams::Streams() : _streamList(nullptr), _currentStream(nullptr) { diff --git a/engines/gargoyle/streams.h b/engines/gargoyle/streams.h index ff0f9be249..77ae8cbbf4 100644 --- a/engines/gargoyle/streams.h +++ b/engines/gargoyle/streams.h @@ -147,6 +147,12 @@ public: * Get a unicode buffer */ virtual glui32 getBufferUni(glui32 *buf, glui32 len) { return 0; } + + /** + * Get a unicode line + */ + virtual glui32 getLineUni(glui32 *ubuf, glui32 len) { return 0; } + }; typedef Stream *strid_t; @@ -245,6 +251,11 @@ public: * Get a unicode buffer */ virtual glui32 getBufferUni(glui32 *buf, glui32 len) override; + + /** + * Get a unicode line + */ + virtual glui32 getLineUni(glui32 *ubuf, glui32 len) override; }; /** @@ -315,6 +326,11 @@ public: * Get a unicode buffer */ virtual glui32 getBufferUni(glui32 *buf, glui32 len) override; + + /** + * Get a unicode line + */ + virtual glui32 getLineUni(glui32 *ubuf, glui32 len) override; }; /** -- cgit v1.2.3