ref: ecd40a88198f1a03b0e87a4f3066f944f09cf0d8
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 = (Stream*)((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; /* 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 = (Biobuf*)(s+1); s->buf = b; Binit(s->bio, Bfildes(o->pdf->bio), OREAD); Biofn(s->bio, bufiof); return s; err: werrstr("stream: %r"); buffree(&b); free(s); return nil; } void streamclose(Stream *s) { buffree(&s->buf); Bterm(s->bio); free(s); }