ref: 1d93500ddcda77cd265d492c6c9094c0f5c7488f
dir: /stream.c/
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "pdf.h"
static int
bufiof(Biobufhdr *b, void *data, long n)
{
Stream *s;
s = (void*)((char*)b - sizeof(*s));
return bufget(&s->buf, data, n);
}
Stream *
streamopen(Object *o)
{
Stream *s;
Buffer b, x;
Object *of, **flts;
Filter *f;
int i, nflts;
s = nil;
if(pdfeval(o)->type != Ostream) /* FIXME open a string object as a stream as well? */
return nil;
bufinit(&b, nil, 0);
if(Bseek(o->pdf->bio, o->stream.off, 0) != o->stream.off)
return nil;
if(bufreadn(&b, o->pdf->bio, o->stream.len) < 0)
goto err;
bufdump(&b);
/* see if there are any filters */
if((of = dictget(o, "Filter")) != nil){
if(pdfeval(of)->type == Oname){ /* one filter */
flts = &of;
nflts = 1;
}else if(of->type == Oarray){ /* array of filters */
flts = of->array.e;
nflts = of->array.ne;
}else{
werrstr("filters type invalid (%T)", of);
goto err;
}
for(i = nflts-1; i >= 0; i--){
if(flts[i]->type != Oname){
werrstr("filter type invalid (%T)", flts[i]);
goto err;
}
if((f = filteropen(flts[i]->name, o)) == nil)
goto err;
bufinit(&x, nil, 0);
if(filterrun(f, &b, &x) != 0){
buffree(&x);
goto err;
}
buffree(&b);
b = x;
}
}
if((s = calloc(1, sizeof(*s)+sizeof(Biobuf))) == nil){
buffree(&b);
return nil;
}
s->bio = (uchar*)(s+1);
s->buf = b;
Binit(s->bio, Bfildes(o->pdf->bio), OREAD);
Biofn(s->bio, bufiof);
bufdump(&s->buf);
return s;
err:
werrstr("stream: %r");
buffree(&b);
free(s);
return nil;
}
void
streamclose(Stream *s)
{
buffree(&s->buf);
Bterm(s->bio);
free(s);
}