lib/standard/file: Added a way to change the buffering for a specified stream
authorLucas Bajolet <r4pass@hotmail.com>
Wed, 10 Dec 2014 19:24:46 +0000 (14:24 -0500)
committerLucas Bajolet <r4pass@hotmail.com>
Wed, 10 Dec 2014 19:24:46 +0000 (14:24 -0500)
Signed-off-by: Lucas Bajolet <r4pass@hotmail.com>

lib/standard/file.nit
lib/standard/file_nit.c
lib/standard/file_nit.h
src/interpreter/naive_interpreter.nit
src/interpreter/primitive_types.nit

index 0a0ed51..2f93d4e 100644 (file)
@@ -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"
index dc1b7fe..f6a6987 100644 (file)
@@ -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);
+}
index 9b1238b..d8d9b4b 100644 (file)
@@ -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))
index fd3e6ee..8e9ea77 100644 (file)
@@ -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)
index d3a0059..8fe483d 100644 (file)
@@ -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