mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
os: cleanup code duplication for os.create and os.open
This commit is contained in:
parent
03525843a0
commit
931c846602
@ -54,6 +54,9 @@ fn C.fseek() int
|
||||
fn C.fopen() voidptr
|
||||
|
||||
|
||||
fn C.fileno(voidptr) int
|
||||
|
||||
|
||||
fn C.fwrite() int
|
||||
|
||||
|
||||
|
113
vlib/os/os.v
113
vlib/os/os.v
@ -223,7 +223,10 @@ pub fn mv_by_cp(source string, target string) ?bool {
|
||||
return true
|
||||
}
|
||||
|
||||
fn vfopen(path, mode string) &C.FILE {
|
||||
// vfopen returns an opened C file, given its path and open mode.
|
||||
// NB: os.vfopen is useful for compatibility with C libraries, that expect `FILE *`.
|
||||
// If you write pure V code, os.create or os.open are more convenient.
|
||||
pub fn vfopen(path, mode string) &C.FILE {
|
||||
$if windows {
|
||||
return C._wfopen(path.to_wide(), mode.to_wide())
|
||||
} $else {
|
||||
@ -231,6 +234,15 @@ fn vfopen(path, mode string) &C.FILE {
|
||||
}
|
||||
}
|
||||
|
||||
// fileno returns the file descriptor of an opened C file
|
||||
pub fn fileno(cfile voidptr) int {
|
||||
$if windows {
|
||||
return C._fileno(cfile)
|
||||
} $else {
|
||||
return C.fileno(cfile)
|
||||
}
|
||||
}
|
||||
|
||||
// read_lines reads the file in `path` into an array of lines.
|
||||
pub fn read_lines(path string) ?[]string {
|
||||
buf := read_file(path) or {
|
||||
@ -1246,3 +1258,102 @@ pub fn resource_abs_path(path string) string {
|
||||
}
|
||||
return os.real_path(os.join_path(base_path, path))
|
||||
}
|
||||
|
||||
|
||||
// open tries to open a file for reading and returns back a read-only `File` object
|
||||
pub fn open(path string) ?File {
|
||||
/*
|
||||
$if linux {
|
||||
$if !android {
|
||||
fd := C.syscall(sys_open, path.str, 511)
|
||||
if fd == -1 {
|
||||
return error('failed to open file "$path"')
|
||||
}
|
||||
return File{
|
||||
fd: fd
|
||||
opened: true
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
cfile := vfopen(path, 'rb')
|
||||
if cfile == 0 {
|
||||
return error('failed to open file "$path"')
|
||||
}
|
||||
fd := fileno(cfile)
|
||||
return File {
|
||||
cfile: cfile
|
||||
fd: fd
|
||||
opened: true
|
||||
}
|
||||
}
|
||||
|
||||
// create creates or opens a file at a specified location and returns a write-only `File` object
|
||||
pub fn create(path string) ?File {
|
||||
/*
|
||||
// NB: android/termux/bionic is also a kind of linux,
|
||||
// but linux syscalls there sometimes fail,
|
||||
// while the libc version should work.
|
||||
$if linux {
|
||||
$if !android {
|
||||
//$if macos {
|
||||
// fd = C.syscall(398, path.str, 0x601, 0x1b6)
|
||||
//}
|
||||
//$if linux {
|
||||
fd = C.syscall(sys_creat, path.str, 511)
|
||||
//}
|
||||
if fd == -1 {
|
||||
return error('failed to create file "$path"')
|
||||
}
|
||||
file = File{
|
||||
fd: fd
|
||||
opened: true
|
||||
}
|
||||
return file
|
||||
}
|
||||
}
|
||||
*/
|
||||
cfile := vfopen(path, 'wb')
|
||||
if cfile == 0 {
|
||||
return error('failed to create file "$path"')
|
||||
}
|
||||
fd := fileno(cfile)
|
||||
return File {
|
||||
cfile: cfile
|
||||
fd: fd
|
||||
opened: true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut f File) write(s string) {
|
||||
if !f.opened {
|
||||
return
|
||||
}
|
||||
/*
|
||||
$if linux {
|
||||
$if !android {
|
||||
C.syscall(sys_write, f.fd, s.str, s.len)
|
||||
return
|
||||
}
|
||||
}
|
||||
*/
|
||||
C.fputs(s.str, f.cfile)
|
||||
}
|
||||
|
||||
pub fn (mut f File) writeln(s string) {
|
||||
if !f.opened {
|
||||
return
|
||||
}
|
||||
/*
|
||||
$if linux {
|
||||
$if !android {
|
||||
snl := s + '\n'
|
||||
C.syscall(sys_write, f.fd, snl.str, snl.len)
|
||||
return
|
||||
}
|
||||
}
|
||||
*/
|
||||
// TODO perf
|
||||
C.fputs(s.str, f.cfile)
|
||||
C.fputs('\n', f.cfile)
|
||||
}
|
||||
|
@ -66,112 +66,12 @@ pub fn is_dir(path string) bool {
|
||||
}
|
||||
*/
|
||||
|
||||
// open opens a file at the specified and returns back a read-only `File` object
|
||||
pub fn open(path string) ?File {
|
||||
/*
|
||||
$if linux {
|
||||
$if !android {
|
||||
fd := C.syscall(sys_open, path.str, 511)
|
||||
if fd == -1 {
|
||||
return error('failed to open file "$path"')
|
||||
}
|
||||
return File{
|
||||
fd: fd
|
||||
opened: true
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
file := File{
|
||||
cfile: C.fopen(charptr(path.str), 'rb')
|
||||
fd: 0
|
||||
opened: true
|
||||
}
|
||||
if isnil(file.cfile) {
|
||||
return error('failed to open file "$path"')
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
// create creates or opens a file at a specified location and returns a write-only `File` object
|
||||
pub fn create(path string) ?File {
|
||||
/*
|
||||
// NB: android/termux/bionic is also a kind of linux,
|
||||
// but linux syscalls there sometimes fail,
|
||||
// while the libc version should work.
|
||||
$if linux {
|
||||
$if !android {
|
||||
//$if macos {
|
||||
// fd = C.syscall(398, path.str, 0x601, 0x1b6)
|
||||
//}
|
||||
//$if linux {
|
||||
fd = C.syscall(sys_creat, path.str, 511)
|
||||
//}
|
||||
if fd == -1 {
|
||||
return error('failed to create file "$path"')
|
||||
}
|
||||
file = File{
|
||||
fd: fd
|
||||
opened: true
|
||||
}
|
||||
return file
|
||||
}
|
||||
}
|
||||
*/
|
||||
file := File{
|
||||
cfile: C.fopen(charptr(path.str), 'wb')
|
||||
fd: 0
|
||||
opened: true
|
||||
}
|
||||
if isnil(file.cfile) {
|
||||
return error('failed to create file "$path"')
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn (mut f File) fseek(pos, mode int) {
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
pub fn (mut f File) write(s string) {
|
||||
if !f.opened {
|
||||
return
|
||||
}
|
||||
/*
|
||||
$if linux {
|
||||
$if !android {
|
||||
C.syscall(sys_write, f.fd, s.str, s.len)
|
||||
return
|
||||
}
|
||||
}
|
||||
*/
|
||||
C.fputs(s.str, f.cfile)
|
||||
// C.fwrite(s.str, 1, s.len, f.cfile)
|
||||
}
|
||||
|
||||
pub fn (mut f File) writeln(s string) {
|
||||
if !f.opened {
|
||||
return
|
||||
}
|
||||
/*
|
||||
$if linux {
|
||||
$if !android {
|
||||
snl := s + '\n'
|
||||
C.syscall(sys_write, f.fd, snl.str, snl.len)
|
||||
return
|
||||
}
|
||||
}
|
||||
*/
|
||||
// C.fwrite(s.str, 1, s.len, f.cfile)
|
||||
// ss := s.clone()
|
||||
// TODO perf
|
||||
C.fputs(s.str, f.cfile)
|
||||
// ss.free()
|
||||
C.fputs('\n', f.cfile)
|
||||
}
|
||||
|
||||
// mkdir creates a new directory with the specified path.
|
||||
pub fn mkdir(path string) ?bool {
|
||||
if path == '.' {
|
||||
|
@ -130,47 +130,6 @@ pub fn is_dir(path string) bool {
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn open(path string) ?File {
|
||||
mode := 'rb'
|
||||
file := File {
|
||||
cfile: C._wfopen(path.to_wide(), mode.to_wide())
|
||||
opened: true
|
||||
}
|
||||
if isnil(file.cfile) {
|
||||
return error('failed to open file "$path"')
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
// create creates a file at a specified location and returns a writable `File` object.
|
||||
pub fn create(path string) ?File {
|
||||
mode := 'wb'
|
||||
file := File {
|
||||
cfile: C._wfopen(path.to_wide(), mode.to_wide())
|
||||
opened: true
|
||||
}
|
||||
if isnil(file.cfile) {
|
||||
return error('failed to create file "$path"')
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
pub fn (mut f File) write(s string) {
|
||||
if !f.opened {
|
||||
return
|
||||
}
|
||||
C.fputs(s.str, f.cfile)
|
||||
}
|
||||
|
||||
pub fn (mut f File) writeln(s string) {
|
||||
if !f.opened {
|
||||
return
|
||||
}
|
||||
// TODO perf
|
||||
C.fputs(s.str, f.cfile)
|
||||
C.fputs('\n', f.cfile)
|
||||
}
|
||||
|
||||
|
||||
// mkdir creates a new directory with the specified path.
|
||||
pub fn mkdir(path string) ?bool {
|
||||
@ -185,12 +144,11 @@ pub fn mkdir(path string) ?bool {
|
||||
// Ref - https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=vs-2019
|
||||
// get_file_handle retrieves the operating-system file handle that is associated with the specified file descriptor.
|
||||
pub fn get_file_handle(path string) HANDLE {
|
||||
mode := 'rb'
|
||||
fd := C._wfopen(path.to_wide(), mode.to_wide())
|
||||
if fd == 0 {
|
||||
cfile := vfopen(path, 'rb')
|
||||
if cfile == 0 {
|
||||
return HANDLE(INVALID_HANDLE_VALUE)
|
||||
}
|
||||
handle := HANDLE(C._get_osfhandle(C._fileno(fd))) // CreateFile? - hah, no -_-
|
||||
handle := HANDLE(C._get_osfhandle(fileno(cfile))) // CreateFile? - hah, no -_-
|
||||
return handle
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user