@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
package/std/fs/metadata.yo
CHANGED
|
@@ -20,14 +20,14 @@
|
|
|
20
20
|
{ malloc, free } :: GlobalAllocator;
|
|
21
21
|
open import "../string";
|
|
22
22
|
{ Path } :: import "../path";
|
|
23
|
-
{ IOError } :: import "../
|
|
24
|
-
{ Statx } :: import "../
|
|
25
|
-
IO_file :: import "../
|
|
23
|
+
{ IOError } :: import "../sys/errors";
|
|
24
|
+
{ Statx } :: import "../sys/statx";
|
|
25
|
+
IO_file :: import "../sys/file";
|
|
26
26
|
{
|
|
27
27
|
AT_FDCWD, AT_SYMLINK_NOFOLLOW, AT_STATX_SYNC_AS_STAT,
|
|
28
28
|
STATX_BASIC_STATS, S_IFMT, S_IFREG, S_IFDIR, S_IFLNK,
|
|
29
29
|
S_IWUSR, S_IWGRP, S_IWOTH
|
|
30
|
-
} :: import "../
|
|
30
|
+
} :: import "../sys/constants";
|
|
31
31
|
|
|
32
32
|
// ============================================================================
|
|
33
33
|
// Metadata
|
package/std/fs/temp.yo
CHANGED
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
open import "../string";
|
|
23
23
|
open import "../fmt";
|
|
24
24
|
{ Path } :: import "../path";
|
|
25
|
-
{ IOError } :: import "../
|
|
25
|
+
{ IOError } :: import "../sys/errors";
|
|
26
26
|
_file_mod :: import "./file";
|
|
27
27
|
_dir_mod :: import "./dir";
|
|
28
|
-
IO_temp :: import "../
|
|
29
|
-
IO_file :: import "../
|
|
28
|
+
IO_temp :: import "../sys/temp";
|
|
29
|
+
IO_file :: import "../sys/file";
|
|
30
30
|
{ memcpy } :: import "../libc/string";
|
|
31
31
|
{ platform, Platform, env } :: import "../process";
|
|
32
32
|
|
package/std/fs/types.yo
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
{
|
|
6
6
|
O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC, O_APPEND,
|
|
7
7
|
O_EXCL, O_CLOEXEC, DEFAULT_FILE_MODE
|
|
8
|
-
} :: import "../
|
|
8
|
+
} :: import "../sys/constants";
|
|
9
9
|
|
|
10
10
|
// ============================================================================
|
|
11
11
|
// OpenMode — determines how a file is opened
|
package/std/fs/walker.yo
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
{ ArrayList } :: import "../collections/array_list";
|
|
24
24
|
open import "../string";
|
|
25
25
|
{ Path } :: import "../path";
|
|
26
|
-
{ IOError } :: import "../
|
|
26
|
+
{ IOError } :: import "../sys/errors";
|
|
27
27
|
{ FileType } :: import "./dir";
|
|
28
28
|
{ DirEntry } :: import "./dir";
|
|
29
29
|
_dir :: import "./dir";
|
package/std/net/addr.yo
CHANGED
|
@@ -144,7 +144,7 @@ impl(IpAddr, ToString(
|
|
|
144
144
|
return match(self.*,
|
|
145
145
|
.V4(a, b, c, d) => {
|
|
146
146
|
buf := Array(u8, usize(16)).fill(u8(0));
|
|
147
|
-
snprintf(&(buf(usize(0))), usize(16), "%d.%d.%d.%d", i32(a), i32(b), i32(c), i32(d));
|
|
147
|
+
snprintf(*(char)(&(buf(usize(0)))), usize(16), "%d.%d.%d.%d", i32(a), i32(b), i32(c), i32(d));
|
|
148
148
|
String.from_cstr(&(buf(usize(0)))).unwrap()
|
|
149
149
|
},
|
|
150
150
|
.V6(segs) => {
|
|
@@ -196,7 +196,7 @@ impl(SocketAddr, ToString(
|
|
|
196
196
|
to_string : (self -> {
|
|
197
197
|
ip_str := self.ip.to_string();
|
|
198
198
|
buf := Array(u8, usize(8)).fill(u8(0));
|
|
199
|
-
snprintf(&(buf(usize(0))), usize(8), "%d", i32(self.port));
|
|
199
|
+
snprintf(*(char)(&(buf(usize(0)))), usize(8), "%d", i32(self.port));
|
|
200
200
|
port_str := String.from_cstr(&(buf(usize(0)))).unwrap();
|
|
201
201
|
return match(self.ip,
|
|
202
202
|
.V4(_, _, _, _) => `${ip_str}:${port_str}`,
|
package/std/net/dns.yo
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// std/net/dns.yo - High-level DNS resolution
|
|
2
2
|
//
|
|
3
|
-
// Wraps std/
|
|
3
|
+
// Wraps std/sys/dns with typed DNS lookup functions.
|
|
4
4
|
//
|
|
5
5
|
// Example:
|
|
6
6
|
// { lookup_host } :: import "std/net/dns";
|
|
@@ -27,24 +27,25 @@ open import "../string";
|
|
|
27
27
|
open import "../fmt";
|
|
28
28
|
{ NetError } :: import "./errors";
|
|
29
29
|
{ IpAddr, SocketAddr } :: import "./addr";
|
|
30
|
-
IO_dns :: import "../
|
|
31
|
-
{ AF_INET, AF_INET6 } :: import "../
|
|
30
|
+
IO_dns :: import "../sys/dns";
|
|
31
|
+
{ AF_INET, AF_INET6 } :: import "../sys/socket";
|
|
32
32
|
|
|
33
33
|
// ============================================================================
|
|
34
34
|
// DNS lookup
|
|
35
35
|
// ============================================================================
|
|
36
36
|
|
|
37
37
|
// Resolve a hostname to a list of IP addresses.
|
|
38
|
-
lookup_host :: (fn(host: String, using(io : IO)) -> Impl(Future(Result(ArrayList(IpAddr), NetError))))(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
lookup_host :: (fn(host: String, using(io : IO)) -> Impl(Future(Result(ArrayList(IpAddr), NetError), IO)))(
|
|
39
|
+
io.async((using(io : IO)) => {
|
|
40
|
+
host_cstr_bytes := host.to_cstr();
|
|
41
|
+
host_cstr := host_cstr_bytes.ptr().unwrap();
|
|
42
42
|
result_ptr := IO_dns.alloc_result();
|
|
43
43
|
ret := io.await(IO_dns.getaddrinfo(host_cstr, .None, .None, result_ptr));
|
|
44
44
|
cond(
|
|
45
45
|
(ret != i32(0)) => {
|
|
46
46
|
IO_dns.free_result(result_ptr);
|
|
47
|
-
|
|
47
|
+
(err_ret : Result(ArrayList(IpAddr), NetError)) = .Err(.DNSFailed(host));
|
|
48
|
+
return err_ret;
|
|
48
49
|
},
|
|
49
50
|
true => ()
|
|
50
51
|
);
|
|
@@ -78,16 +79,16 @@ lookup_host :: (fn(host: String, using(io : IO)) -> Impl(Future(Result(ArrayList
|
|
|
78
79
|
.None => ()
|
|
79
80
|
);
|
|
80
81
|
IO_dns.free_result(result_ptr);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
(ok_ret : Result(ArrayList(IpAddr), NetError)) = .Ok(addrs);
|
|
83
|
+
return ok_ret;
|
|
84
|
+
})
|
|
85
|
+
);
|
|
85
86
|
|
|
86
87
|
// Resolve a hostname and port to a list of socket addresses.
|
|
87
|
-
resolve :: (fn(host: String, port: u16, using(io : IO)) -> Impl(Future(Result(ArrayList(SocketAddr), NetError))))(
|
|
88
|
-
|
|
88
|
+
resolve :: (fn(host: String, port: u16, using(io : IO)) -> Impl(Future(Result(ArrayList(SocketAddr), NetError), IO)))(
|
|
89
|
+
io.async((using(io : IO)) => {
|
|
89
90
|
addrs_result := io.await(lookup_host(host, using(io)));
|
|
90
|
-
match(addrs_result,
|
|
91
|
+
(ret : Result(ArrayList(SocketAddr), NetError)) = match(addrs_result,
|
|
91
92
|
.Ok(addrs) => {
|
|
92
93
|
result := ArrayList(SocketAddr).new();
|
|
93
94
|
i := usize(0);
|
|
@@ -96,12 +97,12 @@ resolve :: (fn(host: String, port: u16, using(io : IO)) -> Impl(Future(Result(Ar
|
|
|
96
97
|
result.push(SocketAddr.new(ip, port));
|
|
97
98
|
i = (i + usize(1));
|
|
98
99
|
};
|
|
99
|
-
|
|
100
|
+
.Ok(result)
|
|
100
101
|
},
|
|
101
102
|
.Err(e) => .Err(e)
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
);
|
|
104
|
+
return ret;
|
|
105
|
+
})
|
|
106
|
+
);
|
|
106
107
|
|
|
107
108
|
export lookup_host, resolve;
|
package/std/net/errors.yo
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// { NetError } :: import "std/net/errors";
|
|
7
7
|
|
|
8
8
|
open import "../string";
|
|
9
|
-
{ IOError } :: import "../
|
|
9
|
+
{ IOError } :: import "../sys/errors";
|
|
10
10
|
{ ToString } :: import "../fmt";
|
|
11
11
|
|
|
12
12
|
// ============================================================================
|
package/std/net/tcp.yo
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// std/net/tcp.yo - High-level TCP types
|
|
2
2
|
//
|
|
3
|
-
// Wraps std/
|
|
3
|
+
// Wraps std/sys/tcp with typed TcpListener and TcpStream objects.
|
|
4
4
|
//
|
|
5
5
|
// Example:
|
|
6
6
|
// { TcpListener, TcpStream } :: import "std/net/tcp";
|
|
@@ -24,13 +24,14 @@
|
|
|
24
24
|
open import "../string";
|
|
25
25
|
open import "../fmt";
|
|
26
26
|
{ NetError } :: import "./errors";
|
|
27
|
+
{ IOError } :: import "../sys/errors";
|
|
27
28
|
{ IpAddr, SocketAddr } :: import "./addr";
|
|
28
|
-
IO_tcp :: import "../
|
|
29
|
+
IO_tcp :: import "../sys/tcp";
|
|
29
30
|
{
|
|
30
31
|
AF_INET, AF_INET6, SOCK_STREAM,
|
|
31
32
|
SOL_SOCKET, SO_REUSEADDR,
|
|
32
33
|
IPPROTO_TCP, TCP_NODELAY, SO_KEEPALIVE
|
|
33
|
-
} :: import "../
|
|
34
|
+
} :: import "../sys/socket";
|
|
34
35
|
|
|
35
36
|
// ============================================================================
|
|
36
37
|
// Internal helpers
|
|
@@ -43,29 +44,39 @@ _make_sockaddr :: (fn(addr: SocketAddr) -> IO_tcp.SockAddr)(
|
|
|
43
44
|
// Build the IP string "a.b.c.d"
|
|
44
45
|
{ snprintf } :: import "../libc/stdio";
|
|
45
46
|
buf := Array(u8, usize(16)).fill(u8(0));
|
|
46
|
-
snprintf(&(buf(usize(0))), usize(16), "%d.%d.%d.%d", i32(a), i32(b), i32(c), i32(d));
|
|
47
|
+
snprintf(*(char)(&(buf(usize(0)))), usize(16), "%d.%d.%d.%d", i32(a), i32(b), i32(c), i32(d));
|
|
47
48
|
IO_tcp.make_sockaddr_in(&(buf(usize(0))), addr.port)
|
|
48
49
|
},
|
|
49
|
-
.V6(_) =>
|
|
50
|
+
.V6(_) =>
|
|
50
51
|
// For V6, create loopback for now
|
|
51
52
|
IO_tcp.make_sockaddr_in6(*(u8)("::1"), addr.port)
|
|
52
|
-
}
|
|
53
53
|
)
|
|
54
54
|
);
|
|
55
55
|
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// TcpStream (declared before TcpListener so accept can reference it)
|
|
58
|
+
// ============================================================================
|
|
59
|
+
|
|
60
|
+
TcpStream :: object(
|
|
61
|
+
_fd : i32,
|
|
62
|
+
_peer_addr : SocketAddr,
|
|
63
|
+
_is_closed : bool
|
|
64
|
+
);
|
|
65
|
+
|
|
56
66
|
// ============================================================================
|
|
57
67
|
// TcpListener
|
|
58
68
|
// ============================================================================
|
|
59
69
|
|
|
60
70
|
TcpListener :: object(
|
|
61
71
|
_fd : i32,
|
|
62
|
-
_local_addr : SocketAddr
|
|
72
|
+
_local_addr : SocketAddr,
|
|
73
|
+
_is_closed : bool
|
|
63
74
|
);
|
|
64
75
|
|
|
65
76
|
impl(TcpListener,
|
|
66
77
|
// Bind to a socket address and start listening.
|
|
67
|
-
bind : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(Result(TcpListener, NetError))))(
|
|
68
|
-
|
|
78
|
+
bind : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(Result(TcpListener, NetError), IO)))(
|
|
79
|
+
io.async((using(io : IO)) => {
|
|
69
80
|
domain := cond(
|
|
70
81
|
addr.ip.is_v4() => AF_INET,
|
|
71
82
|
true => AF_INET6
|
|
@@ -74,7 +85,8 @@ impl(TcpListener,
|
|
|
74
85
|
fd := io.await(IO_tcp.socket(domain, SOCK_STREAM, i32(0)));
|
|
75
86
|
cond(
|
|
76
87
|
(fd < i32(0)) => {
|
|
77
|
-
|
|
88
|
+
(ret : Result(TcpListener, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - fd))));
|
|
89
|
+
return ret;
|
|
78
90
|
},
|
|
79
91
|
true => ()
|
|
80
92
|
);
|
|
@@ -89,7 +101,8 @@ impl(TcpListener,
|
|
|
89
101
|
cond(
|
|
90
102
|
(bind_result < i32(0)) => {
|
|
91
103
|
io.await(IO_tcp.close(fd));
|
|
92
|
-
|
|
104
|
+
(ret : Result(TcpListener, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - bind_result))));
|
|
105
|
+
return ret;
|
|
93
106
|
},
|
|
94
107
|
true => ()
|
|
95
108
|
);
|
|
@@ -98,20 +111,21 @@ impl(TcpListener,
|
|
|
98
111
|
cond(
|
|
99
112
|
(listen_result < i32(0)) => {
|
|
100
113
|
io.await(IO_tcp.close(fd));
|
|
101
|
-
|
|
114
|
+
(ret : Result(TcpListener, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - listen_result))));
|
|
115
|
+
return ret;
|
|
102
116
|
},
|
|
103
117
|
true => ()
|
|
104
118
|
);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
119
|
+
(ret : Result(TcpListener, NetError)) = .Ok(TcpListener(_fd: fd, _local_addr: addr, _is_closed: false));
|
|
120
|
+
return ret;
|
|
121
|
+
})
|
|
122
|
+
),
|
|
109
123
|
|
|
110
124
|
// Accept an incoming connection.
|
|
111
125
|
// Returns a new TcpStream for the accepted connection.
|
|
112
|
-
accept : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(TcpStream, NetError))))({
|
|
126
|
+
accept : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(TcpStream, NetError), IO)))({
|
|
113
127
|
fd := self._fd;
|
|
114
|
-
|
|
128
|
+
io.async((using(io : IO)) => {
|
|
115
129
|
// Allocate space for the peer address
|
|
116
130
|
addr_buf := *(u8)(malloc(usize(128)).unwrap());
|
|
117
131
|
addr_len := *(u32)(malloc(usize(4)).unwrap());
|
|
@@ -121,7 +135,8 @@ impl(TcpListener,
|
|
|
121
135
|
(client_fd < i32(0)) => {
|
|
122
136
|
free(.Some(*(void)(addr_buf)));
|
|
123
137
|
free(.Some(*(void)(addr_len)));
|
|
124
|
-
|
|
138
|
+
(ret : Result(TcpStream, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - client_fd))));
|
|
139
|
+
return ret;
|
|
125
140
|
},
|
|
126
141
|
true => ()
|
|
127
142
|
);
|
|
@@ -130,13 +145,13 @@ impl(TcpListener,
|
|
|
130
145
|
free(.Some(*(void)(addr_buf)));
|
|
131
146
|
free(.Some(*(void)(addr_len)));
|
|
132
147
|
peer_addr := SocketAddr.new(IpAddr.any_v4(), peer_port);
|
|
133
|
-
|
|
148
|
+
(ret : Result(TcpStream, NetError)) = .Ok(TcpStream(
|
|
134
149
|
_fd: client_fd,
|
|
135
150
|
_peer_addr: peer_addr,
|
|
136
151
|
_is_closed: false
|
|
137
152
|
));
|
|
138
|
-
|
|
139
|
-
|
|
153
|
+
return ret;
|
|
154
|
+
})
|
|
140
155
|
}),
|
|
141
156
|
|
|
142
157
|
// Get the local address this listener is bound to.
|
|
@@ -145,16 +160,22 @@ impl(TcpListener,
|
|
|
145
160
|
),
|
|
146
161
|
|
|
147
162
|
// Close the listener.
|
|
148
|
-
close : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(unit, NetError))))({
|
|
163
|
+
close : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(unit, NetError), IO)))({
|
|
149
164
|
fd := self._fd;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
165
|
+
io.async((using(io : IO)) => {
|
|
166
|
+
(ret : Result(unit, NetError)) = cond(
|
|
167
|
+
self._is_closed => .Ok(()),
|
|
168
|
+
true => {
|
|
169
|
+
result := io.await(IO_tcp.close(fd));
|
|
170
|
+
self._is_closed = true;
|
|
171
|
+
cond(
|
|
172
|
+
(result < i32(0)) => .Err(NetError.from_io(IOError.from_errno((i32(0) - result)))),
|
|
173
|
+
true => .Ok(())
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
);
|
|
177
|
+
ret
|
|
178
|
+
})
|
|
158
179
|
}),
|
|
159
180
|
|
|
160
181
|
// Get the file descriptor.
|
|
@@ -165,27 +186,27 @@ impl(TcpListener,
|
|
|
165
186
|
|
|
166
187
|
impl(TcpListener, Dispose(
|
|
167
188
|
dispose : (fn(self: Self) -> unit)({
|
|
168
|
-
|
|
169
|
-
|
|
189
|
+
cond(
|
|
190
|
+
(!(self._is_closed)) => {
|
|
191
|
+
{ close_sync } :: import "../sys/file";
|
|
192
|
+
close_sync(self._fd);
|
|
193
|
+
self._is_closed = true;
|
|
194
|
+
},
|
|
195
|
+
true => ()
|
|
196
|
+
);
|
|
170
197
|
})
|
|
171
198
|
));
|
|
172
199
|
|
|
173
200
|
export TcpListener;
|
|
174
201
|
|
|
175
202
|
// ============================================================================
|
|
176
|
-
// TcpStream
|
|
203
|
+
// TcpStream impl
|
|
177
204
|
// ============================================================================
|
|
178
205
|
|
|
179
|
-
TcpStream :: object(
|
|
180
|
-
_fd : i32,
|
|
181
|
-
_peer_addr : SocketAddr,
|
|
182
|
-
_is_closed : bool
|
|
183
|
-
);
|
|
184
|
-
|
|
185
206
|
impl(TcpStream,
|
|
186
207
|
// Connect to a remote address.
|
|
187
|
-
connect : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(Result(TcpStream, NetError))))(
|
|
188
|
-
|
|
208
|
+
connect : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(Result(TcpStream, NetError), IO)))(
|
|
209
|
+
io.async((using(io : IO)) => {
|
|
189
210
|
domain := cond(
|
|
190
211
|
addr.ip.is_v4() => AF_INET,
|
|
191
212
|
true => AF_INET6
|
|
@@ -193,7 +214,8 @@ impl(TcpStream,
|
|
|
193
214
|
fd := io.await(IO_tcp.socket(domain, SOCK_STREAM, i32(0)));
|
|
194
215
|
cond(
|
|
195
216
|
(fd < i32(0)) => {
|
|
196
|
-
|
|
217
|
+
(ret : Result(TcpStream, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - fd))));
|
|
218
|
+
return ret;
|
|
197
219
|
},
|
|
198
220
|
true => ()
|
|
199
221
|
);
|
|
@@ -203,57 +225,67 @@ impl(TcpStream,
|
|
|
203
225
|
cond(
|
|
204
226
|
(conn_result < i32(0)) => {
|
|
205
227
|
io.await(IO_tcp.close(fd));
|
|
206
|
-
|
|
228
|
+
(ret : Result(TcpStream, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - conn_result))));
|
|
229
|
+
return ret;
|
|
207
230
|
},
|
|
208
231
|
true => ()
|
|
209
232
|
);
|
|
210
|
-
|
|
233
|
+
(ret : Result(TcpStream, NetError)) = .Ok(TcpStream(
|
|
211
234
|
_fd: fd,
|
|
212
235
|
_peer_addr: addr,
|
|
213
236
|
_is_closed: false
|
|
214
237
|
));
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
238
|
+
return ret;
|
|
239
|
+
})
|
|
240
|
+
),
|
|
218
241
|
|
|
219
242
|
// Read bytes from the stream.
|
|
220
243
|
// Returns the number of bytes read (0 means peer closed).
|
|
221
|
-
read : (fn(self: Self, buf: *(u8), size: usize, using(io : IO)) -> Impl(Future(Result(i32, NetError))))({
|
|
244
|
+
read : (fn(self: Self, buf: *(u8), size: usize, using(io : IO)) -> Impl(Future(Result(i32, NetError), IO)))({
|
|
222
245
|
fd := self._fd;
|
|
223
|
-
|
|
246
|
+
io.async((using(io : IO)) => {
|
|
224
247
|
result := io.await(IO_tcp.recv(fd, buf, size, i32(0)));
|
|
225
248
|
NetError.from_result(result)
|
|
226
|
-
})
|
|
227
|
-
|
|
249
|
+
})
|
|
250
|
+
}),
|
|
251
|
+
|
|
252
|
+
// Write a str to the stream.
|
|
253
|
+
// Returns the number of bytes written.
|
|
254
|
+
write_str : (fn(self: Self, data: str, using(io : IO)) -> Impl(Future(Result(i32, NetError), IO)))({
|
|
255
|
+
fd := self._fd;
|
|
256
|
+
s := String.from(data);
|
|
257
|
+
s_bytes := s.as_bytes();
|
|
258
|
+
io.async((using(io : IO)) => {
|
|
259
|
+
result := io.await(IO_tcp.send(fd, s_bytes.ptr().unwrap(), s_bytes.len(), i32(0)));
|
|
260
|
+
NetError.from_result(result)
|
|
261
|
+
})
|
|
228
262
|
}),
|
|
229
263
|
|
|
230
264
|
// Write a String to the stream.
|
|
231
265
|
// Returns the number of bytes written.
|
|
232
|
-
write : (fn(self: Self, data: String, using(io : IO)) -> Impl(Future(Result(i32, NetError))))({
|
|
266
|
+
write : (fn(self: Self, data: String, using(io : IO)) -> Impl(Future(Result(i32, NetError), IO)))({
|
|
233
267
|
fd := self._fd;
|
|
234
268
|
data_bytes := data.as_bytes();
|
|
235
|
-
|
|
269
|
+
io.async((using(io : IO)) => {
|
|
236
270
|
result := io.await(IO_tcp.send(fd, data_bytes.ptr().unwrap(), data_bytes.len(), i32(0)));
|
|
237
271
|
NetError.from_result(result)
|
|
238
|
-
})
|
|
239
|
-
return task;
|
|
272
|
+
})
|
|
240
273
|
}),
|
|
241
274
|
|
|
242
275
|
// Write bytes to the stream.
|
|
243
276
|
// Returns the number of bytes written.
|
|
244
|
-
write_bytes : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(Result(i32, NetError))))({
|
|
277
|
+
write_bytes : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(Result(i32, NetError), IO)))({
|
|
245
278
|
fd := self._fd;
|
|
246
|
-
|
|
279
|
+
io.async((using(io : IO)) => {
|
|
247
280
|
result := io.await(IO_tcp.send(fd, data.ptr().unwrap(), data.len(), i32(0)));
|
|
248
281
|
NetError.from_result(result)
|
|
249
|
-
})
|
|
250
|
-
return task;
|
|
282
|
+
})
|
|
251
283
|
}),
|
|
252
284
|
|
|
253
285
|
// Read all available data into a byte list.
|
|
254
|
-
read_all : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(ArrayList(u8), NetError))))({
|
|
286
|
+
read_all : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(ArrayList(u8), NetError), IO)))({
|
|
255
287
|
fd := self._fd;
|
|
256
|
-
|
|
288
|
+
io.async((using(io : IO)) => {
|
|
257
289
|
buf_size := usize(4096);
|
|
258
290
|
buf := *(u8)(malloc(buf_size).unwrap());
|
|
259
291
|
result := ArrayList(u8).new();
|
|
@@ -262,11 +294,13 @@ impl(TcpStream,
|
|
|
262
294
|
cond(
|
|
263
295
|
(n < i32(0)) => {
|
|
264
296
|
free(.Some(*(void)(buf)));
|
|
265
|
-
|
|
297
|
+
(ret : Result(ArrayList(u8), NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - n))));
|
|
298
|
+
return ret;
|
|
266
299
|
},
|
|
267
300
|
(n == i32(0)) => {
|
|
268
301
|
free(.Some(*(void)(buf)));
|
|
269
|
-
|
|
302
|
+
(ret : Result(ArrayList(u8), NetError)) = .Ok(result);
|
|
303
|
+
return ret;
|
|
270
304
|
},
|
|
271
305
|
true => {
|
|
272
306
|
i := usize(0);
|
|
@@ -278,42 +312,42 @@ impl(TcpStream,
|
|
|
278
312
|
);
|
|
279
313
|
};
|
|
280
314
|
free(.Some(*(void)(buf)));
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
315
|
+
(ret : Result(ArrayList(u8), NetError)) = .Ok(result);
|
|
316
|
+
return ret;
|
|
317
|
+
})
|
|
284
318
|
}),
|
|
285
319
|
|
|
286
320
|
// Shut down the connection.
|
|
287
321
|
// how: 0 = read, 1 = write, 2 = both
|
|
288
|
-
shutdown : (fn(self: Self, how: i32, using(io : IO)) -> Impl(Future(Result(unit, NetError))))({
|
|
322
|
+
shutdown : (fn(self: Self, how: i32, using(io : IO)) -> Impl(Future(Result(unit, NetError), IO)))({
|
|
289
323
|
fd := self._fd;
|
|
290
|
-
|
|
324
|
+
io.async((using(io : IO)) => {
|
|
291
325
|
result := io.await(IO_tcp.shutdown(fd, how));
|
|
292
|
-
cond(
|
|
293
|
-
(result < i32(0)) => .Err(NetError.
|
|
326
|
+
(ret : Result(unit, NetError)) = cond(
|
|
327
|
+
(result < i32(0)) => .Err(NetError.from_io(IOError.from_errno((i32(0) - result)))),
|
|
294
328
|
true => .Ok(())
|
|
295
|
-
)
|
|
296
|
-
|
|
297
|
-
|
|
329
|
+
);
|
|
330
|
+
ret
|
|
331
|
+
})
|
|
298
332
|
}),
|
|
299
333
|
|
|
300
334
|
// Close the stream.
|
|
301
|
-
close : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(unit, NetError))))({
|
|
335
|
+
close : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(unit, NetError), IO)))({
|
|
302
336
|
fd := self._fd;
|
|
303
|
-
|
|
304
|
-
cond(
|
|
337
|
+
io.async((using(io : IO)) => {
|
|
338
|
+
(ret : Result(unit, NetError)) = cond(
|
|
305
339
|
self._is_closed => .Ok(()),
|
|
306
340
|
true => {
|
|
307
341
|
result := io.await(IO_tcp.close(fd));
|
|
308
342
|
self._is_closed = true;
|
|
309
343
|
cond(
|
|
310
|
-
(result < i32(0)) => .Err(NetError.
|
|
344
|
+
(result < i32(0)) => .Err(NetError.from_io(IOError.from_errno((i32(0) - result)))),
|
|
311
345
|
true => .Ok(())
|
|
312
346
|
)
|
|
313
347
|
}
|
|
314
|
-
)
|
|
315
|
-
|
|
316
|
-
|
|
348
|
+
);
|
|
349
|
+
ret
|
|
350
|
+
})
|
|
317
351
|
}),
|
|
318
352
|
|
|
319
353
|
// Get the peer address.
|
|
@@ -327,33 +361,33 @@ impl(TcpStream,
|
|
|
327
361
|
),
|
|
328
362
|
|
|
329
363
|
// Enable/disable TCP_NODELAY (Nagle's algorithm).
|
|
330
|
-
set_nodelay : (fn(self: Self, nodelay: bool, using(io : IO)) -> Impl(Future(Result(unit, NetError))))({
|
|
331
|
-
|
|
332
|
-
|
|
364
|
+
set_nodelay : (fn(self: Self, nodelay: bool, using(io : IO)) -> Impl(Future(Result(unit, NetError), IO)))({
|
|
365
|
+
sock_fd := self._fd;
|
|
366
|
+
io.async((using(io : IO)) => {
|
|
333
367
|
val := cond(nodelay => i32(1), true => i32(0));
|
|
334
368
|
val_ptr := &val;
|
|
335
|
-
result := io.await(IO_tcp.setsockopt(
|
|
336
|
-
cond(
|
|
337
|
-
(result < i32(0)) => .Err(NetError.
|
|
369
|
+
result := io.await(IO_tcp.setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, *(u8)(val_ptr), u32(4)));
|
|
370
|
+
(ret : Result(unit, NetError)) = cond(
|
|
371
|
+
(result < i32(0)) => .Err(NetError.from_io(IOError.from_errno((i32(0) - result)))),
|
|
338
372
|
true => .Ok(())
|
|
339
|
-
)
|
|
340
|
-
|
|
341
|
-
|
|
373
|
+
);
|
|
374
|
+
ret
|
|
375
|
+
})
|
|
342
376
|
}),
|
|
343
377
|
|
|
344
378
|
// Enable/disable SO_KEEPALIVE.
|
|
345
|
-
set_keepalive : (fn(self: Self, enabled: bool, using(io : IO)) -> Impl(Future(Result(unit, NetError))))({
|
|
346
|
-
|
|
347
|
-
|
|
379
|
+
set_keepalive : (fn(self: Self, enabled: bool, using(io : IO)) -> Impl(Future(Result(unit, NetError), IO)))({
|
|
380
|
+
sock_fd := self._fd;
|
|
381
|
+
io.async((using(io : IO)) => {
|
|
348
382
|
val := cond(enabled => i32(1), true => i32(0));
|
|
349
383
|
val_ptr := &val;
|
|
350
|
-
result := io.await(IO_tcp.setsockopt(
|
|
351
|
-
cond(
|
|
352
|
-
(result < i32(0)) => .Err(NetError.
|
|
384
|
+
result := io.await(IO_tcp.setsockopt(sock_fd, SOL_SOCKET, SO_KEEPALIVE, *(u8)(val_ptr), u32(4)));
|
|
385
|
+
(ret : Result(unit, NetError)) = cond(
|
|
386
|
+
(result < i32(0)) => .Err(NetError.from_io(IOError.from_errno((i32(0) - result)))),
|
|
353
387
|
true => .Ok(())
|
|
354
|
-
)
|
|
355
|
-
|
|
356
|
-
|
|
388
|
+
);
|
|
389
|
+
ret
|
|
390
|
+
})
|
|
357
391
|
})
|
|
358
392
|
);
|
|
359
393
|
|
|
@@ -361,7 +395,7 @@ impl(TcpStream, Dispose(
|
|
|
361
395
|
dispose : (fn(self: Self) -> unit)({
|
|
362
396
|
cond(
|
|
363
397
|
(!(self._is_closed)) => {
|
|
364
|
-
{ close_sync } :: import "../
|
|
398
|
+
{ close_sync } :: import "../sys/file";
|
|
365
399
|
close_sync(self._fd);
|
|
366
400
|
self._is_closed = true;
|
|
367
401
|
},
|