| 1 | module os |
| 2 | |
| 3 | pub struct File { |
| 4 | pub: |
| 5 | fd int |
| 6 | pub mut: |
| 7 | is_opened bool |
| 8 | } |
| 9 | |
| 10 | $if !js_browser { |
| 11 | #const $buffer = require('buffer'); |
| 12 | } |
| 13 | // todo(playX): __as_cast is broken here |
| 14 | /* |
| 15 | pub struct ErrFileNotOpened { |
| 16 | msg string = 'os: file not opened' |
| 17 | code int |
| 18 | } |
| 19 | pub struct ErrSizeOfTypeIs0 { |
| 20 | msg string = 'os: size of type is 0' |
| 21 | code int |
| 22 | } |
| 23 | fn error_file_not_opened() IError { |
| 24 | return (&ErrFileNotOpened{}) |
| 25 | } |
| 26 | fn error_size_of_type_0() IError { |
| 27 | return (&ErrSizeOfTypeIs0{}) |
| 28 | } |
| 29 | */ |
| 30 | pub fn open_file(path string, mode string, options ...int) !File { |
| 31 | mut res := File{} |
| 32 | $if js_node { |
| 33 | #if (!options) { options = new array([]); } |
| 34 | #let permissions = 0o666 |
| 35 | #if (options.arr.length > 0) { permissions = options.arr[0]; } |
| 36 | #try { |
| 37 | #res.fd = new int($fs.openSync(''+path,''+mode,permissions)) |
| 38 | #} catch (e) { |
| 39 | #return error(new string('' + e)); |
| 40 | #} |
| 41 | |
| 42 | res.is_opened = true |
| 43 | } $else { |
| 44 | error('cannot open file on non NodeJS runtime') |
| 45 | } |
| 46 | return res |
| 47 | } |
| 48 | |
| 49 | // open tries to open a file for reading and returns back a read-only `File` object. |
| 50 | pub fn open(path string) !File { |
| 51 | f := open_file(path, 'r')! |
| 52 | return f |
| 53 | } |
| 54 | |
| 55 | pub fn create(path string) !File { |
| 56 | f := open_file(path, 'w')! |
| 57 | return f |
| 58 | } |
| 59 | |
| 60 | pub fn stdin() File { |
| 61 | return File{ |
| 62 | fd: 0 |
| 63 | is_opened: true |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | pub fn stdout() File { |
| 68 | return File{ |
| 69 | fd: 1 |
| 70 | is_opened: true |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | pub fn stderr() File { |
| 75 | return File{ |
| 76 | fd: 2 |
| 77 | is_opened: true |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | pub fn (f &File) read(mut buf []u8) !int { |
| 82 | if buf.len == 0 { |
| 83 | return 0 |
| 84 | } |
| 85 | mut nbytes := 0 |
| 86 | #try { |
| 87 | #let readBuffer = Buffer.alloc(buf.val.len.valueOf()); |
| 88 | #nbytes = $fs.readSync(f.val.fd.valueOf(), readBuffer, 0, buf.val.len.valueOf(), null); |
| 89 | # |
| 90 | #for (let i = 0; i < nbytes; i++) { buf.val.arr.arr[i] = new u8(readBuffer[i]); } |
| 91 | #} |
| 92 | #catch (e) { return error('' + e); } |
| 93 | |
| 94 | return nbytes |
| 95 | } |
| 96 | |
| 97 | pub fn (mut f File) write(buf []u8) !int { |
| 98 | if !f.is_opened { |
| 99 | return error('file is not opened') |
| 100 | } |
| 101 | mut nbytes := 0 |
| 102 | #buf.arr.make_copy() |
| 103 | #const b = $buffer.Buffer.from(buf.arr.arr.map((x) => x.valueOf())) |
| 104 | #try { $fs.writeSync(f.val.fd.valueOf(),b,0,buf.len.valueOf(),0); } catch (e) { return error(new string('' + e)); } |
| 105 | |
| 106 | return nbytes |
| 107 | } |
| 108 | |
| 109 | // writeln writes the string `s` into the file, and appends a \n character. |
| 110 | // It returns how many bytes were written, including the \n character. |
| 111 | pub fn (mut f File) writeln(s string) !int { |
| 112 | mut nbytes := f.write(s.bytes())! |
| 113 | nbytes += f.write('\n'.bytes())! |
| 114 | return nbytes |
| 115 | } |
| 116 | |
| 117 | pub fn (mut f File) write_to(pos u64, buf []u8) !int { |
| 118 | if !f.is_opened { |
| 119 | return error('file is not opened') |
| 120 | } |
| 121 | mut nbytes := 0 |
| 122 | #buf.arr.make_copy() |
| 123 | #const b = $buffer.Buffer.from(buf.arr.arr.map((x) => x.valueOf())) |
| 124 | #try { $fs.writeSync(f.val.fd.valueOf(),b,0,buf.len.valueOf(),pos.valueOf()); } catch (e) { return error(new string('' + e)); } |
| 125 | |
| 126 | return nbytes |
| 127 | } |
| 128 | |
| 129 | // write_string writes the string `s` into the file. |
| 130 | // It returns how many bytes were actually written. |
| 131 | pub fn (mut f File) write_string(s string) !int { |
| 132 | nbytes := f.write(s.bytes())! |
| 133 | return nbytes |
| 134 | } |
| 135 | |
| 136 | pub fn (mut f File) close() { |
| 137 | #$fs.closeSync(f.valueOf().fd.valueOf()) |
| 138 | } |
| 139 | |
| 140 | pub fn (mut f File) write_full_buffer(s voidptr, buffer_len usize) ! {} |
| 141 | |
| 142 | pub fn (mut f File) write_array(buffer array) !int { |
| 143 | if !f.is_opened { |
| 144 | return error('file is not opened') |
| 145 | } |
| 146 | mut nbytes := 0 |
| 147 | #buffer.arr.make_copy() |
| 148 | #const b = $buffer.Buffer.from(buffer.arr.arr.map((x) => x.valueOf())) |
| 149 | #try { $fs.writeSync(f.val.fd.valueOf(),b,0,buffer.len.valueOf(),0); } catch (e) { return error(new string('' + e)); } |
| 150 | |
| 151 | return nbytes |
| 152 | } |
| 153 | |