shithub: pdffs

ref: 97218f13586cad7be42bdd1ce28072d10df1c2f9
dir: pdffs/name.c

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

int
pdfname(char *p, char **e, int len)
{
	int i, o;

	if(len < 2){
		werrstr("too short");
		goto err;
	}

	if(p[0] != '/'){
		werrstr("invalid first char");
		goto err;
	}

	for(i = 1, o = 0; i < len; i++){
		if(p[i] < '!' || p[i] > '~'){
			werrstr("invalid char");
			goto err;
		}
		if(p[i] == '#'){
			i++;
			if(i+2 > len){
				werrstr("hex too short");
				goto err;
			}
			if(dec16((uchar*)p+o, 1, p+i, 2) != 1){
				werrstr("invalid hex");
				goto err;
			}
			o++;
			i++;
		}else{
			p[o++] = p[i];
		}
	}

	p[o] = 0;
	*e = p + i;

	return o;
err:
	werrstr("name: %r");
	return -1;
}

#ifdef TEST
static struct {
	char *i;
	int   len;
	char *o;
	int   r;
	int   e;
}t[] = {
	{"/SimpleName",            11, "SimpleName", 10},
	{"WrongName",               9, nil,          -1},
	{"/.$()",                   5, ".$()",        4},
	{"/#30",                    4, "0",           1},
	{"/#3",                     3, nil,          -1},
	{"/#G0",                    4, nil,          -1},
	{"/#",                      2, nil,          -1},
	{"/Wrong Char",            11, nil,          -1},
	{"/\xff",                   2, nil,          -1},
};

void
test_pdfname(void)
{
	char *e;
	int i, r;

	fprint(2, "pdfname\n");
	for(i = 0; i < nelem(t); i++){
		fprint(2, "\t%d: ", i);
		r = pdfname(t[i].i, &e, t[i].len);
		if(r != t[i].r){
			fprint(2, "expected r=%d, got %d", t[i].r, r);
			if(r < 0)
				fprint(2, " (%r)\n");
			else
				fprint(2, "\n");
			continue;
		}else if(r >= 0){
			if(t[i].i+t[i].len != e){
				fprint(2, "expected e=%p, got %p\n", t[i].i+t[i].len, e);
				continue;
			}else if(strcmp(t[i].o, t[i].i) != 0){
				fprint(2, "expected %q, got %q\n", t[i].o, t[i].i);
				continue;
			}
		}
		fprint(2, "OK");
		if(r < 0)
			fprint(2, " (%r)");
		fprint(2, "\n");
	}
}
#endif