{ : new_writer : new_writer2 : write_all : write_byte : write : flush : with_writer } Where Define (with_writer fd size func) Let w (new_writer2 fd size) In Begin { (func w) (IO.flush w) } Where Define (new_writer2 fd size) Define (write w bytes start size) (write w.state bytes start size) Define (write_all w bytes) (write_all w.state bytes) Define (write_byte w byte) (write_byte w.state byte) Define (flush w) (flush w.state) In { : interface {: write : write_all : write_byte : flush} : state (new_writer fd size) } Where Define (write_all w bytes) (write w bytes 0 (CHUNK.size bytes)) Where Define (write_byte w byte) Begin { When [(fetch_top w) = (size w)] { (flush w) } Begin { Let top (fetch_top w) (CHUNK.store_byte w [8 + top] byte) (store_top w [top + 1]) } } Define (write w bytes start count) Let fd (fetch_fd w) Let size (size w) In Iterate {start count} Let top (fetch_top w) In Let room [size - top] In Begin Cond { | [count > room] (Return Begin Cond { | [top = 0] Let r (OS.write fd bytes start count) When [r <= 0] { (OS.die "Failed to write bytes.") } (Continue [start + r] [count - r]) | True (CHUNK.store_bytes w [8 + top] bytes start room) (store_top w size) (flush w) (Continue [start + room] [count - room]) }) | True (CHUNK.store_bytes w [8 + top] bytes start count) (store_top w [top + count]) } Where Define (new_writer fd size) Begin { Let w (alloc size) (init w fd) (Return w) } Define (flush w) Let fd (fetch_fd w) Let top (fetch_top w) In When [top > 0] { Let r (OS.write fd w 8 top) When [r != top] { (OS.die "Failed to flush buffer.") } (store_top w 0) } Where Define (alloc size) (CHUNK.new [8 + size]) Define (init w fd) Begin { (store_fd w fd) } Where Define (store_fd w fd) (CHUNK.store_uint32 w 0 fd) Define (fetch_fd w) (CHUNK.fetch_uint32 w 0) Define (store_top w top) (CHUNK.store_uint32 w 4 top) Define (fetch_top w) (CHUNK.fetch_uint32 w 4) Define (size w) [(CHUNK.size w) - 8] Where Let CHUNK Package "chunk" Let IO Package "io" Let OS Package "os" Let STDIO Package "stdio"