ref: 9b0b7035bdc207bebd8cb011544d29d26b8c8a1d
parent: 544097136c80b4754ac5905f948b802fdb9e090e
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Nov 17 09:38:30 EST 2017
[lib/scc] Add lpack and lunpack These are generic functions to pack/unpack little endian strings.
--- a/inc/scc.h
+++ b/inc/scc.h
@@ -45,3 +45,5 @@
extern void *new(Alloc *allocp);
extern void delete(Alloc *allocp, void *p);
extern int casecmp(const char *s1, const char *s2);
+extern int lpack(char *dst, char *fmt, ...);
+extern int lunpack(char *src, char *fmt, ...);
--- a/lib/scc/libdep.mk
+++ b/lib/scc/libdep.mk
@@ -7,3 +7,5 @@
$(LIBDIR)/xstrdup.o \
$(LIBDIR)/alloc.o \
$(LIBDIR)/casecmp.o \
+ $(LIBDIR)/lunpack.o \
+ $(LIBDIR)/lpack.o \
--- /dev/null
+++ b/lib/scc/lpack.c
@@ -1,0 +1,52 @@
+#include <stdarg.h>
+
+#include "../../inc/scc.h"
+
+int
+lpack(char *dst, char *fmt, ...)
+{
+ char *bp;
+ unsigned s;
+ unsigned long l;
+ unsigned long long q;
+ va_list va;
+
+ bp = dst;
+ va_start(va, fmt);
+ while (*fmt) {
+ switch (*fmt++) {
+ case 'c':
+ *bp++ = va_arg(va, unsigned);
+ break;
+ case 's':
+ s = va_arg(va, unsigned);
+ *bp++ = s >> 8;
+ *bp++ = s;
+ break;
+ case 'l':
+ l = va_arg(va, unsigned long);
+ *bp++ = l >> 24;
+ *bp++ = l >> 16;
+ *bp++ = l >> 8;
+ *bp++ = l;
+ break;
+ case 'q':
+ q = va_arg(va, unsigned long long);
+ *bp++ = q >> 56;
+ *bp++ = q >> 48;
+ *bp++ = q >> 40;
+ *bp++ = q >> 32;
+ *bp++ = q >> 24;
+ *bp++ = q >> 16;
+ *bp++ = q >> 8;
+ *bp++ = q;
+ break;
+ default:
+ va_end(va);
+ return -1;
+ }
+ }
+ va_end(va);
+
+ return dst - bp;
+}
--- /dev/null
+++ b/lib/scc/lunpack.c
@@ -1,0 +1,57 @@
+#include <stdarg.h>
+
+#include "../../inc/scc.h"
+
+int
+lunpack(char *src, char *fmt, ...)
+{
+ char *bp, *cp;
+ unsigned short *sp;
+ unsigned s;
+ unsigned long *lp, l;
+ unsigned long long *qp, q;
+ va_list va;
+
+ bp = src;
+ va_start(va, fmt);
+ while (*fmt) {
+ switch (*fmt++) {
+ case 'c':
+ cp = va_arg(va, unsigned char *);
+ *cp = *bp++;
+ break;
+ case 's':
+ sp = va_arg(va, unsigned short *);
+ s = (unsigned) *bp++ << 8;
+ s |= (unsigned) *bp++;
+ *sp = s;
+ break;
+ case 'l':
+ lp = va_arg(va, unsigned long *);
+ l = (unsigned long) *bp++ << 24;
+ l |= (unsigned long) *bp++ << 16;
+ l |= (unsigned long) *bp++ << 8;
+ l |= (unsigned long) *bp++;
+ *lp = l;
+ break;
+ case 'q':
+ qp = va_arg(va, unsigned long long *);
+ q = (unsigned long) *bp++ << 56;
+ q |= (unsigned long) *bp++ << 48;
+ q |= (unsigned long) *bp++ << 40;
+ q |= (unsigned long) *bp++ << 32;
+ q |= (unsigned long) *bp++ << 24;
+ q |= (unsigned long) *bp++ << 16;
+ q |= (unsigned long) *bp++ << 8;
+ q |= (unsigned long) *bp++;
+ *qp = q;
+ break;
+ default:
+ va_end(va);
+ return -1;
+ }
+ }
+ va_end(va);
+
+ return src - bp;
+}