shithub: pdffs

ref: 17128cefa8384e9433de8a725686b4e544a83308
dir: /name.c/

View raw version
#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