ref: 222bf07cdb99049713271bba455e07e5e4e55e71
parent: a86cea4bc4207f2193a2ba5e35730f1a087f5c06
author: rodri <rgl@antares-labs.eu>
date: Sat Mar 15 08:15:59 EDT 2025
bring unpacking routines and simplify the code
--- a/stl.c
+++ b/stl.c
@@ -3,6 +3,8 @@
#include <bio.h>
#include "stl.h"
+static int bunpack(Biobuf*, char*, ...);
+
static int
Bgets(Biobuf *b, u16int *s)
{
@@ -43,18 +45,64 @@
}
static int
-Bgetfv(Biobuf *b, float *f)
+vbunpack(Biobuf *b, char *fmt, va_list a)
{
- int i;
+ u16int s;
+ u32int l;
+ float f, *v;
+ void *p;
- for(i = 0; i < 3; i++)
- if(Bgetf(b, &f[i]) < 0){
- werrstr("Bgetf: %r");
- return -1;
+ for(;;){
+ switch(*fmt++){
+ case '\0':
+ return 0;
+ case 's':
+ if(Bgets(b, &s) < 0)
+ goto error;
+ *va_arg(a, ushort*) = s;
+ break;
+ case 'l':
+ if(Bgetl(b, &l) < 0)
+ goto error;
+ *va_arg(a, ulong*) = l;
+ break;
+ case 'f':
+ if(Bgetf(b, &f) < 0)
+ goto error;
+ *va_arg(a, float*) = f;
+ break;
+ case 'v':
+ v = va_arg(a, float*);
+ if(bunpack(b, "fff", v+0, v+1, v+2) < 0)
+ goto error;
+ break;
+ case '[':
+ p = va_arg(a, void*);
+ s = va_arg(a, ushort);
+ if(Bread(b, p, s) != s){
+ werrstr("Bread: could not read %ud bytes", s);
+ goto error;
+ }
+ break;
}
- return 0;
+ }
+error:
+ return -1;
}
+static int
+bunpack(Biobuf *b, char *fmt, ...)
+{
+ va_list a;
+ int n;
+
+ va_start(a, fmt);
+ n = vbunpack(b, fmt, a);
+ va_end(a);
+
+ return n;
+}
+
Stl *
readstl(int fd)
{
@@ -71,65 +119,40 @@
stl = mallocz(sizeof(Stl), 1);
if(stl == nil){
- werrstr("mallocz: %r");
+ werrstr("mallocz0: %r");
goto error;
}
- if(Bread(bin, stl->hdr, sizeof(stl->hdr)) != sizeof(stl->hdr)){
- werrstr("Bread: %r");
+ if(bunpack(bin, "[l", stl->hdr, sizeof(stl->hdr), &ntris) < 0){
+ werrstr("hdr bunpack: %r");
goto error;
}
- if(Bgetl(bin, &ntris) < 0){
- werrstr("Bgetl: %r");
- goto error;
- }
for(i = 0; i < ntris; i++){
tri = mallocz(sizeof(Stltri), 1);
if(tri == nil){
- free(tri);
- werrstr("mallocz: %r");
+ werrstr("mallocz1: %r");
goto error;
}
- if(Bgetfv(bin, tri->n) < 0){
+ if(bunpack(bin, "vvvvs", tri->n, tri->p0, tri->p1, tri->p2, &tri->attrlen) < 0){
free(tri);
- werrstr("Bgetfv: %r");
+ werrstr("tri bunpack0: %r");
goto error;
}
- if(Bgetfv(bin, tri->p0) < 0){
- free(tri);
- werrstr("Bgetfv: %r");
- goto error;
- }
- if(Bgetfv(bin, tri->p1) < 0){
- free(tri);
- werrstr("Bgetfv: %r");
- goto error;
- }
- if(Bgetfv(bin, tri->p2) < 0){
- free(tri);
- werrstr("Bgetfv: %r");
- goto error;
- }
-
- if(Bgets(bin, &tri->attrlen) < 0){
- free(tri);
- werrstr("Bgets: %r");
- goto error;
- }
tri = realloc(tri, sizeof(Stltri) + tri->attrlen);
if(tri == nil){
- werrstr("realloc: %r");
+ werrstr("realloc0: %r");
goto error;
}
- if(Bread(bin, tri->attrs, tri->attrlen) != tri->attrlen){
+ if(bunpack(bin, "[", tri->attrs, tri->attrlen) < 0){
free(tri);
- werrstr("Bread: %r");
+ werrstr("tri bunpack1: %r");
goto error;
}
stl->tris = realloc(stl->tris, (stl->ntris+1)*sizeof(*stl->tris));
if(stl->tris == nil){
- werrstr("realloc: %r");
+ free(tri);
+ werrstr("realloc1: %r");
goto error;
}
stl->tris[stl->ntris++] = tri;