From b37dc017279067bfedc165bd738f9b9c1cc1c5a9 Mon Sep 17 00:00:00 2001 From: Lucas Bajolet Date: Wed, 10 Dec 2014 14:24:46 -0500 Subject: [PATCH] lib/standard/file: Added a way to change the buffering for a specified stream Signed-off-by: Lucas Bajolet --- lib/standard/file.nit | 17 +++++++++++++++++ lib/standard/file_nit.c | 4 ++++ lib/standard/file_nit.h | 4 ++++ src/interpreter/naive_interpreter.nit | 8 ++++++++ src/interpreter/primitive_types.nit | 4 ++++ 5 files changed, 37 insertions(+) diff --git a/lib/standard/file.nit b/lib/standard/file.nit index 0a0ed51..2f93d4e 100644 --- a/lib/standard/file.nit +++ b/lib/standard/file.nit @@ -44,6 +44,21 @@ abstract class FStream # File descriptor of this file fun fd: Int do return _file.fileno + + # Sets the buffering mode for the current FStream + # + # If the buf_size is <= 0, its value will be 512 by default + # + # The mode is any of the buffer_mode enumeration in `Sys`: + # - buffer_mode_full + # - buffer_mode_line + # - buffer_mode_none + fun set_buffering_mode(buf_size, mode: Int) do + if buf_size <= 0 then buf_size = 512 + if _file.set_buffering_type(buf_size, mode) != 0 then + last_error = new IOError("Error while changing buffering type for FStream, returned error {sys.errno.strerror}") + end + end end # File input stream @@ -685,6 +700,8 @@ private extern class NativeFile `{ FILE* `} fun fileno: Int `{ return fileno(recv); `} # Flushes the buffer, forcing the write operation fun flush: Int is extern "fflush" + # Used to specify how the buffering will be handled for the current stream. + fun set_buffering_type(buf_length: Int, mode: Int): Int is extern "file_NativeFile_NativeFile_set_buffering_type_0" new io_open_read(path: NativeString) is extern "file_NativeFileCapable_NativeFileCapable_io_open_read_1" new io_open_write(path: NativeString) is extern "file_NativeFileCapable_NativeFileCapable_io_open_write_1" diff --git a/lib/standard/file_nit.c b/lib/standard/file_nit.c index dc1b7fe..f6a6987 100644 --- a/lib/standard/file_nit.c +++ b/lib/standard/file_nit.c @@ -69,3 +69,7 @@ int file_stdin_poll_in_(void) { FILE* file_int_fdtostream(int fd, char* mode){ return fdopen(fd, mode); } + +int file_NativeFile_NativeFile_set_buffering_type_0(FILE* f, int buf_sz, int mode){ + return setvbuf(f, NULL, mode, buf_sz); +} diff --git a/lib/standard/file_nit.h b/lib/standard/file_nit.h index 9b1238b..d8d9b4b 100644 --- a/lib/standard/file_nit.h +++ b/lib/standard/file_nit.h @@ -25,6 +25,7 @@ extern void *string_NativeString_NativeString_file_stat_0(char *f); extern void *file_NativeFile_NativeFile_file_stat_0(FILE *f); extern int string_NativeString_NativeString_file_delete_0(char *f); FILE* file_int_fdtostream(int fd, char* mode); +int file_NativeFile_NativeFile_set_buffering_type_0(FILE* f, int buf_sz, int mode); #define file_NativeFile_NativeFile_io_read_2(p, b, l) fread((b), 1, (l), (FILE*)(p)) #define file_NativeFile_NativeFile_io_write_2(p, b, l) fwrite((b), 1, (l), (FILE*)(p)) @@ -41,6 +42,9 @@ FILE* file_int_fdtostream(int fd, char* mode); #define file_FileStat_FileStat_ctime_0(self) (((struct stat*)self)->st_ctime) #define file_FileStat_FileStat_mtime_0(self) (((struct stat*)self)->st_mtime) #define file_FileStat_FileStat_size_0(self) (((struct stat*)self)->st_size) +#define file_Sys_Sys_buffer_mode_full_0(self) _IOFBF +#define file_Sys_Sys_buffer_mode_line_0(self) _IOLBF +#define file_Sys_Sys_buffer_mode_none_0(self) _IONBF #define string_NativeString_NativeString_file_mkdir_0(p) (mkdir(p, 0777)) #define string_NativeString_NativeString_file_getcwd_0(p) (getcwd(NULL, 0)) diff --git a/src/interpreter/naive_interpreter.nit b/src/interpreter/naive_interpreter.nit index fd3e6ee..8e9ea77 100644 --- a/src/interpreter/naive_interpreter.nit +++ b/src/interpreter/naive_interpreter.nit @@ -781,6 +781,12 @@ redef class AMethPropdef else if pname == "exit" then exit(args[1].to_i) abort + else if pname == "buffer_mode_full" then + return v.int_instance(sys.buffer_mode_full) + else if pname == "buffer_mode_line" then + return v.int_instance(sys.buffer_mode_line) + else if pname == "buffer_mode_none" then + return v.int_instance(sys.buffer_mode_none) else if pname == "sys" then return v.mainobj else if cname == "Int" then @@ -1031,6 +1037,8 @@ redef class AMethPropdef return null else if pname == "io_close" then return v.int_instance(recvval.as(PrimitiveNativeFile).io_close) + else if pname == "set_buffering_type" then + return v.int_instance(recvval.as(PrimitiveNativeFile).set_buffering_type(args[1].to_i, args[2].to_i)) end else if pname == "calloc_array" then var recvtype = args.first.mtype.as(MClassType) diff --git a/src/interpreter/primitive_types.nit b/src/interpreter/primitive_types.nit index d3a0059..8fe483d 100644 --- a/src/interpreter/primitive_types.nit +++ b/src/interpreter/primitive_types.nit @@ -54,4 +54,8 @@ class PrimitiveNativeFile fun fileno: Int do return file._file.fileno fun flush: Int do return file._file.flush + + fun set_buffering_type(size, mode: Int): Int do + return file._file.set_buffering_type(size, mode) + end end -- 1.7.9.5