shithub: libdraw-zig

Download patch

ref: 21bd719e29393785e549018970ec95146ae8361b
parent: b50e95c93da28c22efdc5a159e63544daed4e3e3
author: Jacob G-W <jacoblevgw@gmail.com>
date: Sun Jul 16 19:27:43 EDT 2023

slightly update the protocol handling (ease of use)

--- a/src/libdraw.zig
+++ b/src/libdraw.zig
@@ -29,8 +29,7 @@
         var id: u32 = 0;
         var trys: usize = 0;
         while (trys < 25) : (trys += 1) {
-            var bs = try d.bufImage(1 + 4 + 4 + 4 + 1);
-            var a = bs.writer();
+            var a = try d.allocBuf(1 + 4 + 4 + 4 + 1);
             screenid += 1;
             id = screenid & 0xffff; // old devdraw bug
             a.writeByte('A') catch unreachable;
@@ -56,8 +55,7 @@
     pub fn lineop(dst: *Image, p0: Point, p1: Point, end0: u32, end1: u32, radius: u32, src: *Image, sp: Point, op: DrawOp) !void {
         const d = dst.display;
         try d.setDrawOp(op);
-        var bs = try d.bufImage(1 + 4 + 2 * 4 + 2 * 4 + 4 + 4 + 4 + 4 + 2 * 4);
-        var a = bs.writer();
+        var a = try d.allocBuf(1 + 4 + 2 * 4 + 2 * 4 + 4 + 4 + 4 + 4 + 2 * 4);
         a.writeByte('L') catch unreachable;
         a.writeIntLittle(u32, dst.id) catch unreachable;
         a.writeIntLittle(u32, p0.x) catch unreachable;
@@ -75,8 +73,7 @@
         const d = dst.display;
         try d.setDrawOp(op);
 
-        var bs = try d.bufImage(1 + 4 + 4 + 4 + 4 * 4 + 2 * 4 + 2 * 4);
-        var a = bs.writer();
+        var a = try d.allocBuf(1 + 4 + 4 + 4 + 4 * 4 + 2 * 4 + 2 * 4);
         const s = src orelse d.black;
         const m = mask orelse d.@"opaque";
         a.writeByte('d') catch unreachable;
@@ -233,6 +230,7 @@
     _isnewdisplay: bool,
     screen: ?*Image = null,
     _screen: ?*Screen = null,
+    abpos: usize = 0, // for use in the writer
     pub fn init(ally: std.mem.Allocator, options: struct { devdir: []const u8 = "/dev", windir: []const u8 = "/dev" }) !*Display {
         const NINFO = 12 * 12;
         var info: [NINFO + 1]u8 = undefined;
@@ -352,8 +350,7 @@
         if (depth == 0) {
             return error.BadChanDesc;
         }
-        var bs = try self.bufImage(1 + 4 + 4 + 1 + 4 + 1 + 4 * 4 + 4 * 4 + 4);
-        var a = bs.writer();
+        var a = try self.allocBuf(1 + 4 + 4 + 1 + 4 + 1 + 4 * 4 + 4 * 4 + 4);
         self.imageid += 1;
         const id = self.imageid;
         // start writing the protocol
@@ -395,8 +392,7 @@
             return error.ImageNameTooLong;
         }
         self.flushImage(false) catch {};
-        var bs = try self.bufImage(1 + 4 + 1 + name.len);
-        var a = bs.writer();
+        var a = try self.allocBuf(1 + 4 + 1 + name.len);
         self.imageid += 1;
         const id = self.imageid;
         a.writeByte('n') catch unreachable;
@@ -455,8 +451,7 @@
         return im;
     }
     fn freeRemote(self: *Display, id: u32, t: enum { image, screen }) !void {
-        var bs = try self.bufImage(1 + 4);
-        const a = bs.writer();
+        var a = try self.allocBuf(1 + 4);
         const c: u8 = if (t == .image) 'f' else 'F';
         a.writeByte(c) catch unreachable;
         a.writeIntLittle(u32, id) catch unreachable;
@@ -479,7 +474,30 @@
         }
         try d.freeRemote(image.id, .image);
     }
-    pub fn bufImage(self: *Display, n: usize) !std.io.FixedBufferStream([]u8) {
+    const AllocedBuf = struct {
+        buffer: []u8,
+        pos: *usize,
+        fn writer(self: AllocedBuf) std.io.Writer(AllocedBuf, error{}, write) {
+            return .{ .context = self };
+        }
+        fn write(self: AllocedBuf, bytes: []const u8) error{}!usize {
+            if (bytes.len == 0) return 0;
+            if (self.pos.* >= self.buffer.len) unreachable; // we don't allocate more than we use
+
+            const n = if (self.pos.* + bytes.len <= self.buffer.len)
+                bytes.len
+            else
+                self.buffer.len - self.pos.*;
+
+            @memcpy(self.buffer[self.pos.*..][0..n], bytes[0..n]);
+            self.pos.* += n;
+
+            if (n == 0) unreachable;
+
+            return n;
+        }
+    };
+    pub fn allocBuf(self: *Display, n: usize) !std.io.Writer(AllocedBuf, error{}, AllocedBuf.write) {
         if (n > self.bufsize) {
             return error.BadCountBufSize;
         }
@@ -488,7 +506,9 @@
         }
         const p = self.bufp;
         self.bufp += n;
-        return std.io.fixedBufferStream(p[0..n]);
+        self.abpos = 0;
+        var ab = AllocedBuf{ .buffer = p[0..n], .pos = &self.abpos };
+        return ab.writer();
     }
     pub fn flush(self: *Display) !void {
         const n: i64 = @intCast(@intFromPtr(self.bufp) - @intFromPtr(self.buf.ptr));
@@ -582,8 +602,7 @@
     }
     pub fn setDrawOp(self: *Display, op: DrawOp) !void {
         if (op != .soverD) {
-            var bs = try self.bufImage(1 + 1);
-            var a = bs.writer();
+            var a = try self.allocBuf(1 + 1);
             a.writeByte('O') catch unreachable;
             a.writeByte(@intFromEnum(op)) catch unreachable;
         }