#include <glib/gstdio.h>
#include "chimara-glk-private.h"
-extern ChimaraGlkPrivate *glk_data;
+extern GPrivate *glk_data_key;
/* Internal function: create a stream with a specified rock value */
-static strid_t
-stream_new_common(glui32 rock, glui32 fmode, enum StreamType type)
+strid_t
+stream_new_common(glui32 rock)
{
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+
strid_t str = g_new0(struct glk_stream_struct, 1);
str->magic = MAGIC_STREAM;
str->rock = rock;
- str->file_mode = fmode;
- str->type = type;
+ if(glk_data->register_obj)
+ str->disprock = (*glk_data->register_obj)(str, gidisp_Class_Stream);
/* Add it to the global stream list */
glk_data->stream_list = g_list_prepend(glk_data->stream_list, str);
return str;
}
-/* Internal function: create a window stream to go with window. */
-strid_t
-window_stream_new(winid_t window)
+/* Internal function: Stuff to do upon closing any type of stream. */
+void
+stream_close_common(strid_t str, stream_result_t *result)
{
- /* Create stream and connect it to window */
- strid_t str = stream_new_common(0, filemode_Write, STREAM_TYPE_WINDOW);
- str->window = window;
- str->style = "normal";
- return str;
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+
+ /* Remove the stream from the global stream list */
+ glk_data->stream_list = g_list_delete_link(glk_data->stream_list, str->stream_list);
+
+ /* If it was the current output stream, set that to NULL */
+ if(glk_data->current_stream == str)
+ glk_data->current_stream = NULL;
+
+ /* If it was one or more windows' echo streams, set those to NULL */
+ winid_t win;
+ for(win = glk_window_iterate(NULL, NULL); win;
+ win = glk_window_iterate(win, NULL))
+ if(win->echo_stream == str)
+ win->echo_stream = NULL;
+
+ if(glk_data->unregister_obj)
+ {
+ (*glk_data->unregister_obj)(str, gidisp_Class_Stream, str->disprock);
+ str->disprock.ptr = NULL;
+ }
+
+ /* Return the character counts */
+ if(result)
+ {
+ result->readcount = str->read_count;
+ result->writecount = str->write_count;
+ }
+
+ str->magic = MAGIC_FREE;
+ g_free(str);
}
/**
glk_stream_iterate(strid_t str, glui32 *rockptr)
{
VALID_STREAM_OR_NULL(str, return NULL);
-
+
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
GList *retnode;
if(str == NULL)
glk_stream_set_current(strid_t str)
{
VALID_STREAM_OR_NULL(str, return);
+
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
if(str != NULL && str->file_mode == filemode_Read)
{
strid_t
glk_stream_get_current()
{
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
return glk_data->current_stream;
}
void
glk_put_char(unsigned char ch)
{
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
VALID_STREAM(glk_data->current_stream, return);
glk_put_char_stream(glk_data->current_stream, ch);
}
void
glk_put_char_uni(glui32 ch)
{
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
VALID_STREAM(glk_data->current_stream, return);
glk_put_char_stream_uni(glk_data->current_stream, ch);
}
* Prints a null-terminated string to the current stream. It is exactly
* equivalent to
* |[
- * for (ptr = @s; *ptr; ptr++)
+ * for (ptr = s; *ptr; ptr++)
* #glk_put_char(*ptr);
* ]|
* However, it may be more efficient.
void
glk_put_string(char *s)
{
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
VALID_STREAM(glk_data->current_stream, return);
glk_put_string_stream(glk_data->current_stream, s);
}
void
glk_put_string_uni(glui32 *s)
{
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
VALID_STREAM(glk_data->current_stream, return);
glk_put_string_stream_uni(glk_data->current_stream, s);
}
* Prints a block of characters to the current stream. It is exactly equivalent
* to:
* |[
- * for (i = 0; i < @len; i++)
- * #glk_put_char(@buf[i]);
+ * for (i = 0; i < len; i++)
+ * #glk_put_char(buf[i]);
* ]|
* However, it may be more efficient.
*/
void
glk_put_buffer(char *buf, glui32 len)
{
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
VALID_STREAM(glk_data->current_stream, return);
glk_put_buffer_stream(glk_data->current_stream, buf, len);
}
void
glk_put_buffer_uni(glui32 *buf, glui32 len)
{
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
VALID_STREAM(glk_data->current_stream, return);
glk_put_buffer_stream_uni(glk_data->current_stream, buf, len);
}
* @buf: An allocated buffer, or %NULL.
* @buflen: Length of @buf.
* @fmode: Mode in which the buffer will be opened. Must be one of
- * #filemode_Read, #filemode_Write, or #filemode_ReadWrite.
+ * %filemode_Read, %filemode_Write, or %filemode_ReadWrite.
* @rock: The new stream's rock value.
*
* Opens a stream which reads from or writes to a space in memory. @buf points
{
g_return_val_if_fail(fmode != filemode_WriteAppend, NULL);
- strid_t str = stream_new_common(rock, fmode, STREAM_TYPE_MEMORY);
- str->buffer = buf;
+ strid_t str = stream_new_common(rock);
+ str->file_mode = fmode;
+ str->type = STREAM_TYPE_MEMORY;
str->mark = 0;
- str->buflen = buflen;
str->unicode = FALSE;
+
+ if(buf && buflen)
+ {
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+ str->buffer = buf;
+ str->buflen = buflen;
+ if(glk_data->register_arr)
+ str->buffer_rock = (*glk_data->register_arr)(buf, buflen, "&+#!Cn");
+ }
+
return str;
}
* @buf: An allocated buffer, or %NULL.
* @buflen: Length of @buf.
* @fmode: Mode in which the buffer will be opened. Must be one of
- * #filemode_Read, #filemode_Write, or #filemode_ReadWrite.
+ * %filemode_Read, %filemode_Write, or %filemode_ReadWrite.
* @rock: The new stream's rock value.
*
* Works just like glk_stream_open_memory(), except that the buffer is an array
{
g_return_val_if_fail(fmode != filemode_WriteAppend, NULL);
- strid_t str = stream_new_common(rock, fmode, STREAM_TYPE_MEMORY);
- str->ubuffer = buf;
+ strid_t str = stream_new_common(rock);
+ str->file_mode = fmode;
+ str->type = STREAM_TYPE_MEMORY;
str->mark = 0;
- str->buflen = buflen;
str->unicode = TRUE;
+
+ if(buf && buflen)
+ {
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+ str->ubuffer = buf;
+ str->buflen = buflen;
+ if(glk_data->register_arr)
+ str->buffer_rock = (*glk_data->register_arr)(buf, buflen, "&+#!Iu");
+ }
+
return str;
}
/* Internal function: create a stream using the given parameters. */
-static strid_t
+strid_t
file_stream_new(frefid_t fileref, glui32 fmode, glui32 rock, gboolean unicode)
{
VALID_FILEREF(fileref, return NULL);
}
}
- strid_t str = stream_new_common(rock, fmode, STREAM_TYPE_FILE);
+ strid_t str = stream_new_common(rock);
+ str->file_mode = fmode;
+ str->type = STREAM_TYPE_FILE;
str->file_pointer = fp;
str->binary = binary;
str->unicode = unicode;
/**
* glk_stream_open_file:
* @fileref: Indicates the file which will be opened.
- * @fmode: Mode in which the file will be opened. Can be any of #filemode_Read,
- * #filemode_Write, #filemode_WriteAppend, or #filemode_ReadWrite.
+ * @fmode: Mode in which the file will be opened. Can be any of %filemode_Read,
+ * %filemode_Write, %filemode_WriteAppend, or %filemode_ReadWrite.
* @rock: The new stream's rock value.
*
* Opens a stream which reads to or writes from a disk file. If @fmode is
- * #filemode_Read, the file must already exist; for the other modes, an empty
- * file is created if none exists. If @fmode is #filemode_Write, and the file
+ * %filemode_Read, the file must already exist; for the other modes, an empty
+ * file is created if none exists. If @fmode is %filemode_Write, and the file
* already exists, it is truncated down to zero length (an empty file). If
- * @fmode is #filemode_WriteAppend, the file mark is set to the end of the
+ * @fmode is %filemode_WriteAppend, the file mark is set to the end of the
* file.
*
* When writing in binary mode, Unicode values (characters greater than 255)
/**
* glk_stream_open_file_uni:
* @fileref: Indicates the file which will be opened.
- * @fmode: Mode in which the file will be opened. Can be any of #filemode_Read,
- * #filemode_Write, #filemode_WriteAppend, or #filemode_ReadWrite.
+ * @fmode: Mode in which the file will be opened. Can be any of %filemode_Read,
+ * %filemode_Write, %filemode_WriteAppend, or %filemode_ReadWrite.
* @rock: The new stream's rock value.
*
* This works just like glk_stream_open_file(), except that in binary mode,
return;
case STREAM_TYPE_MEMORY:
- /* Do nothing */
+ {
+ ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+ if(glk_data->unregister_arr)
+ {
+ if(str->unicode)
+ (*glk_data->unregister_arr)(str->ubuffer, str->buflen, "&+#!Iu", str->buffer_rock);
+ else
+ (*glk_data->unregister_arr)(str->buffer, str->buflen, "&+#!Cn", str->buffer_rock);
+ }
+ }
break;
-
+
case STREAM_TYPE_FILE:
if(fclose(str->file_pointer) != 0)
IO_WARNING( "Failed to close file", str->filename, g_strerror(errno) );
stream_close_common(str, result);
}
-
-/* Internal function: Stuff to do upon closing any type of stream. */
-void
-stream_close_common(strid_t str, stream_result_t *result)
-{
- /* Remove the stream from the global stream list */
- glk_data->stream_list = g_list_delete_link(glk_data->stream_list, str->stream_list);
-
- /* If it was the current output stream, set that to NULL */
- if(glk_data->current_stream == str)
- glk_data->current_stream = NULL;
-
- /* If it was one or more windows' echo streams, set those to NULL */
- winid_t win;
- for(win = glk_window_iterate(NULL, NULL); win;
- win = glk_window_iterate(win, NULL))
- if(win->echo_stream == str)
- win->echo_stream = NULL;
-
- /* Return the character counts */
- if(result)
- {
- result->readcount = str->read_count;
- result->writecount = str->write_count;
- }
-
- str->magic = MAGIC_FREE;
- g_free(str);
-}