WIP refactor: add remote_poc_test
This commit is contained in:
parent
ddc06d67d6
commit
47f4202b94
6 changed files with 212 additions and 0 deletions
36
src/remote/framing.zig
Normal file
36
src/remote/framing.zig
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub const max_frame_size = 8 * 4096; // matches thespian.max_message_size
|
||||
|
||||
/// Write a length-prefixed frame. writer must support writeAll.
|
||||
pub fn write_frame(writer: anytype, payload: []const u8) !void {
|
||||
var len_buf: [4]u8 = undefined;
|
||||
std.mem.writeInt(u32, &len_buf, @intCast(payload.len), .big);
|
||||
try writer.writeAll(&len_buf);
|
||||
try writer.writeAll(payload);
|
||||
}
|
||||
|
||||
/// Accumulates bytes until a complete length-prefixed frame is available.
|
||||
/// Returns a slice into the internal buffer on completion; null if more bytes
|
||||
/// are needed. The returned slice is only valid until the next call to feed().
|
||||
pub const Accumulator = struct {
|
||||
buf: [max_frame_size + 4]u8 = undefined,
|
||||
pos: usize = 0,
|
||||
|
||||
pub fn feed(self: *Accumulator, bytes: []const u8) ?[]const u8 {
|
||||
const to_copy = @min(bytes.len, self.buf.len - self.pos);
|
||||
@memcpy(self.buf[self.pos..][0..to_copy], bytes[0..to_copy]);
|
||||
self.pos += to_copy;
|
||||
|
||||
if (self.pos < 4) return null;
|
||||
|
||||
const payload_len = std.mem.readInt(u32, self.buf[0..4], .big);
|
||||
if (payload_len > max_frame_size) return null;
|
||||
|
||||
const total = 4 + payload_len;
|
||||
if (self.pos < total) return null;
|
||||
|
||||
self.pos = 0;
|
||||
return self.buf[4..total];
|
||||
}
|
||||
};
|
||||
24
src/remote/protocol.zig
Normal file
24
src/remote/protocol.zig
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
const cbor = @import("cbor");
|
||||
|
||||
pub const WireMessage = union(enum) {
|
||||
send_named: SendNamed,
|
||||
|
||||
pub const SendNamed = struct {
|
||||
from_id: u64,
|
||||
to_name: []const u8,
|
||||
payload: []const u8, // raw CBOR bytes
|
||||
};
|
||||
};
|
||||
|
||||
/// Decode a raw CBOR frame into a WireMessage.
|
||||
/// Returned slices point into the frame buffer and are only valid while it lives.
|
||||
pub fn decode(frame: []const u8) !WireMessage {
|
||||
var from_id: u64 = 0;
|
||||
var to_name: []const u8 = "";
|
||||
var payload: []const u8 = "";
|
||||
|
||||
if (try cbor.match(frame, .{ "send_named", cbor.extract(&from_id), cbor.extract(&to_name), cbor.extract_cbor(&payload) }))
|
||||
return .{ .send_named = .{ .from_id = from_id, .to_name = to_name, .payload = payload } };
|
||||
|
||||
return error.UnknownMessageType;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue