summaryrefslogtreecommitdiffstats
path: root/src/decompress.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/decompress.h')
-rw-r--r--src/decompress.h139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/decompress.h b/src/decompress.h
new file mode 100644
index 0000000..f10ab88
--- /dev/null
+++ b/src/decompress.h
@@ -0,0 +1,139 @@
+/*
+ * decompress.h: interface to decompression abstraction layer
+ *
+ * Copyright (C) 2007 Colin Watson.
+ *
+ * This file is part of man-db.
+ *
+ * man-db is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * man-db is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with man-db; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef MAN_DECOMPRESS_H
+#define MAN_DECOMPRESS_H
+
+#include <stdbool.h>
+
+#include "pipeline.h"
+
+struct decompress;
+typedef struct decompress decompress;
+
+/* Flags, combined using bitwise-or. */
+enum {
+ /* Allow the resulting decompressor to be constructed by reading and
+ * buffering the decompressed file contents in-process, rather than
+ * by starting a subprocess and streaming the output. This is
+ * suitable if and only if the file contents are only going to be
+ * handled in-process rather than being passed as input to some
+ * other program, but if that is the case then this is a significant
+ * optimization.
+ */
+ DECOMPRESS_ALLOW_INPROCESS = 1
+};
+
+/* Open a decompressor reading from FILENAME. The caller must start the
+ * resulting decompressor. If the DECOMPRESS_ALLOW_INPROCESS flag is given,
+ * then the resulting decompressor may be in-process (in which case
+ * decompress_get_pipeline will fail).
+ */
+decompress *decompress_open (const char *filename, int flags);
+
+/* Open a decompressor reading from file descriptor FD. The caller must
+ * start the resulting decompressor. This always uses pipeline-based
+ * decompression, since if it attempted to decompress data in process it
+ * would be unable to recover if it found that the data was too large.
+ */
+decompress *decompress_fdopen (int fd);
+
+/* Return true if and only if this is a pipeline-based decompressor. */
+bool decompress_is_pipeline (decompress *d);
+
+/* Get the pipeline corresponding to a decompressor. Raises an assertion
+ * failure if this is not a pipeline-based decompressor.
+ */
+pipeline *decompress_get_pipeline (decompress *d);
+
+/* Return the start of the buffer stored in an in-process decompressor.
+ * Raises an assertion failure if this is not an in-process decompressor.
+ */
+const char *decompress_inprocess_buf (decompress *d);
+
+/* Return the total number of uncompressed bytes stored in an in-process
+ * decompressor. Raises an assertion failure if this is not an in-process
+ * decompressor.
+ */
+size_t decompress_inprocess_len (decompress *d);
+
+/* Replace an in-process decompressor's entire buffered file contents.
+ *
+ * In-process decompression works by buffering the whole file in memory,
+ * which works because we constrain it to only ever dealing with small
+ * files, and allows us to emulate streaming without having to resort to
+ * subprocesses, threads, or coroutines. However, there are some cases
+ * (notably encoding conversion) where it's useful to be able to do some
+ * kind of processing on the file contents in a way that similarly looks
+ * like streaming to its consumers. To allow for this, we allow consumers
+ * of decompressed data to replace the buffered file contents and reset the
+ * read offset so that their consumers in turn get the same useful read/peek
+ * API.
+ *
+ * This is of course a hack, and wouldn't be a wise thing to include in a
+ * general-purpose library API, but this is only used within man-db.
+ */
+void decompress_inprocess_replace (decompress *d, char *buf, size_t len);
+
+/* Start the processes in a pipeline-based decompressor. Does nothing for
+ * in-process decompressors.
+ */
+void decompress_start (decompress *d);
+
+/* Read len bytes of data from the decompressor, returning the data block.
+ * len is updated with the number of bytes read.
+ */
+const char *decompress_read (decompress *d, size_t *len);
+
+/* Look ahead in the decompressor's output for len bytes of data, returning
+ * the data block. len is updated with the number of bytes read. The
+ * starting position of the next read or peek is not affected by this call.
+ */
+const char *decompress_peek (decompress *d, size_t *len);
+
+/* Skip over and discard len bytes of data from the peek cache. Asserts that
+ * enough data is available to skip, so you may want to check using
+ * pipeline_peek_size first.
+ */
+void decompress_peek_skip (decompress *d, size_t len);
+
+/* Read a line of data from the decompressor, returning it. */
+const char *decompress_readline (decompress *d);
+
+/* Look ahead in the decompressor's output for a line of data, returning it.
+ * The starting position of the next read or peek is not affected by this
+ * call.
+ */
+const char *decompress_peekline (decompress *d);
+
+/* Wait for a decompressor to complete and return its combined exit status.
+ * For in-process decompressors, simply returns 0.
+ */
+int decompress_wait (decompress *d);
+
+/* Destroy a decompressor. Safely does nothing on NULL. For pipeline-based
+ * decompressors, may wait for the pipeline to complete if it has not already
+ * done so.
+ */
+void decompress_free (decompress *d);
+
+#endif /* MAN_DECOMPRESS_H */