X-Git-Url: http://nitlanguage.org diff --git a/lib/core/file.nit b/lib/core/file.nit index fd848e1..8bf8078 100644 --- a/lib/core/file.nit +++ b/lib/core/file.nit @@ -49,23 +49,24 @@ abstract class FileStream # Return null in case of error fun file_stat: nullable FileStat do - var stat = _file.file_stat + var stat = _file.as(not null).file_stat if stat.address_is_null then return null return new FileStat(stat) end # File descriptor of this file - fun fd: Int do return _file.fileno + fun fd: Int do return _file.as(not null).fileno redef fun close do - if _file == null then return - if _file.address_is_null then + var file = _file + if file == null then return + if file.address_is_null then if last_error != null then return last_error = new IOError("Cannot close unopened file") return end - var i = _file.io_close + var i = file.io_close if i != 0 then last_error = new IOError("Close failed due to error {sys.errno.strerror}") end @@ -83,7 +84,7 @@ abstract class FileStream # * `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 + if _file.as(not null).set_buffering_type(buf_size, mode) != 0 then last_error = new IOError("Error while changing buffering type for FileStream, returned error {sys.errno.strerror}") end end @@ -105,10 +106,10 @@ class FileReader # assert l == f.read_line fun reopen do - if not eof and not _file.address_is_null then close + if not eof and not _file.as(not null).address_is_null then close last_error = null - _file = new NativeFile.io_open_read(path.to_cstring) - if _file.address_is_null then + _file = new NativeFile.io_open_read(path.as(not null).to_cstring) + if _file.as(not null).address_is_null then last_error = new IOError("Cannot open `{path.as(not null)}`: {sys.errno.strerror}") end_reached = true return @@ -126,8 +127,8 @@ class FileReader redef fun fill_buffer do - var nb = _file.io_read(_buffer, _buffer_capacity) - if last_error == null and _file.ferror then + var nb = _file.as(not null).io_read(_buffer, _buffer_capacity) + if last_error == null and _file.as(not null).ferror then last_error = new IOError("Cannot read `{path.as(not null)}`: {sys.errno.strerror}") end_reached = true end @@ -158,7 +159,7 @@ class FileReader self.path = path prepare_buffer(100) _file = new NativeFile.io_open_read(path.to_cstring) - if _file.address_is_null then + if _file.as(not null).address_is_null then last_error = new IOError("Cannot open `{path}`: {sys.errno.strerror}") end_reached = true end @@ -171,7 +172,7 @@ class FileReader self.path = "" prepare_buffer(1) _file = fd.fd_to_stream(read_only) - if _file.address_is_null then + if _file.as(not null).address_is_null then last_error = new IOError("Error: Converting fd {fd} to stream failed with '{sys.errno.strerror}'") end_reached = true end @@ -187,7 +188,7 @@ class FileReader end private fun native_poll_in(fd: Int): Int `{ - struct pollfd fds = {fd, POLLIN, 0}; + struct pollfd fds = {(int)fd, POLLIN, 0}; return poll(&fds, 1, 0); `} end @@ -223,13 +224,13 @@ class FileWriter last_error = new IOError("Cannot write to non-writable stream") return end - if _file.address_is_null then + if _file.as(not null).address_is_null then last_error = new IOError("Writing on a null stream") _is_writable = false return end - var err = _file.write_byte(value) + var err = _file.as(not null).write_byte(value) if err != 1 then # Big problem last_error = new IOError("Problem writing a byte: {err}") @@ -251,12 +252,12 @@ class FileWriter last_error = new IOError("Cannot write to non-writable stream") return end - if _file.address_is_null then + if _file.as(not null).address_is_null then last_error = new IOError("Writing on a null stream") _is_writable = false return end - var err = _file.io_write(native, from, len) + var err = _file.as(not null).io_write(native, from, len) if err != len then # Big problem last_error = new IOError("Problem in writing : {err} {len} \n") @@ -269,7 +270,7 @@ class FileWriter _file = new NativeFile.io_open_write(path.to_cstring) self.path = path _is_writable = true - if _file.address_is_null then + if _file.as(not null).address_is_null then last_error = new IOError("Cannot open `{path}`: {sys.errno.strerror}") is_writable = false end @@ -280,7 +281,7 @@ class FileWriter self.path = "" _file = fd.fd_to_stream(wipe_write) _is_writable = true - if _file.address_is_null then + if _file.as(not null).address_is_null then last_error = new IOError("Error: Opening stream from file descriptor {fd} failed with '{sys.errno.strerror}'") _is_writable = false end @@ -292,7 +293,7 @@ redef class Int # # NOTE: The `mode` specified must be compatible with the one used in the file descriptor. private fun fd_to_stream(mode: NativeString): NativeFile `{ - return fdopen(self, mode); + return fdopen((int)self, mode); `} end @@ -498,8 +499,8 @@ class Path var output = dest.open_wo while not input.eof do - var buffer = input.read(1024) - output.write buffer + var buffer = input.read_bytes(1024) + output.write_bytes buffer end input.close @@ -663,6 +664,19 @@ class Path return res end + # Is `self` the path to an existing directory ? + # + # ~~~nit + # assert ".".to_path.is_dir + # assert not "/etc/issue".to_path.is_dir + # assert not "/should/not/exist".to_path.is_dir + # ~~~ + fun is_dir: Bool do + var st = stat + if st == null then return false + return st.is_dir + end + # Delete a directory and all of its content # # Does not go through symbolic links and may get stuck in a cycle if there @@ -1145,11 +1159,16 @@ redef class String # Create a directory (and all intermediate directories if needed) # + # The optional `mode` parameter specifies the permissions of the directory, + # the default value is `0o777`. + # # Return an error object in case of error. # # assert "/etc/".mkdir != null - fun mkdir: nullable Error + fun mkdir(mode: nullable Int): nullable Error do + mode = mode or else 0o777 + var dirs = self.split_with("/") var path = new FlatBuffer if dirs.is_empty then return null @@ -1162,7 +1181,7 @@ redef class String if d.is_empty then continue path.append(d) path.add('/') - var res = path.to_s.to_cstring.file_mkdir + var res = path.to_s.to_cstring.file_mkdir(mode) if not res and error == null then error = new IOError("Cannot create directory `{path}`: {sys.errno.strerror}") end @@ -1271,7 +1290,7 @@ redef class FlatString redef fun file_extension do var its = _items - var p = _last_byte + var p = last_byte var c = its[p] var st = _first_byte while p >= st and c != '.'.ascii do @@ -1279,12 +1298,12 @@ redef class FlatString c = its[p] end if p <= st then return null - var ls = _last_byte - return new FlatString.with_infos(its, ls - p, p + 1, ls) + var ls = last_byte + return new FlatString.with_infos(its, ls - p, p + 1) end redef fun basename(extension) do - var l = _last_byte + var l = last_byte var its = _items var min = _first_byte var sl = '/'.ascii @@ -1292,7 +1311,7 @@ redef class FlatString if l == min then return "/" var ns = l while ns >= min and its[ns] != sl do ns -= 1 - var bname = new FlatString.with_infos(its, l - ns, ns + 1, l) + var bname = new FlatString.with_infos(its, l - ns, ns + 1) return if extension != null then bname.strip_extension(extension) else bname end @@ -1326,7 +1345,7 @@ redef class NativeString return stat_element; `} - private fun file_mkdir: Bool `{ return !mkdir(self, 0777); `} + private fun file_mkdir(mode: Int): Bool `{ return !mkdir(self, mode); `} private fun rmdir: Bool `{ return !rmdir(self); `} @@ -1414,8 +1433,8 @@ private extern class NativeFile `{ FILE* `} fun flush: Int `{ return fflush(self); `} # Used to specify how the buffering will be handled for the current stream. - fun set_buffering_type(buf_length: Int, mode: Int): Int `{ - return setvbuf(self, NULL, mode, buf_length); + fun set_buffering_type(buf_length, mode: Int): Int `{ + return setvbuf(self, NULL, (int)mode, buf_length); `} new io_open_read(path: NativeString) `{ return fopen(path, "r"); `} @@ -1499,15 +1518,14 @@ redef class Sys int first_polled_fd = -1; int result; - in_len = Array_of_Int_length( in_fds ); - out_len = Array_of_Int_length( out_fds ); + in_len = (int)Array_of_Int_length( in_fds ); + out_len = (int)Array_of_Int_length( out_fds ); total_len = in_len + out_len; c_fds = malloc( sizeof(struct pollfd) * total_len ); /* input streams */ for ( i=0; i