Skip to content

Instantly share code, notes, and snippets.

@grahamc
Created June 29, 2020 14:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grahamc/9f8040886ac01edeb377be6d53d0d4a6 to your computer and use it in GitHub Desktop.
Save grahamc/9f8040886ac01edeb377be6d53d0d4a6 to your computer and use it in GitHub Desktop.
interface LineNotify
"""
Accept lines of bytes, where a line ends with a \n
Tail is only called if the sender closes with a non-line of bytes
""""
fun ref apply(line: Array[U8] iso) =>
None
fun ref tail(data: Array[U8] iso) =>
None
fun ref dispose() =>
None
class InputLines is InputNotify
"""
Accept bytes and emit bytes when they complete a line.
If the input is disposed of without a clean final newline,
the remaining data is sent as the tail.
"""
let _send: LineNotify
var _buffer: Array[U8] iso
new iso create(send: LineNotify iso) =>
_send = consume send
_buffer = []
fun ref apply(data: Array[U8] iso) =>
_buffer.append(consume data)
emit_lines()
fun ref dispose() =>
if _buffer.size() > 0 then
let tail = _buffer = []
_send.tail(consume tail)
end
_send.dispose()
fun ref emit_lines() =>
try
let splitpos: USize = _buffer.find('\n')?
(var line: Array[U8] iso, _buffer) = (consume _buffer).chop(splitpos + 1)
_send(consume line)
if _buffer.size() > 0 then
emit_lines()
end
end
class LinePrinter is LineNotify
"""
Receive lines of bytes and print them to stdout
"""
let _env: Env
new iso create(env: Env) =>
_env = env
fun ref apply(data: Array[U8] iso) =>
try
data.pop()?
end
_env.out.print("Got line: «" + String.from_iso_array(consume data) + "» (elided \\n)")
fun ref tail(data: Array[U8] iso) =>
_env.out.print("Final partial: «" + String.from_iso_array(consume data) + "»")
actor Main
new create(env: Env) =>
env.input(InputLines(LinePrinter(env)))
@SeanTAllen
Copy link

Small point. I would give LinePrinter an OutStream (env.out) rather than access to all of Env.

@SeanTAllen
Copy link

Given the small size of the example, LineNotify isn't needed. There's only one implementer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment