Files openen. Niet getest, omdat het schrijven naar files nog niet
authorfliep <fliep@ddfedd41-794f-dd11-ae45-00112f111e67>
Sat, 9 Aug 2008 22:36:35 +0000 (22:36 +0000)
committerfliep <fliep@ddfedd41-794f-dd11-ae45-00112f111e67>
Sat, 9 Aug 2008 22:36:35 +0000 (22:36 +0000)
geschreven is.

glk_stream_open_file()
glk_stream_open_file_uni()

src/stream.c
src/stream.h

index a6913e2f06ebde4e6a90c53f995f4d0f9f524cbd..da470ba2b48b41514a3241b7385bba849a12439e 100644 (file)
@@ -1,5 +1,8 @@
 #include "stream.h"
+#include "fileref.h"
 #include <string.h>
+#include <stdio.h>
+#include <glib/gstdio.h>
 
 /* Global current stream */
 static strid_t current_stream = NULL;
@@ -285,3 +288,119 @@ glk_put_buffer_stream(strid_t str, char *buf, glui32 len)
        g_free(s);
 }
 
+/* Internal function: create a stream using the given parameters. */
+static strid_t
+stream_new(frefid_t fileref, glui32 fmode, glui32 rock, gboolean unicode)
+{
+       g_return_val_if_fail(fileref != NULL, NULL);
+       
+       gchar *modestr;
+       gboolean binary = fileref->usage & fileusage_BinaryMode;
+       switch(fmode) 
+       {
+               case filemode_Read:
+                       if(!g_file_test(fileref->filename, G_FILE_TEST_EXISTS)) {
+                               g_warning("glk_stream_open_file: Tried to open a file in read "
+                                                 "mode that didn't exist!");
+                               return NULL;
+                       }
+                       modestr = g_strdup(binary? "rb" : "r");
+                       break;
+               case filemode_Write:
+                       modestr = g_strdup(binary? "wb" : "w");
+                       break;
+               case filemode_WriteAppend:
+                       modestr = g_strdup(binary? "ab" : "a");
+                       break;
+               case filemode_ReadWrite:
+                       modestr = g_strdup(binary? "r+b" : "r+");
+                       break;
+               default:
+                       g_warning("glk_stream_open_file: Invalid file mode");
+                       return NULL;
+       }
+       
+       FILE *fp = g_fopen(fileref->filename, modestr);
+       g_free(modestr);
+       if(fp == NULL) {
+               g_warning("glk_stream_open_file: Error opening file");
+               return NULL;
+       }
+       
+       /* If they opened a file in write mode but didn't specifically get
+       permission to do so, complain if the file already exists */
+       if(fileref->orig_filemode == filemode_Read && fmode != filemode_Read) {
+               GtkWidget *dialog = gtk_message_dialog_new(NULL, 0,
+                       GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
+                       "File %s already exists. Overwrite?", fileref->filename);
+               gint response = gtk_dialog_run(GTK_DIALOG(dialog));
+               gtk_widget_destroy(dialog);
+               if(response != GTK_RESPONSE_YES) {
+                       fclose(fp);
+                       return NULL;
+               }
+       }
+       
+       strid_t s = g_new0(struct glk_stream_struct, 1);
+       s->file_mode = fmode;
+       s->stream_type = unicode? STREAM_TYPE_UNICODE_FILE : STREAM_TYPE_FILE;
+       s->file_pointer = fp;
+       s->binary = binary;
+       /* Add it to the global stream list */
+       stream_list = g_list_prepend(stream_list, s);
+       s->stream_list = stream_list;
+
+       return s;
+}
+
+/**
+ * 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.
+ * @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
+ * 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 
+ * file.
+ * 
+ * The file may be written in text or binary mode; this is determined by the
+ * @fileref argument. Similarly, platform-dependent attributes such as file 
+ * type are determined by @fileref.
+ *
+ * When writing in binary mode, Unicode values (characters greater than 255)
+ * cannot be written to the file. If you try, they will be stored as 0x3F ("?")
+ * characters. In text mode, Unicode values are stored in UTF-8.
+ *
+ * Returns: A new stream, or %NULL if the file operation failed.
+ */
+strid_t
+glk_stream_open_file(frefid_t fileref, glui32 fmode, glui32 rock)
+{
+       return stream_new(fileref, fmode, rock, FALSE);
+}
+
+/**
+ * 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.
+ * @rock: The new stream's rock value.
+ *
+ * This works just like glk_stream_open_file(), except that in binary mode,
+ * characters are written and read as four-byte (big-endian) values. This
+ * allows you to write any Unicode character.
+ *
+ * In text mode, the file is written and read in UTF-8.
+ *
+ * Returns: A new stream, or %NULL if the file operation failed.
+ */
+strid_t
+glk_stream_open_file_uni(frefid_t fileref, glui32 fmode, glui32 rock)
+{
+       return stream_new(fileref, fmode, rock, TRUE);
+}
+
index 3fd4fcba07717fee0ec1b74f890d4cb0a31811a2..1d7f131559cdee04be2321a3792c1829bfbd2196 100644 (file)
@@ -31,6 +31,9 @@ struct glk_stream_struct
        gchar *memory_buffer;
        glui32 *memory_buffer_unicode;
        glui32 buffer_len;
+       /* Specific to file streams */
+       FILE *file_pointer;
+       gboolean binary;
 };
 
 strid_t window_stream_new(winid_t window);