-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgopher.mt
More file actions
66 lines (57 loc) · 2.18 KB
/
Copy pathgopher.mt
File metadata and controls
66 lines (57 loc) · 2.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import "lib/codec/utf8" =~ [=> UTF8 :DeepFrozen]
import "lib/tubes" =~ [
=> nullPump :DeepFrozen,
=> makePumpTube :DeepFrozen,
=> chain :DeepFrozen,
]
import "lib/enum" =~ [=> makeEnum :DeepFrozen]
import "lib/record" =~ [=> makeRecord :DeepFrozen]
exports (main)
def [ItemType :DeepFrozen,
FILE :DeepFrozen,
] := makeEnum(["file"])
def [Item :DeepFrozen, makeItem :DeepFrozen
] := makeRecord("Item", [
"type" => ItemType,
"label" => Bytes,
"data" => Any,
"host" => Bytes,
"port" => Int,
])
def gopherLine(selector :Bytes, item :Item) :Bytes as DeepFrozen:
def label := item.getLabel()
def host := item.getHost()
def portBytes := b`${M.toString(item.getPort())}`
return b`0$label$\x09$selector$\x09$host$\x09$portBytes`
def gopherLines(lines :List[Bytes]) :Bytes as DeepFrozen:
return b`$\r$\n`.join(lines) + b`.$\r$\n`
def makeGopherPump(resource) as DeepFrozen:
var buf :Bytes := b``
return object gopherPump extends nullPump:
to received(data :Bytes):
buf += data
if (buf =~ b`@query$\r$\n`):
switch (query):
match b``:
def lines := [for selector => item in (resource)
gopherLine(selector, item)]
return [gopherLines(lines), null]
match selector ? (resource.contains(selector)):
def item := resource[selector]
def bs := UTF8.encode(item.getData(), null)
return [b`$bs$\r$\n.$\r$\n`, null]
match _:
return [b`3$\r$\n`, null]
return []
def tree := [
b`selector` => makeItem(FILE, b`Derp label`, `Test file!`, b`localhost`,
70),
b`another-selector` => makeItem(FILE, b`Herp label`, `Another test file!`,
b`localhost`, 70),
]
def listener(fount, drain) as DeepFrozen:
chain([fount, makePumpTube(makeGopherPump(tree)), drain])
def main(argv, => makeTCP4ServerEndpoint) :Int as DeepFrozen:
def endpoint := makeTCP4ServerEndpoint(70)
endpoint.listen(listener)
return 0