summaryrefslogtreecommitdiff
path: root/stream/filt_filec.c
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2005-03-30 08:30:22 +0200
committerTor Andersson <tor@ghostscript.com>2005-03-30 08:30:22 +0200
commitee154f16bd09a43359967f7e7b86c3677c09461d (patch)
tree08896cfa9ff55e05bfe7855965c620d45115d4d5 /stream/filt_filec.c
parent460ad7040d67a4a93a153f98095ff952a2b15d37 (diff)
downloadmupdf-ee154f16bd09a43359967f7e7b86c3677c09461d.tar.xz
rename part 1 -- files
Diffstat (limited to 'stream/filt_filec.c')
-rw-r--r--stream/filt_filec.c349
1 files changed, 349 insertions, 0 deletions
diff --git a/stream/filt_filec.c b/stream/filt_filec.c
new file mode 100644
index 00000000..05813185
--- /dev/null
+++ b/stream/filt_filec.c
@@ -0,0 +1,349 @@
+#include <fitz.h>
+
+fz_error *
+fz_ferror(fz_file *f)
+{
+ fz_error *e = f->error;
+ f->error = nil;
+ return e;
+}
+
+fz_error *
+fz_openfile(fz_file **filep, char *path, int mode)
+{
+ fz_error *error;
+ fz_file *file;
+ int realmode;
+ int fd;
+ int n;
+
+ assert(mode == FZ_READ || mode == FZ_WRITE || mode == FZ_APPEND);
+
+ realmode = 0;
+ if (mode == FZ_READ)
+ realmode = O_BINARY | O_RDONLY;
+ if (mode == FZ_WRITE)
+ realmode = O_BINARY | O_WRONLY | O_CREAT | O_TRUNC;
+ if (mode == FZ_APPEND)
+ realmode = O_BINARY | O_WRONLY;
+
+ fd = open(path, realmode, 0644);
+ if (fd == -1)
+ return fz_throw("ioerror: open '%s': %s", path, strerror(errno));
+
+ if (mode == FZ_APPEND)
+ {
+ mode = FZ_WRITE;
+ n = lseek(fd, 0, 2);
+ if (n == -1) {
+ error = fz_throw("ioerror: lseek: %s", strerror(errno));
+ close(fd);
+ return error;
+ }
+ }
+
+ file = *filep = fz_malloc(sizeof(fz_file));
+ if (!file)
+ return fz_outofmem;
+
+ file->mode = mode;
+ file->fd = fd;
+ file->depth = 0;
+ file->error = nil;
+ file->filter = nil;
+ file->in = nil;
+ file->out = nil;
+
+ error = fz_newbuffer(&file->in, FZ_BUFSIZE);
+ if (error)
+ goto cleanup;
+
+ error = fz_newbuffer(&file->out, FZ_BUFSIZE);
+ if (error)
+ goto cleanup;
+
+ return nil;
+
+cleanup:
+ *filep = nil;
+ close(fd);
+ fz_dropbuffer(file->out);
+ fz_dropbuffer(file->in);
+ fz_free(file);
+ return error;
+}
+
+fz_error *
+fz_openbuffer(fz_file **filep, fz_buffer *buf, int mode)
+{
+ fz_error *error;
+ fz_file *file;
+
+ assert(mode == FZ_READ || mode == FZ_WRITE);
+
+ file = *filep = fz_malloc(sizeof(fz_file));
+ if (!file)
+ return fz_outofmem;
+
+ file->mode = mode;
+ file->fd = -1;
+ file->depth = 0;
+ file->error = nil;
+ file->filter = nil;
+
+ if (mode == FZ_READ)
+ {
+ file->out = fz_keepbuffer(buf);
+ error = fz_newbuffer(&file->in, FZ_BUFSIZE);
+ if (error)
+ goto cleanup;
+ }
+
+ else
+ {
+ error = fz_newbuffer(&file->out, FZ_BUFSIZE);
+ if (error)
+ goto cleanup;
+ file->in = fz_keepbuffer(buf);
+ }
+
+ return nil;
+
+cleanup:
+ *filep = nil;
+ fz_free(file);
+ return error;
+}
+
+void
+fz_closefile(fz_file *file)
+{
+ assert(file->depth == 0);
+
+ if (file->mode == FZ_WRITE)
+ fz_flush(file);
+
+ if (file->error)
+ {
+ fz_warn("%s", file->error->msg);
+ fz_droperror(file->error);
+ file->error = nil;
+ }
+
+ if (file->fd != -1) /* open to real file */
+ close(file->fd);
+
+ fz_dropbuffer(file->in);
+ fz_dropbuffer(file->out);
+
+ if (file->filter)
+ fz_dropfilter(file->filter);
+
+ fz_free(file);
+}
+
+fz_error *
+fz_pushfilter(fz_file *file, fz_filter *filter)
+{
+ fz_error *error;
+
+ /* without a filter, one buffer is ignored: unignore. */
+ if (file->depth == 0)
+ {
+ fz_buffer *buf;
+
+ buf = file->out;
+ file->out = file->in;
+ file->in = buf;
+
+ if (file->mode == FZ_READ)
+ {
+ file->out->rp = file->out->bp;
+ file->out->wp = file->out->bp;
+ file->out->eof = 0;
+ }
+ else
+ {
+ file->out->eof = 0;
+ file->in->rp = file->in->bp;
+ file->in->wp = file->in->bp;
+ file->in->eof = 0;
+ }
+
+ file->filter = fz_keepfilter(filter);
+ }
+
+ else
+ {
+ if (file->mode == FZ_READ)
+ {
+ error = fz_chainpipeline(&file->filter, file->filter, filter, file->out);
+ if (error)
+ return error;
+
+ error = fz_newbuffer(&file->out, FZ_BUFSIZE);
+ if (error)
+ {
+ fz_unchainpipeline(file->filter, &file->filter, &file->out);
+ return error;
+ }
+ }
+
+ else
+ {
+ error = fz_chainpipeline(&file->filter, filter, file->filter, file->in);
+ if (error)
+ return error;
+
+ error = fz_newbuffer(&file->in, FZ_BUFSIZE);
+ if (error)
+ {
+ fz_unchainpipeline(file->filter, &file->filter, &file->in);
+ return error;
+ }
+ }
+ }
+
+ file->depth ++;
+
+ return nil;
+}
+
+void
+fz_popfilter(fz_file *file)
+{
+ fz_buffer *buf;
+
+ assert(file->depth > 0);
+
+ if (file->mode == FZ_WRITE)
+ fz_flush(file);
+
+ if (file->error)
+ {
+ fz_warn("%s", file->error->msg);
+ fz_droperror(file->error);
+ file->error = nil;
+ }
+
+ if (file->depth == 1)
+ {
+ fz_dropfilter(file->filter);
+ file->filter = nil;
+
+ buf = file->out;
+ file->out = file->in;
+ file->in = buf;
+ }
+ else
+ {
+ if (file->mode == FZ_READ)
+ {
+ fz_dropbuffer(file->out);
+ fz_unchainpipeline(file->filter, &file->filter, &file->out);
+ }
+ else
+ {
+ fz_dropbuffer(file->in);
+ fz_unchainpipeline(file->filter, &file->filter, &file->in);
+ }
+ }
+
+ file->depth --;
+}
+
+int
+fz_seek(fz_file *f, int ofs, int whence)
+{
+ int t;
+ int c;
+
+ if (f->filter)
+ {
+ assert(f->mode == FZ_READ && whence == 0);
+
+ if (ofs < fz_tell(f))
+ {
+ f->error = fz_throw("ioerror: cannot seek backwards in filter");
+ return -1;
+ }
+ while (fz_tell(f) < ofs)
+ {
+ c = fz_readbyte(f);
+ if (c == EOF)
+ return -1;
+ }
+ return ofs;
+ }
+
+ if (whence == 1)
+ {
+ ofs = fz_tell(f) + ofs;
+ whence = 0;
+ }
+
+ if (f->fd == -1)
+ {
+ if (whence == 0)
+ {
+ if (f->mode == FZ_READ)
+ f->out->rp = CLAMP(f->out->bp + ofs, f->out->bp, f->in->ep);
+ else
+ f->in->wp = CLAMP(f->in->bp + ofs, f->in->bp, f->in->ep);
+ }
+ else
+ {
+ if (f->mode == FZ_READ)
+ f->out->rp = CLAMP(f->out->ep + ofs, f->out->bp, f->in->ep);
+ else
+ f->in->wp = CLAMP(f->in->ep + ofs, f->in->bp, f->in->ep);
+ }
+ return fz_tell(f);
+ }
+
+ t = lseek(f->fd, ofs, whence);
+ if (t == -1)
+ {
+ f->error = fz_throw("ioerror: lseek: %s", strerror(errno));
+ return -1;
+ }
+
+ f->out->rp = f->out->bp;
+ f->out->wp = f->out->bp;
+ f->out->eof = 0;
+
+ return t;
+}
+
+int
+fz_tell(fz_file *f)
+{
+ int t;
+
+ if (f->filter)
+ {
+ assert(f->mode == FZ_READ);
+ return f->filter->count - (f->out->wp - f->out->rp);
+ }
+
+ if (f->fd == -1)
+ {
+ if (f->mode == FZ_READ)
+ return f->out->rp - f->out->bp;
+ else
+ return f->in->wp - f->in->bp;
+ }
+
+ t = lseek(f->fd, 0, 1);
+ if (t == -1)
+ {
+ f->error = fz_throw("ioerror: lseek: %s", strerror(errno));
+ return -1;
+ }
+
+ if (f->mode == FZ_READ)
+ return t - (f->out->wp - f->out->rp);
+ else
+ return t + (f->in->wp - f->in->rp);
+}
+