feed
Returns the number of bytes consumed by the chunk size. This is always
less than or equal to bytes.len.
After this function returns, chunk_len will contain the parsed chunk size
in bytes when state is data. Alternately, state may become invalid,
indicating a syntax error in the input stream.
If the amount returned is less than bytes.len, the parser is in the
chunk_data state and the first byte of the chunk is at bytes[result].
Asserts state is neither data nor invalid.
Function parameters
Parameters
- p:*ChunkParser
- bytes:[]const u8
Type definitions in this namespace
Types
Returns the number of bytes consumed by the chunk size.
Functions
- feed
- Returns the number of bytes consumed by the chunk size.
= .{ .state = .head_size, .chunk_len = 0, }
Values
- init
- = .{ .state = .head_size, .chunk_len = 0, }
Source
Implementation
pub fn feed(p: *ChunkParser, bytes: []const u8) usize {
for (bytes, 0..) |c, i| switch (p.state) {
.data_suffix => switch (c) {
'\r' => p.state = .data_suffix_r,
'\n' => p.state = .head_size,
else => {
p.state = .invalid;
return i;
},
},
.data_suffix_r => switch (c) {
'\n' => p.state = .head_size,
else => {
p.state = .invalid;
return i;
},
},
.head_size => {
const digit = switch (c) {
'0'...'9' => |b| b - '0',
'A'...'Z' => |b| b - 'A' + 10,
'a'...'z' => |b| b - 'a' + 10,
'\r' => {
p.state = .head_r;
continue;
},
'\n' => {
p.state = .data;
return i + 1;
},
else => {
p.state = .head_ext;
continue;
},
};
const new_len = p.chunk_len *% 16 +% digit;
if (new_len <= p.chunk_len and p.chunk_len != 0) {
p.state = .invalid;
return i;
}
p.chunk_len = new_len;
},
.head_ext => switch (c) {
'\r' => p.state = .head_r,
'\n' => {
p.state = .data;
return i + 1;
},
else => continue,
},
.head_r => switch (c) {
'\n' => {
p.state = .data;
return i + 1;
},
else => {
p.state = .invalid;
return i;
},
},
.data => unreachable,
.invalid => unreachable,
};
return bytes.len;
}