GLK: Adding glk stream methods

This commit is contained in:
Paul Gilbert
2018-12-08 19:05:59 -08:00
committed by Paul Gilbert
parent d128249854
commit 485e899312
5 changed files with 286 additions and 27 deletions
+34 -20
View File
@@ -335,12 +335,11 @@ strid_t Glk::glk_stream_open_file(frefid_t fileref, FileMode fmode, glui32 rock)
}
strid_t Glk::glk_stream_open_memory(char *buf, glui32 buflen, FileMode fmode, glui32 rock) {
// TODO
return nullptr;
return _streams->addMemoryStream(buf, buflen, fmode, rock, false);
}
void Glk::glk_stream_close(strid_t str, stream_result_t *result) {
// TODO
str->close(result);
}
strid_t Glk::glk_stream_iterate(strid_t str, glui32 *rockptr) const {
@@ -356,22 +355,29 @@ glui32 Glk::glk_stream_get_rock(strid_t str) const {
return str->getRock();
}
void Glk::glk_stream_set_position(strid_t str, glsi32 pos, glui32 seekmode) {
// TODO
void Glk::glk_stream_set_position(strid_t str, glsi32 pos, glui32 seekMode) {
if (!str) {
warning("stream_set_position: invalid ref");
} else {
str->setPosition(pos, seekMode);
}
}
glui32 Glk::glk_stream_get_position(strid_t str) {
// TODO
return 0;
glui32 Glk::glk_stream_get_position(strid_t str) const {
if (!str) {
warning("stream_get_position: invalid ref");
return 0;
} else {
return str->getPosition();
}
}
void Glk::glk_stream_set_current(strid_t str) {
// TODO
_streams->setCurrent(str);
}
strid_t Glk::glk_stream_get_current(void) {
// TODO
return nullptr;
return _streams->getCurrent();
}
void Glk::glk_put_char(unsigned char ch) {
@@ -387,32 +393,40 @@ void Glk::glk_put_char_stream(strid_t str, unsigned char ch) {
}
void Glk::glk_put_string(const char *s) {
// TODO
_streams->getCurrent()->putBuffer(s, strlen(s));
}
void Glk::glk_put_string_stream(strid_t str, const char *s) {
// TODO
str->putBuffer(s, strlen(s));
}
void Glk::glk_put_buffer(char *buf, glui32 len) {
// TODO
_streams->getCurrent()->putBuffer(buf, len);
}
void Glk::glk_put_buffer_stream(strid_t str, const char *buf, glui32 len) {
// TODO
str->putBuffer(buf, len);
}
void Glk::glk_set_style(glui32 styl) {
// TODO
_streams->getCurrent()->setStyle(styl);
}
void Glk::glk_set_style_stream(strid_t str, glui32 styl) {
// TODO
if (str) {
str->setStyle(styl);
} else {
warning("set_style_stream: invalid ref");
}
}
glsi32 Glk::glk_get_char_stream(strid_t str) {
// TODO
return 0;
if (str) {
warning("get_char_stream: invalid ref");
return -1;
} else {
return str->getChar();
}
}
glui32 Glk::glk_get_line_stream(strid_t str, char *buf, glui32 len) {
@@ -661,7 +675,7 @@ strid_t Glk::glk_stream_open_file_uni(frefid_t fileref, FileMode fmode, glui32 r
}
strid_t Glk::glk_stream_open_memory_uni(glui32 *buf, glui32 buflen, FileMode fmode, glui32 rock) {
return _streams->addMemoryStream(buf, buflen, fmode, rock, false);
return _streams->addMemoryStream(buf, buflen, fmode, rock, true);
}
void Glk::glk_request_char_event_uni(winid_t win) {
+2 -2
View File
@@ -96,8 +96,8 @@ public:
void glk_stream_close(strid_t str, stream_result_t *result);
strid_t glk_stream_iterate(strid_t str, glui32 *rockptr) const;
glui32 glk_stream_get_rock(strid_t str) const;
void glk_stream_set_position(strid_t str, glsi32 pos, glui32 seekmode);
glui32 glk_stream_get_position(strid_t str);
void glk_stream_set_position(strid_t str, glsi32 pos, glui32 seekMode);
glui32 glk_stream_get_position(strid_t str) const;
void glk_stream_set_current(strid_t str);
strid_t glk_stream_get_current(void);
-5
View File
@@ -46,11 +46,6 @@ class Window;
#define GLK_MODULE_DATETIME
#define GLK_MODULE_GARGLKTEXT
/**
* These types are opaque object identifiers. They're pointers to opaque
* C structures, which are defined differently by each library.
*/
typedef struct glk_fileref_struct *frefid_t;
typedef struct glk_schannel_struct *schanid_t;
/**
+214
View File
@@ -144,6 +144,18 @@ void WindowStream::putBufferUni(const uint32 *buf, size_t len) {
_window->_echoStream->putBufferUni(buf, len);
}
void WindowStream::setStyle(glui32 val) {
if (!_writable)
return;
if (val >= style_NUMSTYLES)
val = 0;
_window->_attr.style = val;
if (_window->_echoStream)
_window->_echoStream->setStyle(val);
}
/*--------------------------------------------------------------------------*/
MemoryStream::MemoryStream(Streams *streams, void *buf, size_t buflen, FileMode mode, uint32 rock, bool unicode) :
@@ -297,6 +309,66 @@ void MemoryStream::putBufferUni(const uint32 *buf, size_t len) {
}
}
glui32 MemoryStream::getPosition() const {
if (_unicode)
return ((glui32 *)_bufPtr - (glui32 *)_buf);
else
return ((unsigned char *)_bufPtr - (unsigned char *)_buf);
}
void MemoryStream::setPosition(glui32 pos, glui32 seekMode) {
if (!_unicode)
{
if (seekMode == seekmode_Current)
pos = ((unsigned char *)_bufPtr - (unsigned char *)_buf) + pos;
else if (seekMode == seekmode_End)
pos = ((unsigned char *)_bufEof - (unsigned char *)_buf) + pos;
else
/* pos = pos */;
if (pos < 0)
pos = 0;
if (pos > (glui32)((unsigned char *)_bufEof - (unsigned char *)_buf))
pos = ((unsigned char *)_bufEof - (unsigned char *)_buf);
_bufPtr = (unsigned char *)_buf + pos;
} else {
if (seekMode == seekmode_Current)
pos = ((glui32 *)_bufPtr - (glui32 *)_buf) + pos;
else if (seekMode == seekmode_End)
pos = ((glui32 *)_bufEof - (glui32 *)_buf) + pos;
if (pos < 0)
pos = 0;
if (pos > (glui32)((glui32 *)_bufEof - (glui32 *)_buf))
pos = ((glui32 *)_bufEof - (glui32 *)_buf);
_bufPtr = (glui32 *)_buf + pos;
}
}
glsi32 MemoryStream::getChar() {
if (!_readable)
return -1;
if (_bufPtr < _bufEnd) {
if (!_unicode) {
unsigned char ch;
ch = *((unsigned char *)_bufPtr);
_bufPtr = ((unsigned char *)_bufPtr) + 1;
_readCount++;
return ch;
} else {
glui32 ch;
ch = *((glui32 *)_bufPtr);
_bufPtr = ((glui32 *)_bufPtr) + 1;
_readCount++;
if (ch > 0xff)
ch = '?';
return ch;
}
} else {
return -1;
}
}
/*--------------------------------------------------------------------------*/
FileStream::FileStream(Streams *streams, uint32 rock, bool unicode) :
@@ -409,6 +481,148 @@ void FileStream::putCharUtf8(glui32 val) {
}
}
glsi32 FileStream::getCharUtf8() {
glui32 res;
glui32 val0, val1, val2, val3;
if (_inFile->eos())
return -1;
val0 = _inFile->readByte();
if (val0 < 0x80) {
res = val0;
return res;
}
if ((val0 & 0xe0) == 0xc0) {
if (_inFile->eos()) {
warning("incomplete two-byte character");
return -1;
}
val1 = _inFile->readByte();
if ((val1 & 0xc0) != 0x80) {
warning("malformed two-byte character");
return '?';
}
res = (val0 & 0x1f) << 6;
res |= (val1 & 0x3f);
return res;
}
if ((val0 & 0xf0) == 0xe0) {
val1 = _inFile->readByte();
val2 = _inFile->readByte();
if (_inFile->eos()) {
warning("incomplete three-byte character");
return -1;
}
if ((val1 & 0xc0) != 0x80) {
warning("malformed three-byte character");
return '?';
}
if ((val2 & 0xc0) != 0x80) {
warning("malformed three-byte character");
return '?';
}
res = (((val0 & 0xf) << 12) & 0x0000f000);
res |= (((val1 & 0x3f) << 6) & 0x00000fc0);
res |= (((val2 & 0x3f)) & 0x0000003f);
return res;
}
if ((val0 & 0xf0) == 0xf0) {
if ((val0 & 0xf8) != 0xf0) {
warning("malformed four-byte character");
return '?';
}
val1 = _inFile->readByte();
val2 = _inFile->readByte();
val3 = _inFile->readByte();
if (_inFile->eos()) {
warning("incomplete four-byte character");
return -1;
}
if ((val1 & 0xc0) != 0x80) {
warning("malformed four-byte character");
return '?';
}
if ((val2 & 0xc0) != 0x80) {
warning("malformed four-byte character");
return '?';
}
if ((val3 & 0xc0) != 0x80) {
warning("malformed four-byte character");
return '?';
}
res = (((val0 & 0x7) << 18) & 0x1c0000);
res |= (((val1 & 0x3f) << 12) & 0x03f000);
res |= (((val2 & 0x3f) << 6) & 0x000fc0);
res |= (((val3 & 0x3f)) & 0x00003f);
return res;
}
warning("malformed character");
return '?';
}
glui32 FileStream::getPosition() const {
return _outFile->pos();
}
void FileStream::setPosition(glui32 pos, glui32 seekMode) {
_lastOp = 0;
if (_unicode)
pos *= 4;
error("FileStream::setPosition - seek not yet supported");
// fseek(str->file, pos, ((seekmode == seekmode_Current) ? 1 :
// ((seekmode == seekmode_End) ? 2 : 0)));
}
glsi32 FileStream::getChar() {
if (!_readable)
return -1;
ensureOp(filemode_Read);
int res;
if (!_unicode) {
res = _inFile->readByte();
} else if (_textFile) {
res = getCharUtf8();
} else {
glui32 ch;
res = _inFile->readByte();
if (_inFile->eos())
return -1;
ch = (res & 0xFF);
res = _inFile->readByte();
if (_inFile->eos())
return -1;
ch = (ch << 8) | (res & 0xFF);
res = _inFile->readByte();
if (_inFile->eos())
return -1;
ch = (ch << 8) | (res & 0xFF);
res = _inFile->readByte();
if (_inFile->eos())
return -1;
ch = (ch << 8) | (res & 0xFF);
res = ch;
}
if (res != -1) {
_readCount++;
if (res >= 0x100)
return '?';
return (glsi32)res;
} else {
return -1;
}
}
/*--------------------------------------------------------------------------*/
Streams::Streams() : _streamList(nullptr), _currentStream(nullptr) {
+36
View File
@@ -32,6 +32,15 @@ namespace Gargoyle {
class Window;
class Streams;
struct FileReference {
glui32 _rock;
Common::String _filename;
int _fileType;
int _textMode;
gidispatch_rock_t _dispRock;
};
typedef FileReference *frefid_t;
struct StreamResult {
uint32 _readCount;
uint32 _writeCount;
@@ -117,6 +126,14 @@ public:
putBufferUni(buf, len);
putCharUni('\n');
}
virtual glui32 getPosition() const { return 0; }
virtual void setPosition(glui32 pos, glui32 seekMode) {}
virtual void setStyle(glui32 val) {}
virtual glsi32 getChar() { return -1; }
};
typedef Stream *strid_t;
@@ -157,6 +174,8 @@ public:
* Write a unicode character
*/
virtual void putBufferUni(const uint32 *buf, size_t len) override;
virtual void setStyle(glui32 val) override;
};
/**
@@ -194,6 +213,12 @@ public:
* Write a unicode character
*/
virtual void putBufferUni(const uint32 *buf, size_t len) override;
virtual glui32 getPosition() const override;
virtual void setPosition(glui32 pos, glui32 seekMode) override;
virtual glsi32 getChar() override;
};
/**
@@ -215,6 +240,11 @@ private:
* Put a UTF8 character
*/
void putCharUtf8(glui32 val);
/**
* Get a UTF8 character
*/
glsi32 getCharUtf8();
public:
/**
* Constructor
@@ -240,6 +270,12 @@ public:
* Write a unicode character
*/
virtual void putBufferUni(const uint32 *buf, size_t len) override;
virtual glui32 getPosition() const override;
virtual void setPosition(glui32 pos, glui32 seekMode) override;
virtual glsi32 getChar() override;
};
/**