diff --git a/src/lib/xpost_file.c b/src/lib/xpost_file.c
index 15a2877..d6967f2 100644
--- a/src/lib/xpost_file.c
+++ b/src/lib/xpost_file.c
@@ -58,6 +58,10 @@ void *alloca (size_t);
# endif
#endif
+#ifndef _WIN32
+# include <stdio_ext.h> /* __fpurge */
+#endif
+
#include <errno.h>
#include <limits.h>
#include <stdio.h>
@@ -118,13 +122,58 @@ f_tmpfile(void)
# define f_tmpfile tmpfile
#endif
-/* interface fgetc
- in preparation for more elaborate cross-platform non-blocking mechanisms
-cf.
http://stackoverflow.com/questions/20428616/how-to-handle-window-events-while-waiting-for-terminal-input-and
http://stackoverflow.com/questions/25506324/how-to-do-pollstdin-or-selectstdin-when-stdin-is-a-windows-console- */
-int xpost_file_getc(FILE *in){
- return fgetc(in);
+int disk_readch(Xpost_File file){
+ Xpost_DiskFile df = (Xpost_DiskFile) file;
+ return fgetc(df->file);
+}
+
+int disk_writech(Xpost_File file, int c){
+ Xpost_DiskFile df = (Xpost_DiskFile) file;
+ return fputc(c, df->file);
+}
+
+int disk_close(Xpost_File file){
+ Xpost_DiskFile df = (Xpost_DiskFile) file;
+ int ret = fclose(df->file);
+ return df->file = NULL, ret;
+}
+
+int disk_flush(Xpost_File file){
+ Xpost_DiskFile df = (Xpost_DiskFile) file;
+ return fflush(df->file);
+}
+
+int disk_purge(Xpost_File file){
+ Xpost_DiskFile df = (Xpost_DiskFile) file;
+ return __fpurge(df->file);
+}
+
+int disk_unreadch(Xpost_File file, int c){
+ Xpost_DiskFile df = (Xpost_DiskFile) file;
+ return ungetc(c, df->file);
+}
+
+long disk_tell(Xpost_File file){
+ Xpost_DiskFile df = (Xpost_DiskFile) file;
+ return ftell(df->file);
+}
+
+int disk_seek(Xpost_File file, long offset){
+ Xpost_DiskFile df = (Xpost_DiskFile) file;
+ return fseek(df->file, offset, SEEK_SET);
+}
+
+Xpost_File_Methods disk_methods = &(struct Xpost_File_Methods){
+ disk_readch, disk_writech, disk_close, disk_flush, disk_purge, disk_unreadch, disktell, diskseek
+};
+
+Xpost_File xpost_diskfile_open(FILE *fp){
+ Xpost_DiskFile df = malloc(sizeof *df);
+ if (df) {
+ df->methods = disk_methods;
+ df->file = fp;
+ }
+ return (Xpost_File)df;
}
/* filetype objects use a slightly different interpretation
@@ -152,19 +201,21 @@ Xpost_Object xpost_file_cons(Xpost_Memory_File *mem,
Xpost_Object f;
unsigned int ent;
int ret;
+ Xpost_File df;
#ifdef DEBUG_FILE
printf("xpost_file_cons %p\n", fp);
#endif
f.tag = filetype /*| (XPOST_OBJECT_TAG_ACCESS_UNLIMITED << XPOST_OBJECT_TAG_DATA_FLAG_ACCESS_OFFSET)*/;
+ df = xpost_diskfile_open(fp);
/* xpost_memory_table_alloc(mem, sizeof(FILE *), 0, &f.mark_.padw); */
- if (!xpost_memory_table_alloc(mem, sizeof(FILE *), filetype, &ent))
+ if (!xpost_memory_table_alloc(mem, sizeof df, filetype, &ent))
{
XPOST_LOG_ERR("cannot allocate file record");
return invalid;
}
f.mark_.padw = ent;
- ret = xpost_memory_put(mem, f.mark_.padw, 0, sizeof(FILE *), &fp);
+ ret = xpost_memory_put(mem, f.mark_.padw, 0, sizeof df, &df);
if (!ret)
{
XPOST_LOG_ERR("cannot save FILE* in VM");
@@ -384,13 +435,13 @@ int xpost_file_open(Xpost_Memory_File *mem,
/* adapter:
FILE* <- filetype object
yield the FILE* from a filetype object */
-FILE *xpost_file_get_file_pointer(Xpost_Memory_File *mem,
+Xpost_File xpost_file_get_file_pointer(Xpost_Memory_File *mem,
Xpost_Object f)
{
- FILE *fp;
+ Xpost_File fp;
int ret;
- ret = xpost_memory_get(mem, f.mark_.padw, 0, sizeof(FILE *), &fp);
+ ret = xpost_memory_get(mem, f.mark_.padw, 0, sizeof fp, &fp);
if (!ret)
{
return NULL;
@@ -405,6 +456,7 @@ int xpost_file_get_status(Xpost_Memory_File *mem,
return xpost_file_get_file_pointer(mem, f) != NULL;
}
+//FIXME assumes DiskFile subtype
/* call fstat. */