@shd101wyy/yo 0.1.26 → 0.1.27
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/.github/skills/yo-async-effects/SKILL.md +4 -4
- package/.github/skills/yo-async-effects/async-effects-recipes.md +34 -34
- package/.github/skills/yo-core-patterns/SKILL.md +1 -1
- package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +26 -26
- package/.github/skills/yo-project-workflow/SKILL.md +6 -3
- package/.github/skills/yo-project-workflow/workflow-cheatsheet.md +34 -11
- package/.github/skills/yo-syntax/SKILL.md +7 -6
- package/.github/skills/yo-syntax/syntax-cheatsheet.md +73 -60
- package/.github/skills/yo-wasm-integration/wasm-integration-cheatsheet.md +3 -3
- package/README.md +10 -8
- package/out/cjs/index.cjs +456 -438
- package/out/cjs/yo-cli.cjs +576 -543
- package/out/cjs/yo-lsp.cjs +559 -532
- package/out/esm/index.mjs +281 -263
- package/out/types/src/formatter.d.ts +11 -0
- package/out/types/src/lsp/formatting.d.ts +2 -0
- package/out/types/src/tests/formatter.test.d.ts +1 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/std/alg/hash.yo +13 -21
- package/std/allocator.yo +25 -40
- package/std/async.yo +3 -7
- package/std/build.yo +105 -151
- package/std/cli/arg_parser.yo +184 -169
- package/std/collections/array_list.yo +350 -314
- package/std/collections/btree_map.yo +142 -131
- package/std/collections/deque.yo +132 -128
- package/std/collections/hash_map.yo +542 -566
- package/std/collections/hash_set.yo +623 -687
- package/std/collections/linked_list.yo +275 -293
- package/std/collections/ordered_map.yo +113 -85
- package/std/collections/priority_queue.yo +73 -73
- package/std/crypto/md5.yo +191 -95
- package/std/crypto/random.yo +56 -64
- package/std/crypto/sha256.yo +151 -107
- package/std/encoding/base64.yo +87 -81
- package/std/encoding/hex.yo +43 -50
- package/std/encoding/html.yo +56 -81
- package/std/encoding/html_char_utils.yo +7 -13
- package/std/encoding/html_entities.yo +2248 -2253
- package/std/encoding/json.yo +316 -224
- package/std/encoding/punycode.yo +86 -116
- package/std/encoding/toml.yo +67 -66
- package/std/encoding/utf16.yo +37 -44
- package/std/env.yo +62 -91
- package/std/error.yo +7 -15
- package/std/fmt/display.yo +5 -9
- package/std/fmt/index.yo +8 -14
- package/std/fmt/to_string.yo +330 -315
- package/std/fmt/writer.yo +58 -87
- package/std/fs/dir.yo +83 -102
- package/std/fs/file.yo +147 -180
- package/std/fs/metadata.yo +45 -78
- package/std/fs/temp.yo +55 -65
- package/std/fs/types.yo +27 -40
- package/std/fs/walker.yo +53 -68
- package/std/gc.yo +5 -8
- package/std/glob.yo +30 -43
- package/std/http/client.yo +107 -120
- package/std/http/http.yo +106 -96
- package/std/http/index.yo +4 -6
- package/std/imm/list.yo +88 -93
- package/std/imm/map.yo +528 -464
- package/std/imm/set.yo +52 -57
- package/std/imm/sorted_map.yo +340 -286
- package/std/imm/sorted_set.yo +57 -63
- package/std/imm/string.yo +404 -345
- package/std/imm/vec.yo +173 -181
- package/std/io/reader.yo +3 -6
- package/std/io/writer.yo +4 -8
- package/std/libc/assert.yo +5 -9
- package/std/libc/ctype.yo +32 -22
- package/std/libc/dirent.yo +26 -25
- package/std/libc/errno.yo +164 -90
- package/std/libc/fcntl.yo +52 -45
- package/std/libc/float.yo +66 -44
- package/std/libc/limits.yo +42 -33
- package/std/libc/math.yo +53 -82
- package/std/libc/signal.yo +72 -47
- package/std/libc/stdatomic.yo +217 -188
- package/std/libc/stdint.yo +5 -29
- package/std/libc/stdio.yo +5 -29
- package/std/libc/stdlib.yo +32 -39
- package/std/libc/string.yo +5 -23
- package/std/libc/sys/stat.yo +58 -56
- package/std/libc/time.yo +5 -19
- package/std/libc/unistd.yo +5 -20
- package/std/libc/wctype.yo +6 -9
- package/std/libc/windows.yo +26 -30
- package/std/log.yo +41 -55
- package/std/net/addr.yo +102 -97
- package/std/net/dns.yo +27 -28
- package/std/net/errors.yo +50 -49
- package/std/net/tcp.yo +113 -124
- package/std/net/udp.yo +55 -66
- package/std/os/env.yo +35 -33
- package/std/os/signal.yo +15 -25
- package/std/path.yo +276 -311
- package/std/prelude.yo +6304 -4315
- package/std/process/command.yo +87 -103
- package/std/process/index.yo +12 -31
- package/std/regex/compiler.yo +196 -95
- package/std/regex/flags.yo +58 -39
- package/std/regex/index.yo +157 -173
- package/std/regex/match.yo +20 -31
- package/std/regex/node.yo +134 -152
- package/std/regex/parser.yo +283 -259
- package/std/regex/unicode.yo +172 -202
- package/std/regex/vm.yo +155 -171
- package/std/string/index.yo +5 -7
- package/std/string/rune.yo +45 -55
- package/std/string/string.yo +937 -964
- package/std/string/string_builder.yo +94 -104
- package/std/string/unicode.yo +46 -64
- package/std/sync/channel.yo +72 -73
- package/std/sync/cond.yo +31 -36
- package/std/sync/mutex.yo +30 -32
- package/std/sync/once.yo +13 -16
- package/std/sync/rwlock.yo +26 -31
- package/std/sync/waitgroup.yo +20 -25
- package/std/sys/advise.yo +16 -24
- package/std/sys/bufio/buf_reader.yo +77 -93
- package/std/sys/bufio/buf_writer.yo +52 -65
- package/std/sys/clock.yo +4 -9
- package/std/sys/constants.yo +77 -61
- package/std/sys/copy.yo +4 -10
- package/std/sys/dir.yo +26 -43
- package/std/sys/dns.yo +41 -61
- package/std/sys/errors.yo +95 -103
- package/std/sys/events.yo +45 -57
- package/std/sys/externs.yo +319 -267
- package/std/sys/fallocate.yo +7 -11
- package/std/sys/fcntl.yo +14 -22
- package/std/sys/file.yo +26 -40
- package/std/sys/future.yo +5 -8
- package/std/sys/iov.yo +12 -25
- package/std/sys/lock.yo +12 -13
- package/std/sys/mmap.yo +38 -43
- package/std/sys/path.yo +3 -8
- package/std/sys/perm.yo +7 -21
- package/std/sys/pipe.yo +5 -12
- package/std/sys/process.yo +23 -29
- package/std/sys/seek.yo +10 -12
- package/std/sys/signal.yo +7 -13
- package/std/sys/signals.yo +52 -35
- package/std/sys/socket.yo +63 -58
- package/std/sys/socketpair.yo +3 -6
- package/std/sys/sockinfo.yo +11 -20
- package/std/sys/statfs.yo +11 -34
- package/std/sys/statx.yo +25 -52
- package/std/sys/sysinfo.yo +15 -20
- package/std/sys/tcp.yo +62 -92
- package/std/sys/temp.yo +5 -9
- package/std/sys/time.yo +5 -15
- package/std/sys/timer.yo +6 -11
- package/std/sys/tty.yo +10 -18
- package/std/sys/udp.yo +22 -39
- package/std/sys/umask.yo +3 -6
- package/std/sys/unix.yo +33 -52
- package/std/testing/bench.yo +49 -52
- package/std/thread.yo +10 -15
- package/std/time/datetime.yo +105 -89
- package/std/time/duration.yo +43 -56
- package/std/time/instant.yo +13 -18
- package/std/time/sleep.yo +5 -9
- package/std/url/index.yo +184 -209
- package/std/worker.yo +6 -10
package/std/net/tcp.yo
CHANGED
|
@@ -19,33 +19,27 @@
|
|
|
19
19
|
// stream := io.await(listener.accept());
|
|
20
20
|
// // ...
|
|
21
21
|
// });
|
|
22
|
-
|
|
23
|
-
{ GlobalAllocator } :: import "../allocator";
|
|
22
|
+
{ GlobalAllocator } :: import("../allocator");
|
|
24
23
|
{ malloc, free } :: GlobalAllocator;
|
|
25
|
-
{ ArrayList } :: import
|
|
26
|
-
open
|
|
27
|
-
open
|
|
28
|
-
{ NetError } :: import
|
|
29
|
-
{ IOError } :: import
|
|
30
|
-
{ IpAddr, SocketAddr } :: import
|
|
31
|
-
{ Error, AnyError, Exception } :: import
|
|
32
|
-
IO_tcp :: import
|
|
33
|
-
{
|
|
34
|
-
AF_INET, AF_INET6, SOCK_STREAM,
|
|
35
|
-
SOL_SOCKET, SO_REUSEADDR,
|
|
36
|
-
IPPROTO_TCP, TCP_NODELAY, SO_KEEPALIVE
|
|
37
|
-
} :: import "../sys/socket";
|
|
38
|
-
|
|
24
|
+
{ ArrayList } :: import("../collections/array_list");
|
|
25
|
+
open(import("../string"));
|
|
26
|
+
open(import("../fmt"));
|
|
27
|
+
{ NetError } :: import("./errors");
|
|
28
|
+
{ IOError } :: import("../sys/errors");
|
|
29
|
+
{ IpAddr, SocketAddr } :: import("./addr");
|
|
30
|
+
{ Error, AnyError, Exception } :: import("../error");
|
|
31
|
+
IO_tcp :: import("../sys/tcp");
|
|
32
|
+
{ AF_INET, AF_INET6, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR, IPPROTO_TCP, TCP_NODELAY, SO_KEEPALIVE } :: import("../sys/socket");
|
|
39
33
|
// ============================================================================
|
|
40
34
|
// Internal helpers
|
|
41
35
|
// ============================================================================
|
|
42
|
-
|
|
43
36
|
// Convert a SocketAddr to a low-level SockAddr buffer.
|
|
44
|
-
_make_sockaddr :: (fn(addr: SocketAddr) -> IO_tcp.SockAddr)(
|
|
45
|
-
match(
|
|
37
|
+
_make_sockaddr :: (fn(addr : SocketAddr) -> IO_tcp.SockAddr)(
|
|
38
|
+
match(
|
|
39
|
+
addr.ip,
|
|
46
40
|
.V4(a, b, c, d) => {
|
|
47
41
|
// Build the IP string "a.b.c.d"
|
|
48
|
-
{ snprintf } :: import
|
|
42
|
+
{ snprintf } :: import("../libc/stdio");
|
|
49
43
|
buf := Array(u8, usize(16)).fill(u8(0));
|
|
50
44
|
snprintf(*(char)(&(buf(usize(0)))), usize(16), "%d.%d.%d.%d", i32(a), i32(b), i32(c), i32(d));
|
|
51
45
|
IO_tcp.make_sockaddr_in(&(buf(usize(0))), addr.port)
|
|
@@ -55,36 +49,31 @@ _make_sockaddr :: (fn(addr: SocketAddr) -> IO_tcp.SockAddr)(
|
|
|
55
49
|
IO_tcp.make_sockaddr_in6(*(u8)("::1"), addr.port)
|
|
56
50
|
)
|
|
57
51
|
);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
exn.throw(dyn NetError.from_io(IOError.from_errno(errno_val)))
|
|
52
|
+
_throw_io :: (fn(errno_val : i32, using(exn : Exception)) -> unit)(
|
|
53
|
+
exn.throw(dyn(NetError.from_io(IOError.from_errno(errno_val))))
|
|
61
54
|
);
|
|
62
|
-
|
|
63
55
|
// ============================================================================
|
|
64
56
|
// TcpStream (declared before TcpListener so accept can reference it)
|
|
65
57
|
// ============================================================================
|
|
66
|
-
|
|
67
58
|
/// A connected TCP stream for bidirectional data transfer.
|
|
68
59
|
TcpStream :: object(
|
|
69
|
-
_fd
|
|
60
|
+
_fd : i32,
|
|
70
61
|
_peer_addr : SocketAddr,
|
|
71
62
|
_is_closed : bool
|
|
72
63
|
);
|
|
73
|
-
|
|
74
64
|
// ============================================================================
|
|
75
65
|
// TcpListener
|
|
76
66
|
// ============================================================================
|
|
77
|
-
|
|
78
67
|
/// A TCP socket that listens for incoming connections.
|
|
79
68
|
TcpListener :: object(
|
|
80
|
-
_fd
|
|
69
|
+
_fd : i32,
|
|
81
70
|
_local_addr : SocketAddr,
|
|
82
|
-
_is_closed
|
|
71
|
+
_is_closed : bool
|
|
83
72
|
);
|
|
84
|
-
|
|
85
|
-
|
|
73
|
+
impl(
|
|
74
|
+
TcpListener,
|
|
86
75
|
/// Bind to a socket address and start listening.
|
|
87
|
-
bind : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(TcpListener, IO, Exception)))(
|
|
76
|
+
bind : (fn(addr : SocketAddr, using(io : IO)) -> Impl(Future(TcpListener, IO, Exception)))(
|
|
88
77
|
io.async((using(io : IO, exn : Exception)) => {
|
|
89
78
|
domain := cond(
|
|
90
79
|
addr.ip.is_v4() => AF_INET,
|
|
@@ -95,7 +84,7 @@ impl(TcpListener,
|
|
|
95
84
|
fd := NetError.check(raw_fd);
|
|
96
85
|
// Set SO_REUSEADDR
|
|
97
86
|
reuse_val := i32(1);
|
|
98
|
-
reuse_ptr := &reuse_val;
|
|
87
|
+
reuse_ptr := &(reuse_val);
|
|
99
88
|
io.await(IO_tcp.setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, *(u8)(reuse_ptr), u32(4)));
|
|
100
89
|
// Bind
|
|
101
90
|
saddr := _make_sockaddr(addr);
|
|
@@ -104,7 +93,7 @@ impl(TcpListener,
|
|
|
104
93
|
cond(
|
|
105
94
|
(bind_result < i32(0)) => {
|
|
106
95
|
io.await(IO_tcp.close(fd));
|
|
107
|
-
_throw_io(
|
|
96
|
+
_throw_io(i32(0) - bind_result);
|
|
108
97
|
},
|
|
109
98
|
true => ()
|
|
110
99
|
);
|
|
@@ -113,16 +102,15 @@ impl(TcpListener,
|
|
|
113
102
|
cond(
|
|
114
103
|
(listen_result < i32(0)) => {
|
|
115
104
|
io.await(IO_tcp.close(fd));
|
|
116
|
-
_throw_io(
|
|
105
|
+
_throw_io(i32(0) - listen_result);
|
|
117
106
|
},
|
|
118
107
|
true => ()
|
|
119
108
|
);
|
|
120
|
-
return
|
|
109
|
+
return(TcpListener(_fd : fd, _local_addr : addr, _is_closed : false));
|
|
121
110
|
})
|
|
122
111
|
),
|
|
123
|
-
|
|
124
112
|
/// Accept an incoming connection, returning a new `TcpStream`.
|
|
125
|
-
accept : (fn(self: Self, using(io : IO)) -> Impl(Future(TcpStream, IO, Exception)))({
|
|
113
|
+
accept : (fn(self : Self, using(io : IO)) -> Impl(Future(TcpStream, IO, Exception)))({
|
|
126
114
|
fd := self._fd;
|
|
127
115
|
io.async((using(io : IO, exn : Exception)) => {
|
|
128
116
|
// Allocate space for the peer address
|
|
@@ -134,7 +122,7 @@ impl(TcpListener,
|
|
|
134
122
|
(client_fd < i32(0)) => {
|
|
135
123
|
free(.Some(*(void)(addr_buf)));
|
|
136
124
|
free(.Some(*(void)(addr_len)));
|
|
137
|
-
_throw_io(
|
|
125
|
+
_throw_io(i32(0) - client_fd);
|
|
138
126
|
},
|
|
139
127
|
true => ()
|
|
140
128
|
);
|
|
@@ -143,21 +131,21 @@ impl(TcpListener,
|
|
|
143
131
|
free(.Some(*(void)(addr_buf)));
|
|
144
132
|
free(.Some(*(void)(addr_len)));
|
|
145
133
|
peer_addr := SocketAddr.new(IpAddr.any_v4(), peer_port);
|
|
146
|
-
return
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
134
|
+
return(
|
|
135
|
+
TcpStream(
|
|
136
|
+
_fd : client_fd,
|
|
137
|
+
_peer_addr : peer_addr,
|
|
138
|
+
_is_closed : false
|
|
139
|
+
)
|
|
150
140
|
);
|
|
151
141
|
})
|
|
152
142
|
}),
|
|
153
|
-
|
|
154
143
|
/// Get the local address this listener is bound to.
|
|
155
|
-
local_addr : (fn(self: Self) -> SocketAddr)(
|
|
144
|
+
local_addr : (fn(self : Self) -> SocketAddr)(
|
|
156
145
|
self._local_addr
|
|
157
146
|
),
|
|
158
|
-
|
|
159
147
|
/// Close the listener socket.
|
|
160
|
-
close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
148
|
+
close : (fn(self : Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
161
149
|
fd := self._fd;
|
|
162
150
|
io.async((using(io : IO, exn : Exception)) => {
|
|
163
151
|
cond(
|
|
@@ -166,42 +154,43 @@ impl(TcpListener,
|
|
|
166
154
|
r := io.await(IO_tcp.close(fd));
|
|
167
155
|
self._is_closed = true;
|
|
168
156
|
cond(
|
|
169
|
-
(r < i32(0)) => {
|
|
157
|
+
(r < i32(0)) => {
|
|
158
|
+
_throw_io(i32(0) - r);
|
|
159
|
+
},
|
|
170
160
|
true => ()
|
|
171
161
|
);
|
|
172
162
|
}
|
|
173
163
|
);
|
|
174
164
|
})
|
|
175
165
|
}),
|
|
176
|
-
|
|
177
166
|
/// Get the underlying file descriptor.
|
|
178
|
-
fd : (fn(self: Self) -> i32)(
|
|
167
|
+
fd : (fn(self : Self) -> i32)(
|
|
179
168
|
self._fd
|
|
180
169
|
)
|
|
181
170
|
);
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
171
|
+
impl(
|
|
172
|
+
TcpListener,
|
|
173
|
+
Dispose(
|
|
174
|
+
dispose : (fn(self : Self) -> unit)({
|
|
175
|
+
cond(
|
|
176
|
+
(!(self._is_closed)) => {
|
|
177
|
+
{ close_sync } :: import("../sys/file");
|
|
178
|
+
close_sync(self._fd);
|
|
179
|
+
self._is_closed = true;
|
|
180
|
+
},
|
|
181
|
+
true => ()
|
|
182
|
+
);
|
|
183
|
+
})
|
|
184
|
+
)
|
|
185
|
+
);
|
|
186
|
+
export(TcpListener);
|
|
198
187
|
// ============================================================================
|
|
199
188
|
// TcpStream impl
|
|
200
189
|
// ============================================================================
|
|
201
|
-
|
|
202
|
-
|
|
190
|
+
impl(
|
|
191
|
+
TcpStream,
|
|
203
192
|
/// Connect to a remote address, returning a new `TcpStream`.
|
|
204
|
-
connect : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(TcpStream, IO, Exception)))(
|
|
193
|
+
connect : (fn(addr : SocketAddr, using(io : IO)) -> Impl(Future(TcpStream, IO, Exception)))(
|
|
205
194
|
io.async((using(io : IO, exn : Exception)) => {
|
|
206
195
|
domain := cond(
|
|
207
196
|
addr.ip.is_v4() => AF_INET,
|
|
@@ -215,31 +204,31 @@ impl(TcpStream,
|
|
|
215
204
|
cond(
|
|
216
205
|
(conn_result < i32(0)) => {
|
|
217
206
|
io.await(IO_tcp.close(fd));
|
|
218
|
-
_throw_io(
|
|
207
|
+
_throw_io(i32(0) - conn_result);
|
|
219
208
|
},
|
|
220
209
|
true => ()
|
|
221
210
|
);
|
|
222
|
-
return
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
211
|
+
return(
|
|
212
|
+
TcpStream(
|
|
213
|
+
_fd : fd,
|
|
214
|
+
_peer_addr : addr,
|
|
215
|
+
_is_closed : false
|
|
216
|
+
)
|
|
226
217
|
);
|
|
227
218
|
})
|
|
228
219
|
),
|
|
229
|
-
|
|
230
220
|
/// Read bytes from the stream into `buf`.
|
|
231
221
|
/// Returns the number of bytes read, or 0 if the peer closed the connection.
|
|
232
|
-
read : (fn(self: Self, buf: *(u8), size: usize, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
222
|
+
read : (fn(self : Self, buf : *(u8), size : usize, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
233
223
|
fd := self._fd;
|
|
234
224
|
io.async((using(io : IO, exn : Exception)) => {
|
|
235
225
|
r := io.await(IO_tcp.recv(fd, buf, size, i32(0)));
|
|
236
226
|
NetError.check(r)
|
|
237
227
|
})
|
|
238
228
|
}),
|
|
239
|
-
|
|
240
229
|
/// Write a `str` to the stream.
|
|
241
230
|
/// Returns the number of bytes written.
|
|
242
|
-
write_str : (fn(self: Self, data: str, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
231
|
+
write_str : (fn(self : Self, data : str, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
243
232
|
fd := self._fd;
|
|
244
233
|
s := String.from(data);
|
|
245
234
|
s_bytes := s.as_bytes();
|
|
@@ -248,10 +237,9 @@ impl(TcpStream,
|
|
|
248
237
|
NetError.check(r)
|
|
249
238
|
})
|
|
250
239
|
}),
|
|
251
|
-
|
|
252
240
|
/// Write a `String` to the stream.
|
|
253
241
|
/// Returns the number of bytes written.
|
|
254
|
-
write_string : (fn(self: Self, data: String, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
242
|
+
write_string : (fn(self : Self, data : String, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
255
243
|
fd := self._fd;
|
|
256
244
|
data_bytes := data.as_bytes();
|
|
257
245
|
io.async((using(io : IO, exn : Exception)) => {
|
|
@@ -259,65 +247,63 @@ impl(TcpStream,
|
|
|
259
247
|
NetError.check(r)
|
|
260
248
|
})
|
|
261
249
|
}),
|
|
262
|
-
|
|
263
250
|
/// Write raw bytes from an `ArrayList(u8)` to the stream.
|
|
264
251
|
/// Returns the number of bytes written.
|
|
265
|
-
write_bytes : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
252
|
+
write_bytes : (fn(self : Self, data : ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
266
253
|
fd := self._fd;
|
|
267
254
|
io.async((using(io : IO, exn : Exception)) => {
|
|
268
255
|
r := io.await(IO_tcp.send(fd, data.ptr().unwrap(), data.len(), i32(0)));
|
|
269
256
|
NetError.check(r)
|
|
270
257
|
})
|
|
271
258
|
}),
|
|
272
|
-
|
|
273
259
|
/// Read all available data from the stream into a byte list.
|
|
274
|
-
read_bytes : (fn(self: Self, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))({
|
|
260
|
+
read_bytes : (fn(self : Self, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))({
|
|
275
261
|
fd := self._fd;
|
|
276
262
|
io.async((using(io : IO, exn : Exception)) => {
|
|
277
263
|
buf_size := usize(4096);
|
|
278
264
|
buf := *(u8)(malloc(buf_size).unwrap());
|
|
279
265
|
acc := ArrayList(u8).new();
|
|
280
266
|
done := false;
|
|
281
|
-
while
|
|
267
|
+
while(runtime(!(done)), {
|
|
282
268
|
n := io.await(IO_tcp.recv(fd, buf, buf_size, i32(0)));
|
|
283
269
|
cond(
|
|
284
270
|
(n < i32(0)) => {
|
|
285
271
|
free(.Some(*(void)(buf)));
|
|
286
272
|
done = true;
|
|
287
|
-
_throw_io(
|
|
273
|
+
_throw_io(i32(0) - n);
|
|
288
274
|
},
|
|
289
275
|
(n == i32(0)) => {
|
|
290
276
|
done = true;
|
|
291
277
|
},
|
|
292
278
|
true => {
|
|
293
279
|
i := usize(0);
|
|
294
|
-
while
|
|
280
|
+
while(runtime(i < usize(n)), {
|
|
295
281
|
acc.push((buf &+ i).*);
|
|
296
282
|
i = (i + usize(1));
|
|
297
|
-
};
|
|
283
|
+
});
|
|
298
284
|
}
|
|
299
285
|
);
|
|
300
|
-
};
|
|
286
|
+
});
|
|
301
287
|
free(.Some(*(void)(buf)));
|
|
302
|
-
return
|
|
288
|
+
return(acc);
|
|
303
289
|
})
|
|
304
290
|
}),
|
|
305
|
-
|
|
306
291
|
/// Shut down part or all of the connection.
|
|
307
292
|
/// `how`: 0 = read, 1 = write, 2 = both.
|
|
308
|
-
shutdown : (fn(self: Self, how: i32, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
293
|
+
shutdown : (fn(self : Self, how : i32, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
309
294
|
fd := self._fd;
|
|
310
295
|
io.async((using(io : IO, exn : Exception)) => {
|
|
311
296
|
r := io.await(IO_tcp.shutdown(fd, how));
|
|
312
297
|
cond(
|
|
313
|
-
(r < i32(0)) => {
|
|
298
|
+
(r < i32(0)) => {
|
|
299
|
+
_throw_io(i32(0) - r);
|
|
300
|
+
},
|
|
314
301
|
true => ()
|
|
315
302
|
);
|
|
316
303
|
})
|
|
317
304
|
}),
|
|
318
|
-
|
|
319
305
|
/// Close the stream.
|
|
320
|
-
close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
306
|
+
close : (fn(self : Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
321
307
|
fd := self._fd;
|
|
322
308
|
io.async((using(io : IO, exn : Exception)) => {
|
|
323
309
|
cond(
|
|
@@ -326,64 +312,67 @@ impl(TcpStream,
|
|
|
326
312
|
r := io.await(IO_tcp.close(fd));
|
|
327
313
|
self._is_closed = true;
|
|
328
314
|
cond(
|
|
329
|
-
(r < i32(0)) => {
|
|
315
|
+
(r < i32(0)) => {
|
|
316
|
+
_throw_io(i32(0) - r);
|
|
317
|
+
},
|
|
330
318
|
true => ()
|
|
331
319
|
);
|
|
332
320
|
}
|
|
333
321
|
);
|
|
334
322
|
})
|
|
335
323
|
}),
|
|
336
|
-
|
|
337
324
|
/// Get the remote peer's socket address.
|
|
338
|
-
peer_addr : (fn(self: Self) -> SocketAddr)(
|
|
325
|
+
peer_addr : (fn(self : Self) -> SocketAddr)(
|
|
339
326
|
self._peer_addr
|
|
340
327
|
),
|
|
341
|
-
|
|
342
328
|
/// Get the underlying file descriptor.
|
|
343
|
-
fd : (fn(self: Self) -> i32)(
|
|
329
|
+
fd : (fn(self : Self) -> i32)(
|
|
344
330
|
self._fd
|
|
345
331
|
),
|
|
346
|
-
|
|
347
332
|
/// Enable or disable TCP_NODELAY (disables Nagle's algorithm).
|
|
348
|
-
set_nodelay : (fn(self: Self, nodelay: bool, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
333
|
+
set_nodelay : (fn(self : Self, nodelay : bool, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
349
334
|
sock_fd := self._fd;
|
|
350
335
|
io.async((using(io : IO, exn : Exception)) => {
|
|
351
336
|
val := cond(nodelay => i32(1), true => i32(0));
|
|
352
|
-
val_ptr := &val;
|
|
337
|
+
val_ptr := &(val);
|
|
353
338
|
r := io.await(IO_tcp.setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, *(u8)(val_ptr), u32(4)));
|
|
354
339
|
cond(
|
|
355
|
-
(r < i32(0)) => {
|
|
340
|
+
(r < i32(0)) => {
|
|
341
|
+
_throw_io(i32(0) - r);
|
|
342
|
+
},
|
|
356
343
|
true => ()
|
|
357
344
|
);
|
|
358
345
|
})
|
|
359
346
|
}),
|
|
360
|
-
|
|
361
347
|
/// Enable or disable SO_KEEPALIVE on the socket.
|
|
362
|
-
set_keepalive : (fn(self: Self, enabled: bool, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
348
|
+
set_keepalive : (fn(self : Self, enabled : bool, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
363
349
|
sock_fd := self._fd;
|
|
364
350
|
io.async((using(io : IO, exn : Exception)) => {
|
|
365
351
|
val := cond(enabled => i32(1), true => i32(0));
|
|
366
|
-
val_ptr := &val;
|
|
352
|
+
val_ptr := &(val);
|
|
367
353
|
r := io.await(IO_tcp.setsockopt(sock_fd, SOL_SOCKET, SO_KEEPALIVE, *(u8)(val_ptr), u32(4)));
|
|
368
354
|
cond(
|
|
369
|
-
(r < i32(0)) => {
|
|
355
|
+
(r < i32(0)) => {
|
|
356
|
+
_throw_io(i32(0) - r);
|
|
357
|
+
},
|
|
370
358
|
true => ()
|
|
371
359
|
);
|
|
372
360
|
})
|
|
373
361
|
})
|
|
374
362
|
);
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
(
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
)
|
|
388
|
-
|
|
389
|
-
|
|
363
|
+
impl(
|
|
364
|
+
TcpStream,
|
|
365
|
+
Dispose(
|
|
366
|
+
dispose : (fn(self : Self) -> unit)({
|
|
367
|
+
cond(
|
|
368
|
+
(!(self._is_closed)) => {
|
|
369
|
+
{ close_sync } :: import("../sys/file");
|
|
370
|
+
close_sync(self._fd);
|
|
371
|
+
self._is_closed = true;
|
|
372
|
+
},
|
|
373
|
+
true => ()
|
|
374
|
+
);
|
|
375
|
+
})
|
|
376
|
+
)
|
|
377
|
+
);
|
|
378
|
+
export(TcpStream);
|
package/std/net/udp.yo
CHANGED
|
@@ -18,30 +18,25 @@
|
|
|
18
18
|
// sock := io.await(UdpSocket.bind(addr));
|
|
19
19
|
// io.await(sock.close());
|
|
20
20
|
// });
|
|
21
|
-
|
|
22
|
-
{ GlobalAllocator } :: import "../allocator";
|
|
21
|
+
{ GlobalAllocator } :: import("../allocator");
|
|
23
22
|
{ malloc, free } :: GlobalAllocator;
|
|
24
|
-
{ ArrayList } :: import
|
|
25
|
-
open
|
|
26
|
-
open
|
|
27
|
-
{ NetError } :: import
|
|
28
|
-
{ IOError } :: import
|
|
29
|
-
{ IpAddr, SocketAddr } :: import
|
|
30
|
-
{ Error, AnyError, Exception } :: import
|
|
31
|
-
IO_udp :: import
|
|
32
|
-
IO_tcp :: import
|
|
33
|
-
{
|
|
34
|
-
|
|
35
|
-
SOL_SOCKET, SO_BROADCAST
|
|
36
|
-
} :: import "../sys/socket";
|
|
37
|
-
{ snprintf } :: import "../libc/stdio";
|
|
38
|
-
|
|
23
|
+
{ ArrayList } :: import("../collections/array_list");
|
|
24
|
+
open(import("../string"));
|
|
25
|
+
open(import("../fmt"));
|
|
26
|
+
{ NetError } :: import("./errors");
|
|
27
|
+
{ IOError } :: import("../sys/errors");
|
|
28
|
+
{ IpAddr, SocketAddr } :: import("./addr");
|
|
29
|
+
{ Error, AnyError, Exception } :: import("../error");
|
|
30
|
+
IO_udp :: import("../sys/udp");
|
|
31
|
+
IO_tcp :: import("../sys/tcp");
|
|
32
|
+
{ AF_INET, AF_INET6, SOCK_DGRAM, SOL_SOCKET, SO_BROADCAST } :: import("../sys/socket");
|
|
33
|
+
{ snprintf } :: import("../libc/stdio");
|
|
39
34
|
// ============================================================================
|
|
40
35
|
// Internal helpers
|
|
41
36
|
// ============================================================================
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
_make_sockaddr :: (fn(addr : SocketAddr) -> IO_tcp.SockAddr)(
|
|
38
|
+
match(
|
|
39
|
+
addr.ip,
|
|
45
40
|
.V4(a, b, c, d) => {
|
|
46
41
|
buf := Array(u8, usize(16)).fill(u8(0));
|
|
47
42
|
snprintf(*(char)(&(buf(usize(0)))), usize(16), "%d.%d.%d.%d", i32(a), i32(b), i32(c), i32(d));
|
|
@@ -51,25 +46,22 @@ _make_sockaddr :: (fn(addr: SocketAddr) -> IO_tcp.SockAddr)(
|
|
|
51
46
|
IO_tcp.make_sockaddr_in6(*(u8)("::1"), addr.port)
|
|
52
47
|
)
|
|
53
48
|
);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
exn.throw(dyn NetError.from_io(IOError.from_errno(errno_val)))
|
|
49
|
+
_throw_net_io :: (fn(errno_val : i32, using(exn : Exception)) -> unit)(
|
|
50
|
+
exn.throw(dyn(NetError.from_io(IOError.from_errno(errno_val))))
|
|
57
51
|
);
|
|
58
|
-
|
|
59
52
|
// ============================================================================
|
|
60
53
|
// UdpSocket
|
|
61
54
|
// ============================================================================
|
|
62
|
-
|
|
63
55
|
/// A UDP socket for sending and receiving datagrams.
|
|
64
56
|
UdpSocket :: object(
|
|
65
|
-
_fd
|
|
57
|
+
_fd : i32,
|
|
66
58
|
_local_addr : SocketAddr,
|
|
67
|
-
_is_closed
|
|
59
|
+
_is_closed : bool
|
|
68
60
|
);
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
impl(
|
|
62
|
+
UdpSocket,
|
|
71
63
|
/// Create and bind a UDP socket to the given address.
|
|
72
|
-
bind : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(UdpSocket, IO, Exception)))(
|
|
64
|
+
bind : (fn(addr : SocketAddr, using(io : IO)) -> Impl(Future(UdpSocket, IO, Exception)))(
|
|
73
65
|
io.async((using(io : IO, exn : Exception)) => {
|
|
74
66
|
domain := cond(
|
|
75
67
|
addr.ip.is_v4() => AF_INET,
|
|
@@ -83,17 +75,16 @@ impl(UdpSocket,
|
|
|
83
75
|
cond(
|
|
84
76
|
(bind_r < i32(0)) => {
|
|
85
77
|
io.await(IO_udp.close(fd));
|
|
86
|
-
_throw_net_io(
|
|
78
|
+
_throw_net_io(i32(0) - bind_r);
|
|
87
79
|
},
|
|
88
80
|
true => ()
|
|
89
81
|
);
|
|
90
|
-
return
|
|
82
|
+
return(UdpSocket(_fd : fd, _local_addr : addr, _is_closed : false));
|
|
91
83
|
})
|
|
92
84
|
),
|
|
93
|
-
|
|
94
85
|
/// Send a datagram to a specific address.
|
|
95
86
|
/// Returns the number of bytes sent.
|
|
96
|
-
send_to : (fn(self: Self, data: ArrayList(u8), addr: SocketAddr, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
87
|
+
send_to : (fn(self : Self, data : ArrayList(u8), addr : SocketAddr, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
97
88
|
fd := self._fd;
|
|
98
89
|
io.async((using(io : IO, exn : Exception)) => {
|
|
99
90
|
saddr := _make_sockaddr(addr);
|
|
@@ -102,38 +93,34 @@ impl(UdpSocket,
|
|
|
102
93
|
NetError.check(r)
|
|
103
94
|
})
|
|
104
95
|
}),
|
|
105
|
-
|
|
106
96
|
/// Receive a datagram into the provided buffer.
|
|
107
97
|
/// Returns the number of bytes received.
|
|
108
|
-
recv : (fn(self: Self, buf: *(u8), size: usize, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
98
|
+
recv : (fn(self : Self, buf : *(u8), size : usize, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
109
99
|
fd := self._fd;
|
|
110
100
|
io.async((using(io : IO, exn : Exception)) => {
|
|
111
101
|
r := io.await(IO_udp.recv(fd, buf, size, i32(0)));
|
|
112
102
|
NetError.check(r)
|
|
113
103
|
})
|
|
114
104
|
}),
|
|
115
|
-
|
|
116
105
|
/// Receive a datagram and retrieve the sender's address.
|
|
117
106
|
/// Returns the number of bytes received.
|
|
118
|
-
recv_from : (fn(self: Self, buf: *(u8), size: usize, src_addr: *(u8), src_addr_len: *(u32), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
107
|
+
recv_from : (fn(self : Self, buf : *(u8), size : usize, src_addr : *(u8), src_addr_len : *(u32), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
119
108
|
fd := self._fd;
|
|
120
109
|
io.async((using(io : IO, exn : Exception)) => {
|
|
121
110
|
r := io.await(IO_udp.recvfrom(fd, buf, size, i32(0), src_addr, src_addr_len));
|
|
122
111
|
NetError.check(r)
|
|
123
112
|
})
|
|
124
113
|
}),
|
|
125
|
-
|
|
126
114
|
/// Send data on a connected socket (requires prior connect).
|
|
127
|
-
send : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
115
|
+
send : (fn(self : Self, data : ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
|
|
128
116
|
fd := self._fd;
|
|
129
117
|
io.async((using(io : IO, exn : Exception)) => {
|
|
130
118
|
r := io.await(IO_udp.send(fd, data.ptr().unwrap(), data.len(), i32(0)));
|
|
131
119
|
NetError.check(r)
|
|
132
120
|
})
|
|
133
121
|
}),
|
|
134
|
-
|
|
135
122
|
/// Close the socket.
|
|
136
|
-
close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
123
|
+
close : (fn(self : Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
137
124
|
fd := self._fd;
|
|
138
125
|
io.async((using(io : IO, exn : Exception)) => {
|
|
139
126
|
cond(
|
|
@@ -142,50 +129,52 @@ impl(UdpSocket,
|
|
|
142
129
|
r := io.await(IO_udp.close(fd));
|
|
143
130
|
self._is_closed = true;
|
|
144
131
|
cond(
|
|
145
|
-
(r < i32(0)) => {
|
|
132
|
+
(r < i32(0)) => {
|
|
133
|
+
_throw_net_io(i32(0) - r);
|
|
134
|
+
},
|
|
146
135
|
true => ()
|
|
147
136
|
);
|
|
148
137
|
}
|
|
149
138
|
);
|
|
150
139
|
})
|
|
151
140
|
}),
|
|
152
|
-
|
|
153
141
|
/// Enable or disable SO_BROADCAST on the socket.
|
|
154
|
-
set_broadcast : (fn(self: Self, enabled: bool, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
142
|
+
set_broadcast : (fn(self : Self, enabled : bool, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
|
|
155
143
|
fd := self._fd;
|
|
156
144
|
io.async((using(io : IO, exn : Exception)) => {
|
|
157
145
|
val := cond(enabled => i32(1), true => i32(0));
|
|
158
|
-
val_ptr := &val;
|
|
146
|
+
val_ptr := &(val);
|
|
159
147
|
r := io.await(IO_udp.setsockopt(fd, SOL_SOCKET, SO_BROADCAST, *(u8)(val_ptr), u32(4)));
|
|
160
148
|
cond(
|
|
161
|
-
(r < i32(0)) => {
|
|
149
|
+
(r < i32(0)) => {
|
|
150
|
+
_throw_net_io(i32(0) - r);
|
|
151
|
+
},
|
|
162
152
|
true => ()
|
|
163
153
|
);
|
|
164
154
|
})
|
|
165
155
|
}),
|
|
166
|
-
|
|
167
156
|
/// Get the local address this socket is bound to.
|
|
168
|
-
local_addr : (fn(self: Self) -> SocketAddr)(
|
|
157
|
+
local_addr : (fn(self : Self) -> SocketAddr)(
|
|
169
158
|
self._local_addr
|
|
170
159
|
),
|
|
171
|
-
|
|
172
160
|
/// Get the underlying file descriptor.
|
|
173
|
-
fd : (fn(self: Self) -> i32)(
|
|
161
|
+
fd : (fn(self : Self) -> i32)(
|
|
174
162
|
self._fd
|
|
175
163
|
)
|
|
176
164
|
);
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
)
|
|
190
|
-
|
|
191
|
-
|
|
165
|
+
impl(
|
|
166
|
+
UdpSocket,
|
|
167
|
+
Dispose(
|
|
168
|
+
dispose : (fn(self : Self) -> unit)({
|
|
169
|
+
cond(
|
|
170
|
+
(!(self._is_closed)) => {
|
|
171
|
+
{ close_sync } :: import("../sys/file");
|
|
172
|
+
close_sync(self._fd);
|
|
173
|
+
self._is_closed = true;
|
|
174
|
+
},
|
|
175
|
+
true => ()
|
|
176
|
+
);
|
|
177
|
+
})
|
|
178
|
+
)
|
|
179
|
+
);
|
|
180
|
+
export(UdpSocket);
|