ref: 3c27f041321b91dbf2bfd0ab9e4865e03854cd68
dir: /object.c/
#include <u.h>
#include <libc.h>
#include <ctype.h>
#include "pdf.h"
Object *
pdfobject(char *p, char **e, int len)
{
Object *o;
char *s, *p0;
int sz;
o = nil;
for(; len > 0 && isws(*p); p++, len--);
if(len < 1){
werrstr("too short");
goto err;
}
if(*p < 1){
werrstr("unexpected non-ascii char");
goto err;
}
switch(*p){
case '<': /* dictionary or a string */
if(len < 2){
werrstr("too short");
goto err;
}
if(p[1] == '<'){ /* dictionary */
o = pdfdict(p, e, len);
break;
}
/* fall through */
case '(': /* string */
if((sz = pdfstring(p, e, len)) < 0)
goto err;
if((o = malloc(sizeof(*o)+sz+1)) != nil){
o->type = Ostr;
o->str = (char*)(o+1);
strcpy(o->str, p);
}
break;
case '/':
if((sz = pdfname(p, e, len)) < 0)
goto err;
if((o = malloc(sizeof(*o)+sz+1)) != nil){
o->type = Oname;
o->str = (char*)(o+1);
strcpy(o->str, p);
}
break;
case '[':
o = pdfarray(p, e, len);
break;
default:
if(isdigit(*p)){
if((o = malloc(sizeof(*o)+sz+1)) != nil){
o->type = Onum;
o->num = strtod(p, e);
sz = len - (*e - p);
p0 = *e;
s = p0;
for(; sz > 0 && isws(*s); s++, sz--);
if(sz > 0 && isdigit(*s)){
strtod(s, &p);
sz -= (p - s);
s = p;
for(; sz > 0 && isws(*s); s++, sz--);
if(sz > 0 && *s == 'R'){ /* indirect object */
sz--;
s++;
o->type = Oindir;
p0 = s;
len = sz;
}
}
*e = p0;
}
break;
}
werrstr("unexpected char %c", *p);
goto err;
}
if(o != nil)
return o;
err:
werrstr("object: %r");
freeobject(o);
return nil;
}
void
freeobject(Object *o)
{
if(o == nil)
return;
free(o);
}