zoap

A WiP CoAP implementation for bare-metal constrained devices in Zig

git clone https://git.8pit.net/zoap.git

 1const mem = @import("std").mem;
 2
 3/// WriteBuffer adds support allows writing bytes to an underlying buffer
 4/// with safety-checked undefined behaviour. That is, the caller should
 5/// check in advance whether sufficient space is available via
 6/// WriteBuffer.capacity().
 7pub const WriteBuffer = struct {
 8    slice: []u8,
 9    pos: usize = 0,
10
11    pub fn serialized(self: *WriteBuffer) []u8 {
12        return self.slice[0..self.pos];
13    }
14
15    pub fn capacity(self: *WriteBuffer) usize {
16        return self.slice.len - self.pos;
17    }
18
19    pub fn bytes(self: *WriteBuffer, buf: []const u8) void {
20        // mem.copy does provide us with safety-checked
21        // undefined behaviour. Thus we don't need to check
22        // the capacity explicitly here.
23        mem.copy(u8, self.slice[self.pos..], buf);
24        self.pos += buf.len;
25    }
26
27    fn write(self: *WriteBuffer, ptr: anytype) void {
28        self.bytes(mem.asBytes(ptr));
29    }
30
31    pub fn byte(self: *WriteBuffer, b: u8) void {
32        self.write(&b);
33    }
34
35    pub fn half(self: *WriteBuffer, h: u16) void {
36        self.write(&h);
37    }
38
39    pub fn word(self: *WriteBuffer, w: u32) void {
40        self.write(&w);
41    }
42};
43
44pub const ReadBuffer = struct {
45    slice: []const u8,
46
47    pub fn length(self: *ReadBuffer) usize {
48        return self.slice.len;
49    }
50
51    pub fn remaining(self: *ReadBuffer) []const u8 {
52        return self.slice;
53    }
54
55    pub fn bytes(self: *ReadBuffer, numBytes: usize) !([]const u8) {
56        if (self.slice.len < numBytes)
57            return error.OutOfBounds;
58
59        const result = self.slice[0..numBytes];
60        self.slice = self.slice[numBytes..];
61        return result;
62    }
63
64    fn read(self: *ReadBuffer, comptime T: type, dest: anytype) !void {
65        const slice = try self.bytes(@sizeOf(T));
66        dest.* = @bitCast(T, slice[0..@sizeOf(T)].*);
67    }
68
69    pub fn byte(self: *ReadBuffer) !u8 {
70        var r: u8 = undefined;
71        try self.read(u8, &r);
72        return r;
73    }
74
75    pub fn half(self: *ReadBuffer) !u16 {
76        var r: u16 = undefined;
77        try self.read(u16, &r);
78        return r;
79    }
80
81    pub fn word(self: *ReadBuffer) !u32 {
82        var r: u32 = undefined;
83        try self.read(u32, &r);
84        return r;
85    }
86};