shithub: pdffs

ref: a9516693e7142a658f4e3ea190272f4cd73b24be
dir: /dict.c/

View raw version
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "pdf.h"

/* 7.3.7 Dictionary Objects */

Object *
pdfdict(Pdf *pdf, Biobuf *b)
{
	Object *o, *k, *v;
	KeyValue *kv;
	int c, nokey;

	/* skip '<<' */
	Bseek(b, 2, 1);

	k = v = nil;
	o = calloc(1, sizeof(*o));
	o->type = Odict;
	for(nokey = 0;;){
		if((c = Bgetc(b)) < 0)
			goto err;
		if(c == '>'){
			if(Bgetc(b) == '>')
				break;
			werrstr("no '>>'");
			goto err;
		}
		if(nokey){
			werrstr("no '>>'");
			goto err;
		}

		Bungetc(b);
		if((k = pdfobj(pdf, b)) == nil){
			nokey = 1;
			continue;
		}
		if((v = pdfobj(pdf, b)) == nil)
			goto err;
		if(k->type != Oname){
			werrstr("expected name as a key");
			goto err;
		}

		if((kv = realloc(o->dict.kv, (o->dict.nkv+1)*sizeof(KeyValue))) == nil)
			goto err;

		o->dict.kv = kv;
		kv[o->dict.nkv].key = strdup(k->name);
		pdfobjfree(k);
		kv[o->dict.nkv++].value = v;
		k = v = nil;
	}

	return o;
err:
	pdfobjfree(o);
	pdfobjfree(k);
	pdfobjfree(v);
	werrstr("dict: %r");

	return nil;
}

Object *
pdfdictget(Object *o, char *name)
{
	int i;

	if(o == nil || (o->type != Ostream && o->type != Odict) || name == nil)
		return nil;
	for(i = 0; i < o->dict.nkv && strcmp(name, o->dict.kv[i].key) != 0; i++);

	return i < o->dict.nkv ? o->dict.kv[i].value : nil;
}