Function read [src]

Reads the body of the message into buffer. Returns the number of bytes placed in the buffer. If skip is true, the buffer will be unused and the body will be skipped. See std.http.Client.Connection for an example of conn.

Prototype

pub fn read(r: *HeadersParser, conn: anytype, buffer: []u8, skip: bool) !usize

Parameters

r: *HeadersParserbuffer: []u8skip: bool

Source

pub fn read(r: *HeadersParser, conn: anytype, buffer: []u8, skip: bool) !usize { assert(r.state.isContent()); if (r.done) return 0; var out_index: usize = 0; while (true) { switch (r.state) { .invalid, .start, .seen_n, .seen_r, .seen_rn, .seen_rnr => unreachable, .finished => { const data_avail = r.next_chunk_length; if (skip) { conn.fill() catch |err| switch (err) { error.EndOfStream => { r.done = true; return 0; }, else => |e| return e, }; const nread = @min(conn.peek().len, data_avail); conn.drop(@intCast(nread)); r.next_chunk_length -= nread; if (r.next_chunk_length == 0 or nread == 0) r.done = true; return out_index; } else if (out_index < buffer.len) { const out_avail = buffer.len - out_index; const can_read = @as(usize, @intCast(@min(data_avail, out_avail))); const nread = try conn.read(buffer[0..can_read]); r.next_chunk_length -= nread; if (r.next_chunk_length == 0 or nread == 0) r.done = true; return nread; } else { return out_index; } }, .chunk_data_suffix, .chunk_data_suffix_r, .chunk_head_size, .chunk_head_ext, .chunk_head_r => { conn.fill() catch |err| switch (err) { error.EndOfStream => { r.done = true; return 0; }, else => |e| return e, }; const i = r.findChunkedLen(conn.peek()); conn.drop(@intCast(i)); switch (r.state) { .invalid => return error.HttpChunkInvalid, .chunk_data => if (r.next_chunk_length == 0) { if (std.mem.eql(u8, conn.peek(), "\r\n")) { r.state = .finished; conn.drop(2); } else { // The trailer section is formatted identically // to the header section. r.state = .seen_rn; } r.done = true; return out_index; }, else => return out_index, } continue; }, .chunk_data => { const data_avail = r.next_chunk_length; const out_avail = buffer.len - out_index; if (skip) { conn.fill() catch |err| switch (err) { error.EndOfStream => { r.done = true; return 0; }, else => |e| return e, }; const nread = @min(conn.peek().len, data_avail); conn.drop(@intCast(nread)); r.next_chunk_length -= nread; } else if (out_avail > 0) { const can_read: usize = @intCast(@min(data_avail, out_avail)); const nread = try conn.read(buffer[out_index..][0..can_read]); r.next_chunk_length -= nread; out_index += nread; } if (r.next_chunk_length == 0) { r.state = .chunk_data_suffix; continue; } return out_index; }, } } }