# Copyright 2005 Kevin Reid, under the terms of the MIT X license # found at http://www.opensource.org/licenses/mit-license.html ................ pragma.enable("easy-return") pragma.disable("explicit-result-guard") pragma.enable("dot-props") pragma.enable("verb-curry") pragma.enable("accumulator") def makeInStreamShell := def Range := EIO::Range def ALL := EIO::ALL def Element := int # XXX should be int8 (0..255) def makeFDInStreamAuthor { to run(lisp) { # XXX reduce the amount of lisp stuff this emaker uses def DeepFrozenStamp := lisp["E.ELIB", "+DEEP-FROZEN-STAMP+"]::value def read := lisp["CL", "READ-FROM-STRING"]::"function" def intern := lisp["CL", "INTERN"]::"function" { def asdfOperate := lisp["ASDF", "OPERATE"]::"function" def load_op := intern("LOAD-OP", "ASDF") # XXX :verbose nil for asdf loads asdfOperate(load_op, intern("E-ON-CL.SOCKETS", "KEYWORD")) } def l__quasiParser { to valueMaker(t) { return def vm { to substitute(values) { return read(simple__quasiParser.valueMaker(t).substitute(values)) } } } } def fooAddReceiveHandler := lisp["E.SOCKETS", "FOO-ADD-RECEIVE-HANDLER"]::"function" def fooRemoveReceiveHandler := lisp["E.SOCKETS", "FOO-REMOVE-RECEIVE-HANDLER"]::"function" /** Make an InStream that reads from a non-blocking-POSIX-read()-style data source. */ def makeFDInStream implements DeepFrozenStamp { /** 'nameObj' is used for printing the stream. */ to run(nameObj :any, fdRef, bufferLimit :(int >= 1)) { def inBuffer := [].diverge(Element) def inStream := makeInStreamShell(Element, def inBackend, def inImpl { to __printOn(out :TextWriter) { out.printSame(nameObj) } to semiObtain(count :Range, proceed, report) { def n := if (count == ALL) { inBuffer.size() } else { inBuffer.size().min(count) } return if (proceed == EIO::ADVANCE) { inBuffer.removeRun(0, n) } else if (report == EIO::ELEMENTS) { inBuffer.run(0, n) } } to terminate(t) { traceln(`XXX should be closing the fd $fdRef but that isn't implemented yet (makeFDInStreamAuthor)`) } }) var eof := false def inFDHandler def removeHandler() { fooRemoveReceiveHandler((lisp["ELIB", "REF-SHORTEN"]::"function")(inFDHandler)) } def vat := lisp["E.ELIB", "*VAT*"]::value bind inFDHandler := fooAddReceiveHandler(fdRef, def fdHandler() { escape error { escape eofExit { def elements := fdRef.read(bufferLimit - inBuffer.size(), error, eofExit) #traceln(`$inStream: read $elements from fd $fdRef`) inBuffer.append(elements) } catch _ { traceln(`$inStream: eof`) removeHandler() eof := true } } catch p { traceln(`$inStream: error $p`) removeHandler() inStream.fail(p) } inBackend.setAvailable(inBuffer.size()) }) return inStream } } return makeFDInStream } }