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 buffer = $fs.readFileSync(f.val.fd.valueOf()); |
88 | # |
89 | #for (const val of buffer.values()) { buf.arr[nbytes++] = val; } |
90 | #} |
91 | #catch (e) { return error('' + e); } |
92 | |
93 | return nbytes |
94 | } |
95 | |
96 | pub fn (mut f File) write(buf []u8) !int { |
97 | if !f.is_opened { |
98 | return error('file is not opened') |
99 | } |
100 | mut nbytes := 0 |
101 | #buf.arr.make_copy() |
102 | #const b = $buffer.Buffer.from(buf.arr.arr.map((x) => x.valueOf())) |
103 | #try { $fs.writeSync(f.val.fd.valueOf(),b,0,buf.len.valueOf(),0); } catch (e) { return error(new string('' + e)); } |
104 | |
105 | return nbytes |
106 | } |
107 | |
108 | // writeln writes the string `s` into the file, and appends a \n character. |
109 | // It returns how many bytes were written, including the \n character. |
110 | pub fn (mut f File) writeln(s string) !int { |
111 | mut nbytes := f.write(s.bytes())! |
112 | nbytes += f.write('\n'.bytes())! |
113 | return nbytes |
114 | } |
115 | |
116 | pub fn (mut f File) write_to(pos u64, buf []u8) !int { |
117 | if !f.is_opened { |
118 | return error('file is not opened') |
119 | } |
120 | mut nbytes := 0 |
121 | #buf.arr.make_copy() |
122 | #const b = $buffer.Buffer.from(buf.arr.arr.map((x) => x.valueOf())) |
123 | #try { $fs.writeSync(f.val.fd.valueOf(),b,0,buf.len.valueOf(),pos.valueOf()); } catch (e) { return error(new string('' + e)); } |
124 | |
125 | return nbytes |
126 | } |
127 | |
128 | // write_string writes the string `s` into the file |
129 | // It returns how many bytes were actually written. |
130 | pub fn (mut f File) write_string(s string) !int { |
131 | nbytes := f.write(s.bytes())! |
132 | return nbytes |
133 | } |
134 | |
135 | pub fn (mut f File) close() { |
136 | #$fs.closeSync(f.valueOf().fd.valueOf()) |
137 | } |
138 | |
139 | pub fn (mut f File) write_full_buffer(s voidptr, buffer_len usize) ! {} |
140 | |
141 | pub fn (mut f File) write_array(buffer array) !int { |
142 | if !f.is_opened { |
143 | return error('file is not opened') |
144 | } |
145 | mut nbytes := 0 |
146 | #buffer.arr.make_copy() |
147 | #const b = $buffer.Buffer.from(buffer.arr.arr.map((x) => x.valueOf())) |
148 | #try { $fs.writeSync(f.val.fd.valueOf(),b,0,buffer.len.valueOf(),0); } catch (e) { return error(new string('' + e)); } |
149 | |
150 | return nbytes |
151 | } |