# Copyright 2007-2008 Kevin Reid, under the terms of the MIT X license # found at http://www.opensource.org/licenses/mit-license.html ................ ? pragma.syntax("0.9") Utilities for reading and writing binary representations on streams. Note that there is currently an 8-bits-per-byte assumption baked in, but this WILL CHANGE. Also, the chosen names for these binary types are not perfect, and suggestions for improving them are welcome. ? def := # value: ? def now := ; null ? def ::"eventual" := ; null ? def trickleIn := ; null ? def stdoutS := (List[0..255], E.call, def testW { > to write(chunk :List) { > chunk.printOn("", " ", "", stdout) > if (chunk.size().aboveZero()) { stdout.print(" ") } > } > to close() { stdout.print("") } > to flush() {} > to fail(p) { stdout.print(p) } > }); null UnsignedInteger: ? def unsignedIntegerCoding :DeepFrozen := # value: Reading, immediate ? def take := unsignedIntegerCoding[8].takingFrom([1, 250].asStream(), now) # value: ? take() # value: 1 ? take() # value: 250 ? def take := unsignedIntegerCoding[16].takingFrom([2, 5, 0, 10].asStream(), now) # value: ? take() # value: 517 ? take() # value: 10 Reading, eventual ? def take := unsignedIntegerCoding[16].takingFrom(trickleIn([2, 5, 0, 10].asStream()), now) # value: ? take() # problem: not synchronously callable: .iterate(<...taker$_$_>) ? def take := unsignedIntegerCoding[16].takingFrom(trickleIn([2, 5, 0, 10].asStream()), ::"eventual") # value: ? interp.waitAtTop(def r := take()); r # value: ? r # value: 517 ? interp.waitAtTop(def r := take()); r # value: ? r # value: 10 Writing, immediate ? def write := unsignedIntegerCoding[8].writingTo(stdoutS) # value: ? write(10) # stdout: 10 ? def write := unsignedIntegerCoding[16].writingTo(stdoutS) # value: ? write(10) # stdout: 0 10 ? write(517) # stdout: 2 5 SignedInteger: ? def signedIntegerCoding :DeepFrozen := # value: Reading, immediate ? def take := signedIntegerCoding[8].takingFrom([1, 250].asStream(), now) # value: ? take() # value: 1 ? take() # value: -6 ? def take := signedIntegerCoding[16].takingFrom([10, 5, 255, 10].asStream(), now) # value: ? take() # value: 2565 ? take() # value: -246 Reading, eventual ? def take := signedIntegerCoding[16].takingFrom(trickleIn([10, 5, 255, 10].asStream()), now) # value: ? take() # problem: not synchronously callable: .iterate(<...taker$_$_>) ? def take := signedIntegerCoding[16].takingFrom(trickleIn([10, 5, 255, 10].asStream()), ::"eventual") # value: ? interp.waitAtTop(def r := take()); r # value: ? r # value: 2565 ? interp.waitAtTop(def r := take()); r # value: ? r # value: -246 Writing, immediate ? def write := signedIntegerCoding[8].writingTo(stdoutS) # value: ? write(10) # stdout: 10 ? write(-10) # stdout: 246 ? def write := signedIntegerCoding[16].writingTo(stdoutS) # value: ? write(10) # stdout: 0 10 ? write(-246) # stdout: 255 10 XXX test consequences if bit size isn't a multiple of stream byte size WholeNum: ? def wholeNumCoding :DeepFrozen := # value: Reading, immediate ? def take := wholeNumCoding.takingFrom(def s := [0, 127, 130, 1, 99].asStream(), now) # value: ? take() # value: 0 ? take() # value: 127 ? take() # value: 257 ? s # value: [99].asStream() Reading, eventual ? def take := wholeNumCoding.takingFrom(trickleIn(def s := [0, 130, 1].asStream()), now) # value: ? take() # problem: doesn't coerce to a ConstList ? def take := wholeNumCoding.takingFrom(trickleIn(def s := [0, 130, 1].asStream()), ::"eventual") # value: ? interp.waitAtTop(def r := take()); r # value: ? r # value: 0 ? interp.waitAtTop(def r := take()); r # value: ? r # value: 257 Writing, immediate ? def write := wholeNumCoding.writingTo(stdoutS) # value: ? write(10) # stdout: 10 ? write(128) # stdout: 129 0 UTF8StringWithLength16: ? def utf8StringWithLength16Coding :DeepFrozen := # value: Reading, immediate ? def take := utf8StringWithLength16Coding.takingFrom(def s := [ > 0, 0, > 0, 2, 32, 33, > 0, 3, 226, 128, 162, > 226, 128, 162, > ].asStream(), now) # value: ? take() # value: "" ? take() # value: " !" ? take() # value: "•" ? s # value: [226, 128, 162].asStream() Reading, eventual ? def take := utf8StringWithLength16Coding.takingFrom(trickleIn(def s := [0, 0].asStream()), now) # value: ? take() # problem: not synchronously callable: .iterate(<...taker$_$_>) ? def take := utf8StringWithLength16Coding.takingFrom(trickleIn(def s := [ > 0, 0, > 0, 2, 32, 33, > 0, 3, 226, 128, 162, > 226, 128, 162, > ].asStream()), ::"eventual") # value: ? interp.waitAtTop(def r := take()); r # value: ? r # value: "" ? interp.waitAtTop(def r := take()); r # value: ? r # value: " !" ? interp.waitAtTop(def r := take()); r # value: ? r # value: "•" ? s # value: [226, 128, 162].asStream() Writing, immediate ? def write := utf8StringWithLength16Coding.writingTo(stdoutS) # value: ? write("") # stdout: 0 0 ? write("ab") # stdout: 0 2 97 98 ? write("\u2022") # stdout: 0 3 226 128 162 Float64: ? def float64Coding :DeepFrozen := # value: XXX not actually implemented yet Character32: ? def character32Coding :DeepFrozen := # value: XXX not actually implemented yet DataEBuild: ? def dataEBuildCoding :DeepFrozen := # value: Reading, immediate ? def take := dataEBuildCoding.takingFrom(def s := [2, 99, 1, 45].asStream(), now) # value: ? def rc := take() # value: <...taker$_> ? s # value: [45].asStream() ? rc((def deSubgraphKit := ).makeBuilder()) # value: 99 ? rc(deSubgraphKit.makeBuilder()) # value: 99 x XXX This is not yet implemented; we need to modify deBytecodeKit to support it. xReading, eventual x x ? def take := dataEBuildCoding.takingFrom(trickleIn([2, 99, 1, 45].asStream()), now) x # value: x x ? def rc := take() x # problem: not synchronously callable: .iterate(<...taker$_$_>) x x ? def take := dataEBuildCoding.takingFrom(trickleIn([2, 99, 1, 45].asStream()), ::"eventual") x # value: x x ? interp.waitAtTop(def rc := take()); rc x # value: x x # value: <...taker$_> x x ? rc(deSubgraphKit.makeBuilder()) x # value: 99 Writing, immediate ? def write := dataEBuildCoding.writingTo(stdoutS) # value: ? def b; write(def extentRC(bind b) { return b.buildRoot(b.buildLiteral(99)) }) # stdout: 2 99 1 (testing output and also the effects of calling the builder late) ? b.buildLiteral(98) # problem: builder for past its dynamic extent XXX support eventual writing XXX byte-width options XXX consequences of hitting EOF in the middle of a read XXX better printOns for writers and takers