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

ConnectionClose
EndOfStream
MessageTooBig
MissingMaskBit
ReadFailed
UnexpectedOpCode

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, }; } }