ref: 474117ed563f8f84f11d3dcf90635c584be29ec1
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