/* Copyright (c) 2000-2010, Dirk Krause All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dirk Krause nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dkstream.h Generic I/O API. This module provides a generic I/O API allowing applications to use the same code regardless whether to write plain or compressed files (and may be network connections in the future...). Functions in this module can be grouped into three categories: - Functions to create and destroy dk_stream_t data structures, - functions for binary I/O, - functions for text I/O and - other functions. To open a stream you should use dkstream_openfile(), dkstream_opengz(), dkstream_openbz2() and dkstream_close() instead of dkstream_new() and dkstream_delete(). If you already opened the file use dkstream_for_file(), dkstream_for_gz() or dkstream_for_bz2() to create a dk_stream_t. Unless otherwise stated, int functions in this module return a positive number to indicate success or a true condition, 0 to indicate an error or an unfullfilled condition. Pointer functions return valid pointers on success, NULL on error. */ #ifndef DK_STREAM_INC #define DK_STREAM_INC 1 #include #include #if DK_HAVE_ZLIB_H #include #endif #if DK_HAVE_BZLIB_H #include #endif #if defined(EXTERN) #undef EXTERN #endif #ifndef DK_STREAM_C #if !DK_HAVE_PROTOTYPES #define EXTERN extern #else #define EXTERN /* nix */ #endif #else #define EXTERN /* nix */ #endif #if defined(__cplusplus) extern "C" { #endif /** Create a new dk_stream_t dynamically. The stream must be released using dkstream_delete(). @param data Data for the stream. @param fct Low-level function for the stream. @return Pointer to the new dk_stream_t on success, NULL on error. */ EXTERN dk_stream_t *dkstream_new DK_PR((void *data, dk_stream_fct_t *fct)); /** Release a dk_stream_t structure obtained from dkstream_new(). @param st Stream data to release. */ EXTERN void dkstream_delete DK_PR((dk_stream_t *st)); /** Open stream for plain file. The stream must be relased and the file must be closed using dkstream_close(). @param n Path name of the file. @param m Open mode (i.e. "r", "w"...). @param i Security checks to ignore (DK_SF_SEC_xxx). @param r Pointer to a variable receiving the error code for failed security checks (if any). @return Stream to use for I/O. */ EXTERN dk_stream_t *dkstream_openfile DK_PR((char *n, char *m, int i, int *r)); /** Open stream for gzip compressed file. The stream must be relased and the file must be closed using dkstream_close(). @param n Path name of the file. @param m Open mode (i.e. "r", "w"...). @param i Security checks to ignore (DK_SF_SEC_xxx). @param r Pointer to a variable receiving the error code for failed security checks (if any). @return Stream to use for I/O. */ EXTERN dk_stream_t *dkstream_opengz DK_PR((char *n, char *m, int i, int *r)); /** Open stream for bzip2 compressed file. The stream must be relased and the file must be closed using dkstream_close(). @param n Path name of the file. @param m Open mode (i.e. "r", "w"...). @param i Security checks to ignore (DK_SF_SEC_xxx). @param r Pointer to a variable receiving the error code for failed security checks (if any). @return Stream to use for I/O. */ EXTERN dk_stream_t *dkstream_openbz2 DK_PR((char *n, char *m, int i, int *r)); /** Open stream for already opened file. The stream must be released using dkstream_close(). The file \a f is not closed by dkstream_close(). @param f The file. @return Stream to use for I/O. */ EXTERN dk_stream_t *dkstream_for_file DK_PR((FILE *f)); #if DK_HAVE_ZLIB_H /** Open stream for already gzFile. The stream must be released using dkstream_close(). The gzFile \a gzf is not closed by dkstream_close(). @param gzf The gzFile. @return Stream to use for I/O. */ EXTERN dk_stream_t *dkstream_for_gz DK_PR((gzFile gzf)); #endif #if DK_HAVE_BZLIB_H /** Open stream for already opened BZFILE. The stream must be released using dkstream_close(). The BZFILE \a bzf is not closed by dkstream_close(). @param bzf The BZFILE. @return Stream to use for I/O. */ EXTERN dk_stream_t *dkstream_for_bz2 DK_PR((BZFILE *bzf)); #endif /** Releases dk_stream_t structures obtained from dkstream_openfile(), dkstream_opengz(), dkstream_openbz2(), dkstream_for_file(), dkstream_for_gz() and dkstream_for_bz2(). @param st The stream to close. */ EXTERN void dkstream_close DK_PR((dk_stream_t *st)); /** Write binary data to stream. @param s The stream to write to. @param b Pointer to buffer containing data to write. @param l Size of \a b in bytes. @return The number of bytes written. */ EXTERN size_t dkstream_write DK_PR((dk_stream_t *s, char *b, size_t l)); /** Read binary data from stream. @param s The stream to read from. @param b Pointer to buffer. @param l Length of buffer in bytes. @return The number of bytes read. */ EXTERN size_t dkstream_read DK_PR((dk_stream_t *s, char *b, size_t l)); /** Write a word (2 bytes) to stream binary. The word is converted to network byte order before it is written to the stream. @param s The stream to write to. @param w The word to write. @return Flag to indicate success. */ EXTERN int dkstream_wb_word DK_PR((dk_stream_t *s, dk_word w)); /** Write an unsigned word (2 bytes) to stream binary. The word is converted to network byte order before it is written to the stream. @param s The stream to write to. @param w The word to write. @return Flag to indicate success. */ EXTERN int dkstream_wb_uword DK_PR((dk_stream_t *s, dk_uword w)); /** Write a double-word (4 bytes) to stream binary. The double-word is converted to network byte order before it is written to the stream. @param s The stream to write to. @param w The double-word to write. @return Flag to indicate success. */ EXTERN int dkstream_wb_dword DK_PR((dk_stream_t *s, dk_dword w)); /** Write an unsigned double-word (4 bytes) to stream binary. The double-word is converted to network byte order before it is written to the stream. @param s The stream to write to. @param w The double-word to write. @return Flag to indicate success. */ EXTERN int dkstream_wb_udword DK_PR((dk_stream_t *s, dk_udword w)); /** Write a string to stream in binary form. A string in binary form is written to the stream in 2 parts: - The string length (including the finalizing 0x00 byte) as unsigned word. - The string text including the finalizing 0x00 byte. @param s The stream to write to. @param str The string to write. @return Flag to indicate success. */ EXTERN int dkstream_wb_string DK_PR((dk_stream_t *s, char *str)); /** Read word (2 bytes) binary from stream. Two bytes are read from stream and converted to host byte order. @param s The stream to read from. @param w Pointer to variable to store the result. @return Flag to indicate success. */ EXTERN int dkstream_rb_word DK_PR((dk_stream_t *s, dk_word *w)); /** Read unsigned word (2 bytes) binary from stream. Two bytes are read from stream and converted to host byte order. @param s The stream to read from. @param w Pointer to variable to store the result. @return Flag to indicate success. */ EXTERN int dkstream_rb_uword DK_PR((dk_stream_t *s, dk_uword *w)); /** Read double-word (4 bytes) binary from stream. Four bytes are read from stream and converted to host byte order. @param s The stream to read from. @param d Pointer to variable to store the result. @return Flag to indicate success. */ EXTERN int dkstream_rb_dword DK_PR((dk_stream_t *s, dk_dword *d)); /** Read unsigned double-word (4 bytes) binary from stream. Four bytes are read from stream and converted to host byte order. @param s The stream to read from. @param d Pointer to variable to store the result. @return Flag to indicate success. */ EXTERN int dkstream_rb_udword DK_PR((dk_stream_t *s, dk_udword *d)); /** Read string in binary form from stream. Reading consists of the following steps: - The string length (2-byte word) is read from stream, - buffer memory is allocated dynamically to store string and - the string is read from stream into the buffer. You must release the strings memory using dk_delete() if the string is not longer needed. @param s The stream to read from. @return Pointer to the buffer on success, NULL on error. */ EXTERN char *dkstream_rb_string DK_PR((dk_stream_t *s)); /** Write string in text form to stream. The string is written "as is" witout adding a trailing newline. @param s The stream to write to. @param b The string to write. @return Flag to indicate success. */ EXTERN int dkstream_puts DK_PR((dk_stream_t *s, char *b)); /** Write double in text form to stream. Check opt for DK_STREAM_OPT_DOUBLE_NO_EXPONENT to see whether or not exponent notation is allowed. @param s The stream to write to. @param d The number to write. @return Flag to indicate success. */ EXTERN int dkstream_puts_double_use_exp DK_PR((dk_stream_t *s, double d)); /** Write double in text form to stream, exponent notation allowed. @param s The stream to write to. @param d The number to write. @return Flag to indicate success. */ EXTERN int dkstream_puts_double DK_PR((dk_stream_t *s, double d)); /** Write unsigned long in text form to stream. @param s The stream to write to. @param u The value to write. @return Flag to indicate success. */ EXTERN int dkstream_puts_ul DK_PR((dk_stream_t *s, unsigned long u)); /** Write long in text form to stream. @param s The stream to write to. @param l The value to write. @return Flag to indicate success. */ EXTERN int dkstream_puts_long DK_PR((dk_stream_t *s, long l)); /** Write a text (array of strings) in text form to stream. A newline is appended after each array element. The array must be finished by a NULL pointer. @param s The stream to write to. @param a An array containing pointers to the strings to write. @return Flag to indicate success. */ EXTERN int dkstream_puts_array DK_PR((dk_stream_t *s, char **a)); /** Retrieve text line from stream. Text is read from stream to the buffer until either the buffer is full or a newline is found. @param s The stream to read from. @param b The destination buffer. @param l Length of buffer \a b in bytes. @return Pointer to buffer on success, NULL on error. */ EXTERN char *dkstream_gets DK_PR((dk_stream_t *s, char *b, size_t l)); /** Get number of bytes written to the stream. @param s The stream to check. @return Number of bytes written to the stream. */ EXTERN unsigned long dkstream_get_bytes_written DK_PR((dk_stream_t *s)); /** Find file type suffixes to handle (read operations). @return Array of elements connecting a file type suffix to a stream-open function. */ EXTERN dk_stream_suffix_t *dkstream_get_read_suffixes DK_PR((void)); /** Find file type suffixes to handle (write operations). @return Array of elements connecting a file type suffix to a stream open function. */ EXTERN dk_stream_suffix_t *dkstream_get_write_suffixes DK_PR((void)); /** Print double value to stream, avoid exponential notation. @param s Stream to print to. @param d Value to print. @return Flag to indicate success. */ EXTERN int dkstream_puts_double_no_exp DK_PR((dk_stream_t *s, double d)); /** Print double value in string to stream, avoid exponential notation. This function is not intended for use by the application programmer, it is used internally by dkstream_puts_double_no_exp(). @param s Stream to print to. @param t Text buffer containing exponential notation. @return Flag to indicate success. */ EXTERN int dkstream_puts_double_str_no_exp DK_PR((dk_stream_t *s, char *t)); /** Set up to deny (fl=1) or allow (fl=0) the use of exponent notation when printing double values. @param s Stream to configure. @param fl New flag value. @return Flag to indicate success. */ EXTERN void dkstream_set_double_no_exponent DK_PR((dk_stream_t *s, int fl)); /** Get flag for: no exponent notation for double values. @param s Stream to retrieve information from. @return Flag value. */ EXTERN int dkstream_get_double_no_exponent DK_PR((dk_stream_t *s)); #if defined(__cplusplus) } #endif /** Low-level API commands: Test support for command. */ #define DK_STREAM_CMD_TEST 1 /** Low-level API commands: Read bytes into buffer. */ #define DK_STREAM_CMD_RDBUF 2 /** Low-level API commands: Write bytes from buffer. */ #define DK_STREAM_CMD_WRBUF 3 /** Low-level API commands: Flush after final write operation. */ #define DK_STREAM_CMD_FINAL 4 /** Low-level API commands: Stream is closed now. */ #define DK_STREAM_CMD_FINISH 5 /** Low-level API commands: Rewind to start of stream data. */ #define DK_STREAM_CMD_REWIND 6 /** Low-level API commands: Flush. */ #define DK_STREAM_CMD_FLUSH 7 /** Low-level API commands: Check whether end of input is reached. */ #define DK_STREAM_CMD_AT_END 8 /** Low-level API commands: Get string. */ #define DK_STREAM_CMD_GETS 9 /** Low-level API commands: Put string. */ #define DK_STREAM_CMD_PUTS 10 /* The opt field */ /** Do not use exponent notation for double values.*/ #define DK_STREAM_OPT_DOUBLE_NO_EXPONENT 1 /* Internally used by Perl XS */ #define DK_STREAM_FLAGS_STATE_USABLE 1 #define DK_STREAM_FLAGS_STATE_CLOSED 0 #define DK_STREAM_FLAGS_STATE_MASK 1 #define DK_STREAM_FLAGS_FILTER 4 #endif