spl/spl/stream.spl

109 lines
2.6 KiB
Text

"The SPL stream is an IO construct used to read and write to ";
"some external thing, for example a file or a TCP socket.";
"All functions here are encapsulations of their native counterparts.";
"Examples:";
"def tcp 'localhost' 8080 StreamType:tcp:create =tcp";
"def file 'test.txt' 1 StreamType:file:create =file 'hi':to-bytes file:write-exact; file:close null =file";
construct Stream {
id
;
construct { this | with type this ;
type new-stream this:=id
this
}
read-one { mega | with this ;
def buf 1 anew =buf
while { buf this:id read-stream pop not } { }
0 buf:get _mega
}
"the buffer is written to in-place.";
read { mega [int] | with buf this ;
buf gettype "mega" eq if { buf anew =buf }
buf this:id read-stream
}
"the buffer is written to in-place.";
read-exact { [int] | with buf this ;
buf gettype "mega" eq if { buf anew =buf }
buf this:id read-all-stream buf
}
read-to-end { [int] | with buf this ;
def full 0 anew =full
buf gettype "mega" eq if { buf anew =buf }
def read
while { buf this:id read-stream pop _mega dup =read } {
full (0 read buf:sub) aadd =full
} pop
full
}
write { mega | with buf this ;
buf this:id write-stream
}
write-exact { | with buf this ;
buf this:id write-all-stream
}
flush { | with this ;
this:id flush-stream
}
close { | with this ;
this:id close-stream
}
peer { StreamPeer | with this ;
this:id get-stream-peer StreamPeer:new
}
}
construct StreamPeer {
ip
port
;
construct { this | with ip port this ;
ip this:=ip
port this:=port
this
}
_str { str | with this ;
this:ip ":" concat this:port _str concat
}
}
construct StreamType {
id
;
construct { this | with id this ;
id this:=id
this
}
create { Stream | with this ;
this:id Stream:new
}
}
def stream-types 0 anew =stream-types
construct _StreamTypes {
;
construct { this | with this ;
{ | with type ;
"type StreamType:new this:=<type>";
(type StreamType:new) (this ("=" type concat)) dyn-objcall
} stream-types:foreach
this
}
}
func register-stream-type { | with id ;
stream-types [ id ] aadd =stream-types
id _StreamTypes dyn-def-field
}
"tcp" register-stream-type
"udp" register-stream-type
"file" register-stream-type
"cmd" register-stream-type
func StreamTypes { _StreamTypes |
_StreamTypes:new
}