use io; use os; export type identity_reader = struct { vtable: io::stream, conn: io::handle, buffer: [os::BUFSIZ]u8, pending: size, length: size, }; const identity_reader_vtable = io::vtable { reader = &identity_read, ... }; // Creates a new reader that reads data until the response's Content-Length is // reached; i.e. the null Transport-Encoding. fn new_identity_reader( conn: io::handle, buffer: []u8, content_length: size, ) *io::stream = { let rd = alloc(identity_reader { vtable = &identity_reader_vtable, conn = conn, length = content_length, ... }); rd.buffer[..len(buffer)] = buffer[..]; rd.pending = len(buffer); return rd; }; fn identity_read( s: *io::stream, buf: []u8, ) (size | io::EOF | io::error) = { let rd = s: *identity_reader; assert(rd.vtable == &identity_reader_vtable); if (rd.length <= 0) { return io::EOF; }; if (rd.pending == 0) { let nread = rd.length; if (nread > len(rd.buffer)) { nread = len(rd.buffer); }; match (io::read(rd.conn, rd.buffer[..nread])?) { case let n: size => rd.pending = n; case io::EOF => return io::EOF; }; }; let n = len(buf); if (n > rd.pending) { n = rd.pending; }; buf[..n] = rd.buffer[..n]; rd.buffer[..len(rd.buffer) - n] = rd.buffer[n..]; rd.pending -= n; rd.length -= n; return n; };