Function readSmallMessage [src]
Reads the next message from the WebSocket stream, failing if the
message does not fit into the input buffer. The returned memory points
into the input buffer and is invalidated on the next read.
Prototype
pub fn readSmallMessage(ws: *WebSocket) ReadSmallTextMessageError!SmallMessage Parameters
ws: *WebSocket Possible Errors
Source
pub fn readSmallMessage(ws: *WebSocket) ReadSmallTextMessageError!SmallMessage {
const in = ws.input;
while (true) {
const header = try in.takeArray(2);
const h0: Header0 = @bitCast(header[0]);
const h1: Header1 = @bitCast(header[1]);
switch (h0.opcode) {
.text, .binary, .pong, .ping => {},
.connection_close => return error.ConnectionClose,
.continuation => return error.UnexpectedOpCode,
_ => return error.UnexpectedOpCode,
}
if (!h0.fin) return error.MessageTooBig;
if (!h1.mask) return error.MissingMaskBit;
const len: usize = switch (h1.payload_len) {
.len16 => try in.takeInt(u16, .big),
.len64 => std.math.cast(usize, try in.takeInt(u64, .big)) orelse return error.MessageTooBig,
else => @intFromEnum(h1.payload_len),
};
if (len > in.buffer.len) return error.MessageTooBig;
const mask: u32 = @bitCast((try in.takeArray(4)).*);
const payload = try in.take(len);
// Skip pongs.
if (h0.opcode == .pong) continue;
// The last item may contain a partial word of unused data.
const floored_len = (payload.len / 4) * 4;
const u32_payload: []align(1) u32 = @ptrCast(payload[0..floored_len]);
for (u32_payload) |*elem| elem.* ^= mask;
const mask_bytes: []const u8 = @ptrCast(&mask);
for (payload[floored_len..], mask_bytes[0 .. payload.len - floored_len]) |*leftover, m|
leftover.* ^= m;
return .{
.opcode = h0.opcode,
.data = payload,
};
}
}