use io; use fmt; type packet = []u8; def PCKSZ: size = 4; type packet_reader = struct { buf: [256]u8, good: []u8, }; fn packet_reader_new() packet_reader = { let pr = packet_reader { buf = [0...], ... }; pr.good = pr.buf[0..0]; return pr; }; // call when input is ready. could block otherwise fn packet_reader_read(pr: *packet_reader, sock: io::handle) (void | io::error | io::EOF) = { const remaining_amt = len(pr.good); const read_pos = if (remaining_amt > 0) { // still some unconsumed content in the buffer // move unconsumed stuff to start of buffer fmt::printfln("moving {} remaining bytes",remaining_amt)!; pr.buf[0..remaining_amt] = pr.good; yield remaining_amt; } else 0z; const nread = match(io::read(sock, pr.buf[read_pos..])?) { case io::EOF => return io::EOF; case let n: size => yield n; }; fmt::printfln("read {} bytes",nread)!; const total_amt = read_pos + nread; pr.good = pr.buf[0..total_amt]; fmt::printfln("now {} bytes in buffer",total_amt)!; }; fn packet_reader_next(pr: *packet_reader) (packet | done) = { // either parse a full packet out of the front of good, // move good along that many bytes, // and return the packet, // or, ascertain there is no full packet, and return done if (len(pr.good) < PCKSZ) return done; const packet_bytes = pr.good[..PCKSZ]; pr.good = pr.good[PCKSZ..]; return packet_bytes; };