ref: d180b70c6c69ffe8168cc8571772ad6e15ac6aba
dir: /pack.myr/
use std use sys use "types" pkg draw = const pack : (dpy : display#, fmt : byte[:], vsz : std.size, args : ... -> void) const flush : (dpy : display# -> bool) const flushbuf : (dpy : display# -> bool) ;; const pack = {dpy, fmt, vsz, args var ap var sz, b, o ap = std.vastart(&args) sz = fixsize(fmt) + vsz b = ensure(dpy, sz) o = 0 for c : fmt match (c : char) | 'b': b[o] = std.vanext(&ap) o += 1 | 's': var v : int16 = std.vanext(&ap) std.putle16(b[o:o+2], v) o += 2 | 'i': var v : int32 = std.vanext(&ap) std.putle32(b[o:o+4], v) o += 4 | 'p': var p : point = std.vanext(&ap) std.putle32(b[o + 0:o + 4], p.x) std.putle32(b[o + 4:o + 8], p.y) o += 2*4 | 'r': var r : rect = std.vanext(&ap) std.putle32(b[o+ 0:o+ 4], r.x0) std.putle32(b[o+ 4:o+ 8], r.y0) std.putle32(b[o+ 8:o+12], r.x1) std.putle32(b[o+12:o+16], r.y1) o += 4*4 | 'S': var s : byte[:] = std.vanext(&ap) b[o++] = (s.len : byte) std.slcp(b[o:o+s.len], s) o += s.len | 'I': var s : int16[:] = std.vanext(&ap) for var i = 0; i < s.len; i++ std.putle16(b[o:o+2], s[i]) o += 2 ;; | 'd': var d : byte[:] = std.vanext(&ap) std.slcp(b[o:o+d.len], d) o += d.len | ' ': /* for readability of format strings */ | chr: std.fatal("unknown specifier {} in pack\n", chr) ;; ;; } const fixsize = {fmt var sz sz = 0 for c : fmt match (c : char) | 'b': sz += 1 | 's': sz += 2 | 'i': sz += 4 | 'r': sz += 4*4 | 'p': sz += 2*4 | _: /* variable sizes */ ;; ;; -> sz } const ensure = {dpy, sz var ret if dpy.bufoff + sz > dpy.buf.len flush(dpy) ;; ret = dpy.buf[dpy.bufoff:dpy.bufoff + sz] dpy.bufoff += sz -> ret } const flush = {dpy /* five bytes always reserved here */ dpy.buf[dpy.bufoff++] = ('v' : byte) -> flushbuf(dpy) } const flushbuf = {dpy var off, ret var errbuf : byte[128] off = 0 ret = true while off != dpy.bufoff match std.write(dpy.datafd, dpy.buf[off:dpy.bufoff]) | `std.Ok n: off += n | `std.Err e: sys.errstr(errbuf[:]) std.fatal("**error: {}\n", std.cstrconv(errbuf[:])) ret = false break ;; ;; dpy.bufoff = 0 -> true }