diff options
Diffstat (limited to 'src/decompress.h')
-rw-r--r-- | src/decompress.h | 139 |
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 */ |