@shd101wyy/yo 0.0.23 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/cjs/index.cjs +560 -520
- package/out/cjs/yo-cli.cjs +598 -558
- package/out/esm/index.mjs +551 -511
- package/out/types/src/codegen/exprs/arc.d.ts +5 -0
- package/out/types/src/codegen/types/generation.d.ts +2 -0
- package/out/types/src/codegen/utils/index.d.ts +8 -1
- package/out/types/src/evaluator/builtins/rc-fns.d.ts +5 -0
- package/out/types/src/evaluator/calls/arc.d.ts +15 -0
- package/out/types/src/evaluator/calls/trait-type.d.ts +8 -1
- package/out/types/src/evaluator/context.d.ts +11 -1
- package/out/types/src/evaluator/types/utils.d.ts +8 -3
- package/out/types/src/evaluator/utils/closure.d.ts +7 -1
- package/out/types/src/evaluator/values/impl.d.ts +8 -0
- package/out/types/src/expr.d.ts +6 -0
- package/out/types/src/test-runner.d.ts +2 -0
- package/out/types/src/types/creators.d.ts +2 -1
- package/out/types/src/types/definitions.d.ts +10 -0
- package/out/types/src/types/guards.d.ts +2 -1
- package/out/types/src/types/tags.d.ts +1 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/std/collections/array_list.yo +80 -10
- package/std/collections/btree_map.yo +120 -2
- package/std/collections/deque.yo +98 -6
- package/std/collections/hash_map.yo +137 -1
- package/std/collections/hash_set.yo +85 -1
- package/std/collections/linked_list.yo +61 -1
- package/std/collections/priority_queue.yo +70 -1
- package/std/crypto/md5.yo +4 -4
- package/std/crypto/random.yo +3 -3
- package/std/crypto/sha256.yo +8 -7
- package/std/encoding/base64.yo +6 -6
- package/std/encoding/hex.yo +27 -22
- package/std/encoding/json.yo +185 -186
- package/std/encoding/utf16.yo +2 -2
- package/std/fmt/display.yo +1 -1
- package/std/fmt/writer.yo +2 -4
- package/std/fs/dir.yo +5 -5
- package/std/fs/file.yo +21 -13
- package/std/fs/metadata.yo +4 -4
- package/std/fs/temp.yo +3 -3
- package/std/fs/types.yo +1 -1
- package/std/fs/walker.yo +1 -1
- package/std/net/addr.yo +2 -2
- package/std/net/dns.yo +21 -20
- package/std/net/errors.yo +1 -1
- package/std/net/tcp.yo +134 -100
- package/std/net/udp.yo +51 -42
- package/std/os/env.yo +21 -23
- package/std/os/signal.yo +10 -9
- package/std/prelude.yo +158 -22
- package/std/string/string.yo +99 -1
- package/std/sync/once.yo +1 -1
- package/std/{io → sys}/advise.yo +1 -1
- package/std/sys/bufio/buf_reader.yo +300 -0
- package/std/sys/bufio/buf_writer.yo +168 -0
- package/std/{io → sys}/clock.yo +1 -1
- package/std/{io → sys}/constants.yo +1 -1
- package/std/{io → sys}/copy.yo +1 -1
- package/std/{io → sys}/dir.yo +6 -6
- package/std/{io → sys}/dns.yo +3 -3
- package/std/{io → sys}/errors.yo +1 -1
- package/std/{io → sys}/events.yo +1 -1
- package/std/{io → sys}/externs.yo +1 -1
- package/std/{io → sys}/fallocate.yo +1 -1
- package/std/{io → sys}/fcntl.yo +1 -1
- package/std/{io → sys}/file.yo +1 -1
- package/std/{io → sys}/future.yo +1 -1
- package/std/{io → sys}/iov.yo +1 -1
- package/std/{io → sys}/lock.yo +1 -1
- package/std/{io → sys}/mmap.yo +1 -1
- package/std/{io → sys}/path.yo +1 -1
- package/std/{io → sys}/perm.yo +3 -3
- package/std/{io → sys}/pipe.yo +1 -1
- package/std/{io → sys}/process.yo +1 -1
- package/std/{io → sys}/seek.yo +1 -1
- package/std/{io → sys}/signal.yo +1 -1
- package/std/{io → sys}/signals.yo +1 -1
- package/std/{io → sys}/socket.yo +1 -1
- package/std/{io → sys}/socketpair.yo +1 -1
- package/std/{io → sys}/sockinfo.yo +1 -1
- package/std/{io → sys}/statfs.yo +2 -2
- package/std/{io → sys}/statx.yo +1 -1
- package/std/{io → sys}/sysinfo.yo +1 -1
- package/std/{io → sys}/tcp.yo +3 -3
- package/std/{io → sys}/temp.yo +1 -1
- package/std/{io → sys}/time.yo +2 -2
- package/std/{io → sys}/timer.yo +1 -1
- package/std/{io → sys}/tty.yo +1 -1
- package/std/{io → sys}/udp.yo +4 -4
- package/std/{io → sys}/umask.yo +1 -1
- package/std/{io → sys}/unix.yo +1 -1
- package/std/time/datetime.yo +18 -23
- package/std/time/instant.yo +13 -11
- package/std/url/url.yo +533 -0
- package/std/math/functions.yo +0 -74
- package/std/math/random.yo +0 -94
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
// std/sys/bufio/buf_reader.yo - Buffered reader for file descriptors
|
|
2
|
+
//
|
|
3
|
+
// Wraps a file descriptor with an internal buffer for efficient reads.
|
|
4
|
+
// Reduces the number of system calls by reading data in larger chunks.
|
|
5
|
+
//
|
|
6
|
+
// Example:
|
|
7
|
+
// { BufReader } :: import "std/sys/bufio/buf_reader";
|
|
8
|
+
// IO_file :: import "std/sys/file";
|
|
9
|
+
//
|
|
10
|
+
// reader := BufReader.new(fd);
|
|
11
|
+
// line := io.await(reader.read_line(using(io)));
|
|
12
|
+
// match(line,
|
|
13
|
+
// .Ok(.Some(s)) => println(s),
|
|
14
|
+
// .Ok(.None) => println("EOF"),
|
|
15
|
+
// .Err(e) => println(e.to_string())
|
|
16
|
+
// );
|
|
17
|
+
|
|
18
|
+
{ ArrayList } :: import "../../collections/array_list";
|
|
19
|
+
open import "../../string";
|
|
20
|
+
{ IOError } :: import "../errors";
|
|
21
|
+
IO_file :: import "../file";
|
|
22
|
+
{ GlobalAllocator } :: import "../../allocator";
|
|
23
|
+
{ malloc, free } :: GlobalAllocator;
|
|
24
|
+
|
|
25
|
+
_DEFAULT_BUF_SIZE :: usize(4096);
|
|
26
|
+
_NEWLINE :: u8(10); // '\n'
|
|
27
|
+
|
|
28
|
+
BufReader :: object(
|
|
29
|
+
_fd : i32,
|
|
30
|
+
_buf : ArrayList(u8),
|
|
31
|
+
_pos : usize,
|
|
32
|
+
_filled : usize,
|
|
33
|
+
_offset : u64,
|
|
34
|
+
_capacity : usize
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
impl(BufReader,
|
|
38
|
+
// Create a buffered reader with default buffer size (4096 bytes).
|
|
39
|
+
new : (fn(fd: i32) -> Self)(
|
|
40
|
+
Self(
|
|
41
|
+
_fd: fd,
|
|
42
|
+
_buf: ArrayList(u8).with_capacity(_DEFAULT_BUF_SIZE),
|
|
43
|
+
_pos: usize(0),
|
|
44
|
+
_filled: usize(0),
|
|
45
|
+
_offset: u64(0),
|
|
46
|
+
_capacity: _DEFAULT_BUF_SIZE
|
|
47
|
+
)
|
|
48
|
+
),
|
|
49
|
+
|
|
50
|
+
// Create a buffered reader with a custom buffer size.
|
|
51
|
+
with_capacity : (fn(fd: i32, capacity: usize) -> Self)(
|
|
52
|
+
Self(
|
|
53
|
+
_fd: fd,
|
|
54
|
+
_buf: ArrayList(u8).with_capacity(capacity),
|
|
55
|
+
_pos: usize(0),
|
|
56
|
+
_filled: usize(0),
|
|
57
|
+
_offset: u64(0),
|
|
58
|
+
_capacity: capacity
|
|
59
|
+
)
|
|
60
|
+
),
|
|
61
|
+
|
|
62
|
+
// Return the underlying file descriptor.
|
|
63
|
+
fd : (fn(self: Self) -> i32)(
|
|
64
|
+
self._fd
|
|
65
|
+
),
|
|
66
|
+
|
|
67
|
+
// Return the number of buffered bytes available to read without I/O.
|
|
68
|
+
buffered : (fn(self: Self) -> usize)(
|
|
69
|
+
(self._filled - self._pos)
|
|
70
|
+
),
|
|
71
|
+
|
|
72
|
+
// Read a line from the reader (up to and including '\n').
|
|
73
|
+
// Returns .None on EOF when no data is available.
|
|
74
|
+
// Returns .Some(line) with the line content (without the trailing '\n').
|
|
75
|
+
read_line : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(Option(String), IOError), IO)))({
|
|
76
|
+
the_fd := self._fd;
|
|
77
|
+
io.async((using(io : IO)) => {
|
|
78
|
+
line_bytes := ArrayList(u8).new();
|
|
79
|
+
found_newline := false;
|
|
80
|
+
hit_eof := false;
|
|
81
|
+
(read_err : Option(IOError)) = .None;
|
|
82
|
+
|
|
83
|
+
while runtime((((!(found_newline)) && (!(hit_eof))) && read_err.is_none())), {
|
|
84
|
+
cond(
|
|
85
|
+
(self._pos < self._filled) => {
|
|
86
|
+
scan := self._pos;
|
|
87
|
+
while runtime(((scan < self._filled) && (!(found_newline)))), {
|
|
88
|
+
b := self._buf.get(scan).unwrap();
|
|
89
|
+
cond(
|
|
90
|
+
(b == _NEWLINE) => {
|
|
91
|
+
found_newline = true;
|
|
92
|
+
},
|
|
93
|
+
true => {
|
|
94
|
+
line_bytes.push(b);
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
scan = (scan + usize(1));
|
|
98
|
+
};
|
|
99
|
+
self._pos = scan;
|
|
100
|
+
},
|
|
101
|
+
true => {
|
|
102
|
+
raw_buf := *(u8)(malloc(self._capacity).unwrap());
|
|
103
|
+
n := io.await(IO_file.read(the_fd, raw_buf, u32(self._capacity), self._offset));
|
|
104
|
+
cond(
|
|
105
|
+
(n < i32(0)) => {
|
|
106
|
+
free(.Some(*(void)(raw_buf)));
|
|
107
|
+
read_err = .Some(IOError.from_errno((i32(0) - n)));
|
|
108
|
+
},
|
|
109
|
+
(n == i32(0)) => {
|
|
110
|
+
free(.Some(*(void)(raw_buf)));
|
|
111
|
+
hit_eof = true;
|
|
112
|
+
},
|
|
113
|
+
true => {
|
|
114
|
+
self._offset = (self._offset + u64(n));
|
|
115
|
+
self._buf = ArrayList(u8).with_capacity(self._capacity);
|
|
116
|
+
i := usize(0);
|
|
117
|
+
while runtime((i < usize(n))), {
|
|
118
|
+
self._buf.push((raw_buf &+ i).*);
|
|
119
|
+
i = (i + usize(1));
|
|
120
|
+
};
|
|
121
|
+
self._pos = usize(0);
|
|
122
|
+
self._filled = usize(n);
|
|
123
|
+
free(.Some(*(void)(raw_buf)));
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
match(read_err,
|
|
131
|
+
.Some(e) => .Err(e),
|
|
132
|
+
.None =>
|
|
133
|
+
cond(
|
|
134
|
+
(hit_eof && (line_bytes.len() == usize(0))) => .Ok(.None),
|
|
135
|
+
true => .Ok(.Some(String.from_bytes(line_bytes)))
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
})
|
|
139
|
+
}),
|
|
140
|
+
|
|
141
|
+
// Read up to `size` bytes into a provided buffer.
|
|
142
|
+
// Returns the number of bytes actually read.
|
|
143
|
+
read : (fn(self: Self, buf: *(u8), size: u32, using(io : IO)) -> Impl(Future(Result(i32, IOError), IO)))({
|
|
144
|
+
the_fd := self._fd;
|
|
145
|
+
io.async((using(io : IO)) => {
|
|
146
|
+
available := (self._filled - self._pos);
|
|
147
|
+
(read_err : Option(IOError)) = .None;
|
|
148
|
+
(read_n : i32) = i32(0);
|
|
149
|
+
done := false;
|
|
150
|
+
|
|
151
|
+
// If there's data already buffered, serve from buffer
|
|
152
|
+
cond(
|
|
153
|
+
(available > usize(0)) => {
|
|
154
|
+
to_copy := cond(
|
|
155
|
+
(available < usize(size)) => available,
|
|
156
|
+
true => usize(size)
|
|
157
|
+
);
|
|
158
|
+
i := usize(0);
|
|
159
|
+
while runtime((i < to_copy)), {
|
|
160
|
+
b := self._buf.get((self._pos + i)).unwrap();
|
|
161
|
+
(buf &+ i).* = b;
|
|
162
|
+
i = (i + usize(1));
|
|
163
|
+
};
|
|
164
|
+
self._pos = (self._pos + to_copy);
|
|
165
|
+
read_n = i32(to_copy);
|
|
166
|
+
done = true;
|
|
167
|
+
},
|
|
168
|
+
true => ()
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
// Buffer is empty and large read: bypass buffer
|
|
172
|
+
cond(
|
|
173
|
+
((!(done)) && (usize(size) >= self._capacity)) => {
|
|
174
|
+
n := io.await(IO_file.read(the_fd, buf, size, self._offset));
|
|
175
|
+
cond(
|
|
176
|
+
(n < i32(0)) => {
|
|
177
|
+
read_err = .Some(IOError.from_errno((i32(0) - n)));
|
|
178
|
+
},
|
|
179
|
+
true => {
|
|
180
|
+
self._offset = (self._offset + u64(n));
|
|
181
|
+
read_n = n;
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
done = true;
|
|
185
|
+
},
|
|
186
|
+
true => ()
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
// Buffer is empty and small read: fill buffer first
|
|
190
|
+
cond(
|
|
191
|
+
(!(done)) => {
|
|
192
|
+
raw_buf := *(u8)(malloc(self._capacity).unwrap());
|
|
193
|
+
n := io.await(IO_file.read(the_fd, raw_buf, u32(self._capacity), self._offset));
|
|
194
|
+
cond(
|
|
195
|
+
(n < i32(0)) => {
|
|
196
|
+
free(.Some(*(void)(raw_buf)));
|
|
197
|
+
read_err = .Some(IOError.from_errno((i32(0) - n)));
|
|
198
|
+
},
|
|
199
|
+
(n == i32(0)) => {
|
|
200
|
+
free(.Some(*(void)(raw_buf)));
|
|
201
|
+
read_n = i32(0);
|
|
202
|
+
},
|
|
203
|
+
true => {
|
|
204
|
+
self._offset = (self._offset + u64(n));
|
|
205
|
+
self._buf = ArrayList(u8).with_capacity(self._capacity);
|
|
206
|
+
i := usize(0);
|
|
207
|
+
while runtime((i < usize(n))), {
|
|
208
|
+
self._buf.push((raw_buf &+ i).*);
|
|
209
|
+
i = (i + usize(1));
|
|
210
|
+
};
|
|
211
|
+
self._pos = usize(0);
|
|
212
|
+
self._filled = usize(n);
|
|
213
|
+
free(.Some(*(void)(raw_buf)));
|
|
214
|
+
|
|
215
|
+
to_copy := cond(
|
|
216
|
+
(usize(n) < usize(size)) => usize(n),
|
|
217
|
+
true => usize(size)
|
|
218
|
+
);
|
|
219
|
+
j := usize(0);
|
|
220
|
+
while runtime((j < to_copy)), {
|
|
221
|
+
b := self._buf.get(j).unwrap();
|
|
222
|
+
(buf &+ j).* = b;
|
|
223
|
+
j = (j + usize(1));
|
|
224
|
+
};
|
|
225
|
+
self._pos = to_copy;
|
|
226
|
+
read_n = i32(to_copy);
|
|
227
|
+
}
|
|
228
|
+
);
|
|
229
|
+
},
|
|
230
|
+
true => ()
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
match(read_err,
|
|
234
|
+
.Some(e) => .Err(e),
|
|
235
|
+
.None => .Ok(read_n)
|
|
236
|
+
)
|
|
237
|
+
})
|
|
238
|
+
}),
|
|
239
|
+
|
|
240
|
+
// Read all remaining data into an ArrayList of bytes.
|
|
241
|
+
read_all : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(ArrayList(u8), IOError), IO)))({
|
|
242
|
+
the_fd := self._fd;
|
|
243
|
+
io.async((using(io : IO)) => {
|
|
244
|
+
result := ArrayList(u8).new();
|
|
245
|
+
|
|
246
|
+
// First drain any buffered data
|
|
247
|
+
cond(
|
|
248
|
+
(self._pos < self._filled) => {
|
|
249
|
+
i := self._pos;
|
|
250
|
+
while runtime((i < self._filled)), {
|
|
251
|
+
result.push(self._buf.get(i).unwrap());
|
|
252
|
+
i = (i + usize(1));
|
|
253
|
+
};
|
|
254
|
+
self._pos = self._filled;
|
|
255
|
+
},
|
|
256
|
+
true => ()
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
// Then read the rest from fd
|
|
260
|
+
raw_buf := *(u8)(malloc(self._capacity).unwrap());
|
|
261
|
+
(read_err : Option(IOError)) = .None;
|
|
262
|
+
while runtime(true), {
|
|
263
|
+
n := io.await(IO_file.read(the_fd, raw_buf, u32(self._capacity), self._offset));
|
|
264
|
+
cond(
|
|
265
|
+
(n < i32(0)) => {
|
|
266
|
+
read_err = .Some(IOError.from_errno((i32(0) - n)));
|
|
267
|
+
break;
|
|
268
|
+
},
|
|
269
|
+
(n == i32(0)) => break,
|
|
270
|
+
true => {
|
|
271
|
+
self._offset = (self._offset + u64(n));
|
|
272
|
+
j := usize(0);
|
|
273
|
+
while runtime((j < usize(n))), {
|
|
274
|
+
result.push((raw_buf &+ j).*);
|
|
275
|
+
j = (j + usize(1));
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
};
|
|
280
|
+
free(.Some(*(void)(raw_buf)));
|
|
281
|
+
match(read_err,
|
|
282
|
+
.Some(e) => .Err(e),
|
|
283
|
+
.None => .Ok(result)
|
|
284
|
+
)
|
|
285
|
+
})
|
|
286
|
+
}),
|
|
287
|
+
|
|
288
|
+
// Read all remaining data as a String.
|
|
289
|
+
read_to_string : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(String, IOError), IO)))(
|
|
290
|
+
io.async((using(io : IO)) => {
|
|
291
|
+
bytes_result := io.await(self.read_all(using(io)));
|
|
292
|
+
match(bytes_result,
|
|
293
|
+
.Ok(bytes) => .Ok(String.from_bytes(bytes)),
|
|
294
|
+
.Err(e) => .Err(e)
|
|
295
|
+
)
|
|
296
|
+
})
|
|
297
|
+
)
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
export BufReader;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// std/sys/bufio/buf_writer.yo - Buffered writer for file descriptors
|
|
2
|
+
//
|
|
3
|
+
// Wraps a file descriptor with an internal buffer for efficient writes.
|
|
4
|
+
// Reduces the number of system calls by batching small writes together.
|
|
5
|
+
//
|
|
6
|
+
// Example:
|
|
7
|
+
// { BufWriter } :: import "std/sys/bufio/buf_writer";
|
|
8
|
+
//
|
|
9
|
+
// writer := BufWriter.new(fd);
|
|
10
|
+
// io.await(writer.write_string(String.from("hello\n"), using(io)));
|
|
11
|
+
// io.await(writer.flush(using(io)));
|
|
12
|
+
|
|
13
|
+
{ ArrayList } :: import "../../collections/array_list";
|
|
14
|
+
open import "../../string";
|
|
15
|
+
{ IOError } :: import "../errors";
|
|
16
|
+
IO_file :: import "../file";
|
|
17
|
+
{ GlobalAllocator } :: import "../../allocator";
|
|
18
|
+
{ malloc, free } :: GlobalAllocator;
|
|
19
|
+
|
|
20
|
+
_DEFAULT_BUF_SIZE :: usize(4096);
|
|
21
|
+
|
|
22
|
+
BufWriter :: object(
|
|
23
|
+
_fd : i32,
|
|
24
|
+
_buf : ArrayList(u8),
|
|
25
|
+
_offset : u64,
|
|
26
|
+
_capacity : usize
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
impl(BufWriter,
|
|
30
|
+
// Create a buffered writer with default buffer size (4096 bytes).
|
|
31
|
+
new : (fn(fd: i32) -> Self)(
|
|
32
|
+
Self(
|
|
33
|
+
_fd: fd,
|
|
34
|
+
_buf: ArrayList(u8).with_capacity(_DEFAULT_BUF_SIZE),
|
|
35
|
+
_offset: u64(0),
|
|
36
|
+
_capacity: _DEFAULT_BUF_SIZE
|
|
37
|
+
)
|
|
38
|
+
),
|
|
39
|
+
|
|
40
|
+
// Create a buffered writer with a custom buffer size.
|
|
41
|
+
with_capacity : (fn(fd: i32, capacity: usize) -> Self)(
|
|
42
|
+
Self(
|
|
43
|
+
_fd: fd,
|
|
44
|
+
_buf: ArrayList(u8).with_capacity(capacity),
|
|
45
|
+
_offset: u64(0),
|
|
46
|
+
_capacity: capacity
|
|
47
|
+
)
|
|
48
|
+
),
|
|
49
|
+
|
|
50
|
+
// Return the underlying file descriptor.
|
|
51
|
+
fd : (fn(self: Self) -> i32)(
|
|
52
|
+
self._fd
|
|
53
|
+
),
|
|
54
|
+
|
|
55
|
+
// Return the number of bytes currently buffered.
|
|
56
|
+
buffered : (fn(self: Self) -> usize)(
|
|
57
|
+
self._buf.len()
|
|
58
|
+
),
|
|
59
|
+
|
|
60
|
+
// Internal: flush the buffer contents to fd.
|
|
61
|
+
_flush_inner : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(unit, IOError), IO)))({
|
|
62
|
+
the_fd := self._fd;
|
|
63
|
+
io.async((using(io : IO)) => {
|
|
64
|
+
(write_err : Option(IOError)) = .None;
|
|
65
|
+
|
|
66
|
+
cond(
|
|
67
|
+
(self._buf.len() > usize(0)) => {
|
|
68
|
+
written := usize(0);
|
|
69
|
+
total := self._buf.len();
|
|
70
|
+
|
|
71
|
+
while runtime(((written < total) && write_err.is_none())), {
|
|
72
|
+
remaining := u32((total - written));
|
|
73
|
+
buf_ptr := self._buf.ptr().unwrap();
|
|
74
|
+
n := io.await(IO_file.write(the_fd, (buf_ptr &+ written), remaining, self._offset));
|
|
75
|
+
cond(
|
|
76
|
+
(n < i32(0)) => {
|
|
77
|
+
write_err = .Some(IOError.from_errno((i32(0) - n)));
|
|
78
|
+
},
|
|
79
|
+
true => {
|
|
80
|
+
written = (written + usize(n));
|
|
81
|
+
self._offset = (self._offset + u64(n));
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
self._buf = ArrayList(u8).with_capacity(self._capacity);
|
|
87
|
+
},
|
|
88
|
+
true => ()
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
match(write_err,
|
|
92
|
+
.Some(e) => .Err(e),
|
|
93
|
+
.None => .Ok(())
|
|
94
|
+
)
|
|
95
|
+
})
|
|
96
|
+
}),
|
|
97
|
+
|
|
98
|
+
// Write bytes from a pointer into the buffer.
|
|
99
|
+
// Automatically flushes when the buffer is full.
|
|
100
|
+
// Returns total number of bytes written.
|
|
101
|
+
write : (fn(self: Self, data: *(u8), size: u32, using(io : IO)) -> Impl(Future(Result(i32, IOError), IO)))({
|
|
102
|
+
the_fd := self._fd;
|
|
103
|
+
io.async((using(io : IO)) => {
|
|
104
|
+
remaining := usize(size);
|
|
105
|
+
src_pos := usize(0);
|
|
106
|
+
(write_err : Option(IOError)) = .None;
|
|
107
|
+
|
|
108
|
+
while runtime(((remaining > usize(0)) && write_err.is_none())), {
|
|
109
|
+
space := (self._capacity - self._buf.len());
|
|
110
|
+
cond(
|
|
111
|
+
(space == usize(0)) => {
|
|
112
|
+
// Buffer full, flush it
|
|
113
|
+
flush_result := io.await(self._flush_inner(using(io)));
|
|
114
|
+
match(flush_result,
|
|
115
|
+
.Err(e) => { write_err = .Some(e); },
|
|
116
|
+
.Ok(_) => ()
|
|
117
|
+
);
|
|
118
|
+
},
|
|
119
|
+
true => {
|
|
120
|
+
to_copy := cond(
|
|
121
|
+
(remaining < space) => remaining,
|
|
122
|
+
true => space
|
|
123
|
+
);
|
|
124
|
+
i := usize(0);
|
|
125
|
+
while runtime((i < to_copy)), {
|
|
126
|
+
self._buf.push((data &+ (src_pos + i)).*);
|
|
127
|
+
i = (i + usize(1));
|
|
128
|
+
};
|
|
129
|
+
src_pos = (src_pos + to_copy);
|
|
130
|
+
remaining = (remaining - to_copy);
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
match(write_err,
|
|
136
|
+
.Some(e) => .Err(e),
|
|
137
|
+
.None => .Ok(i32(size))
|
|
138
|
+
)
|
|
139
|
+
})
|
|
140
|
+
}),
|
|
141
|
+
|
|
142
|
+
// Write a String to the buffer.
|
|
143
|
+
write_string : (fn(self: Self, s: String, using(io : IO)) -> Impl(Future(Result(i32, IOError), IO)))(
|
|
144
|
+
io.async((using(io : IO)) => {
|
|
145
|
+
bytes := s.as_bytes();
|
|
146
|
+
result := io.await(self.write(bytes.ptr().unwrap(), u32(bytes.len()), using(io)));
|
|
147
|
+
result
|
|
148
|
+
})
|
|
149
|
+
),
|
|
150
|
+
|
|
151
|
+
// Write bytes from an ArrayList to the buffer.
|
|
152
|
+
write_bytes : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(Result(i32, IOError), IO)))(
|
|
153
|
+
io.async((using(io : IO)) => {
|
|
154
|
+
result := io.await(self.write(data.ptr().unwrap(), u32(data.len()), using(io)));
|
|
155
|
+
result
|
|
156
|
+
})
|
|
157
|
+
),
|
|
158
|
+
|
|
159
|
+
// Flush all buffered data to the underlying file descriptor.
|
|
160
|
+
flush : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(unit, IOError), IO)))(
|
|
161
|
+
io.async((using(io : IO)) => {
|
|
162
|
+
flush_result := io.await(self._flush_inner(using(io)));
|
|
163
|
+
flush_result
|
|
164
|
+
})
|
|
165
|
+
)
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
export BufWriter;
|
package/std/{io → sys}/clock.yo
RENAMED
package/std/{io → sys}/copy.yo
RENAMED
package/std/{io → sys}/dir.yo
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// std/
|
|
1
|
+
// std/sys/dir.yo - Directory operations
|
|
2
2
|
//
|
|
3
3
|
// Provides low-level directory manipulation wrappers around C runtime externs.
|
|
4
4
|
//
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
// - Negative value: -errno on failure
|
|
13
13
|
//
|
|
14
14
|
// Example:
|
|
15
|
-
// { AT_FDCWD } :: import "std/
|
|
16
|
-
// { mkdir, unlink, rename } :: import "std/
|
|
15
|
+
// { AT_FDCWD } :: import "std/sys/constants";
|
|
16
|
+
// { mkdir, unlink, rename } :: import "std/sys/dir";
|
|
17
17
|
//
|
|
18
18
|
// task := async {
|
|
19
19
|
// result := await mkdir(AT_FDCWD, *(u8)("/tmp/yo_test_dir"), i32(0o755));
|
|
@@ -83,9 +83,9 @@ readlink :: (fn(dirfd: i32, path: *(u8), buf: *(u8), bufsize: usize) -> i32)(
|
|
|
83
83
|
// Iterate entries using dirent_reclen to advance through the buffer.
|
|
84
84
|
//
|
|
85
85
|
// Usage pattern:
|
|
86
|
-
// { openat, close } :: import "std/
|
|
87
|
-
// { AT_FDCWD, O_RDONLY, O_DIRECTORY } :: import "std/
|
|
88
|
-
// { getdents, dirent_name, dirent_type } :: import "std/
|
|
86
|
+
// { openat, close } :: import "std/sys/file";
|
|
87
|
+
// { AT_FDCWD, O_RDONLY, O_DIRECTORY } :: import "std/sys/constants";
|
|
88
|
+
// { getdents, dirent_name, dirent_type } :: import "std/sys/dir";
|
|
89
89
|
//
|
|
90
90
|
// async {
|
|
91
91
|
// fd := await openat(AT_FDCWD, *(u8)("/tmp"), (O_RDONLY | O_DIRECTORY), i32(0));
|
package/std/{io → sys}/dns.yo
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// std/
|
|
1
|
+
// std/sys/dns.yo - DNS resolution operations
|
|
2
2
|
//
|
|
3
3
|
// Provides async DNS resolution wrapping getaddrinfo/getnameinfo, plus
|
|
4
4
|
// accessors for iterating the linked list of addrinfo results.
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
// Example:
|
|
11
11
|
// { GlobalAllocator } :: import "../allocator";
|
|
12
12
|
// { malloc, free } :: GlobalAllocator;
|
|
13
|
-
// dns :: import "std/
|
|
14
|
-
// { AF_INET } :: import "std/
|
|
13
|
+
// dns :: import "std/sys/dns";
|
|
14
|
+
// { AF_INET } :: import "std/sys/socket";
|
|
15
15
|
//
|
|
16
16
|
// async {
|
|
17
17
|
// result_ptr := dns.alloc_result();
|
package/std/{io → sys}/errors.yo
RENAMED
package/std/{io → sys}/events.yo
RENAMED
package/std/{io → sys}/fcntl.yo
RENAMED
package/std/{io → sys}/file.yo
RENAMED
package/std/{io → sys}/future.yo
RENAMED
package/std/{io → sys}/iov.yo
RENAMED
package/std/{io → sys}/lock.yo
RENAMED
package/std/{io → sys}/mmap.yo
RENAMED
package/std/{io → sys}/path.yo
RENAMED
package/std/{io → sys}/perm.yo
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// std/
|
|
1
|
+
// std/sys/perm.yo - File permission and access operations
|
|
2
2
|
//
|
|
3
3
|
// Provides synchronous wrappers for chmod, chown, and access operations.
|
|
4
4
|
// All operations return i32 directly (no IOFuture overhead).
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
// - Negative value: -errno on failure
|
|
9
9
|
//
|
|
10
10
|
// Example:
|
|
11
|
-
// perm :: import "std/
|
|
12
|
-
// { AT_FDCWD, S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH, F_OK, R_OK, W_OK } :: import "std/
|
|
11
|
+
// perm :: import "std/sys/perm";
|
|
12
|
+
// { AT_FDCWD, S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH, F_OK, R_OK, W_OK } :: import "std/sys/constants";
|
|
13
13
|
//
|
|
14
14
|
// // Check if file exists and is readable
|
|
15
15
|
// ret := perm.access(AT_FDCWD, *(u8)("/tmp/test.txt"), (R_OK | W_OK));
|
package/std/{io → sys}/pipe.yo
RENAMED
package/std/{io → sys}/seek.yo
RENAMED
package/std/{io → sys}/signal.yo
RENAMED
package/std/{io → sys}/socket.yo
RENAMED