nbio/sendfile

Code

main.odin ¶
66 linesSource

1/*
2Example that shows the `sendfile` operation.
3
4Dials a TCP server (localhost:1234) (use `nc -l 1234` to start a netcat server)
5and sends the contents of this file to it.
6
7Try it with a big file and you will see progress updates as the file is sent.
8*/
9package main
10
11import "core:fmt"
12import "core:nbio"
13import "core:os"
14import "core:terminal/ansi"
15
16main :: proc() {
17	if len(os.args) <= 1 {
18		fmt.eprintfln("usage: %s <path>", os.args[0])
19		return
20	}
21
22	err := nbio.acquire_thread_event_loop()
23	assert(err == nil)
24	defer nbio.release_thread_event_loop()
25
26	nbio.dial({nbio.IP4_Loopback, 1234}, on_dial)
27
28	err = nbio.run()
29	assert(err == nil)
30
31	on_dial :: proc(op: ^nbio.Operation) {
32		fmt.assertf(op.dial.err == nil, "dial: %v", op.dial.err)
33
34		file, err := nbio.open_sync(os.args[1])
35		assert(err == nil)
36
37		// Call can also take an offset, a length, a timeout.
38		// By default it sends the entire file, without a timeout.
39		sendfile_op := nbio.sendfile(op.dial.socket, file, on_sent, progress_updates=true)
40
41		fmt.print(ansi.CSI + ansi.DECTCEM_HIDE)
42		render_progress(sendfile_op, clear=false)
43	}
44
45	on_sent :: proc(op: ^nbio.Operation) {
46		fmt.assertf(op.sendfile.err == nil, "sendfile: %v", op.sendfile.err)
47
48		render_progress(op, clear=true)
49		if op.sendfile.sent < op.sendfile.nbytes {
50			// Progress update, not done.
51			return
52		}
53
54		fmt.print(ansi.CSI + ansi.DECTCEM_SHOW)
55		nbio.close(op.sendfile.file)
56	}
57}
58
59render_progress :: proc(op: ^nbio.Operation, clear: bool) {
60	if clear {
61		fmt.print(ansi.CSI + "1" + ansi.CUU)
62	}
63
64	fmt.print(ansi.CSI + "2" + ansi.EL + ansi.CSI + "0" + ansi.CHA)
65	fmt.printfln("%M/%M", op.sendfile.sent, op.sendfile.nbytes)
66}

Declarations Used 20