ref: d613b76a67a6dbb4d2c16a17e6994e7bdf2731df
dir: /name.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "pdf.h" /* 7.3.5 Name Objects */ Object * pdfname(Biobuf *b) { Object *o; char *s, *r, hex[3]; int c, sz, maxsz; Bgetc(b); /* skip '/' */ maxsz = 32; if((s = malloc(maxsz)) == nil) goto err; for(sz = 0;;){ if((c = Bgetc(b)) < 0){ if(c == Beof) break; goto err; } if(isws(c) || isdelim(c)){ Bungetc(b); break; } if(c < '!' || c > '~'){ werrstr("invalid char %02x", c); goto err; } if(c == '#'){ if((c = Bgetc(b)) < 0) goto err; hex[0] = c; if((c = Bgetc(b)) < 0) goto err; hex[1] = c; if(dec16((uchar*)hex, 1, hex, 2) != 1){ werrstr("invalid hex"); goto err; } c = hex[0]; } if(sz+1 >= maxsz){ maxsz *= 2; if((r = realloc(s, maxsz)) == nil) goto err; s = r; } s[sz++] = c; } if((o = malloc(sizeof(*o))) != nil){ o->name = s; s[sz] = 0; o->type = Oname; return o; } err: werrstr("name: %r"); free(s); return nil; } #ifdef TEST static struct { char *in; char *out; }t[] = { {"/SimpleName", "SimpleName"}, {"/.$()", ".$"}, {"/#30", "0"}, {"/#3", nil}, {"/#G0", nil}, {"/#", nil}, {"/Space Between", "Space"}, {"/Two/Names", "Two"}, {"/\xff", nil,}, }; static char *s; static int off, n; static int rd(Biobufhdr *, void *data, long sz) { if(sz > n-off) sz = n-off; memmove(data, s+off, sz); off += sz; return sz; } void test_pdfname(void) { Object *o; Biobuf b; int i; fprint(2, "pdfname\n"); for(i = 0; i < nelem(t); i++){ s = t[i].in; n = strlen(s); off = 0; Binit(&b, -1, OREAD); Biofn(&b, rd); fprint(2, "\t%d: ", i); o = pdfname(&b); if(o == nil && t[i].out != nil) fprint(2, "ERROR: expected %q, got error: %r\n", t[i].out); else if(o != nil && t[i].out == nil) fprint(2, "ERROR: expected error, got %q\n", o->name); else if(o == nil && t[i].out == nil) fprint(2, "OK (%r)\n"); else if(strcmp(o->name, t[i].out) != 0) fprint(2, "ERROR: expected %q, got %q\n", t[i].out, o->name); else fprint(2, "OK\n"); pdfobjfree(o); Bterm(&b); } } #endif