/* ** Copyright (C) 2006-2007 by Carnegie Mellon University. ** ** @OPENSOURCE_HEADER_START@ ** ** Use of the SILK system and related source code is subject to the terms ** of the following licenses: ** ** GNU Public License (GPL) Rights pursuant to Version 2, June 1991 ** Government Purpose License Rights (GPLR) pursuant to DFARS 252.225-7013 ** ** NO WARRANTY ** ** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER ** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY ** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN ** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY ** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT ** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE ** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT, ** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY ** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF ** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. ** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF ** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON ** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE ** DELIVERABLES UNDER THIS LICENSE. ** ** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie ** Mellon University, its trustees, officers, employees, and agents from ** all claims or demands made against them (and any related losses, ** expenses, or attorney's fees) arising out of, or relating to Licensee's ** and/or its sub licensees' negligent use or willful misuse of or ** negligent conduct or willful misconduct regarding the Software, ** facilities, or other rights or assistance granted by Carnegie Mellon ** University under this License, including, but not limited to, any ** claims of product liability, personal injury, death, damage to ** property, or violation of any laws or regulations. ** ** Carnegie Mellon University Software Engineering Institute authored ** documents are sponsored by the U.S. Department of Defense under ** Contract F19628-00-C-0003. Carnegie Mellon University retains ** copyrights in all material produced under this contract. The U.S. ** Government retains a non-exclusive, royalty-free license to publish or ** reproduce these documents, or allow others to do so, for U.S. ** Government purposes only pursuant to the copyright license under the ** contract clause at 252.227.7013. ** ** @OPENSOURCE_HEADER_END@ */ #ifndef _SKSTREAM_H #define _SKSTREAM_H #include "silk.h" RCSIDENTVAR(rcsID_SKSTREAM_H, "$SiLK: skstream.h 7617 2007-06-21 21:34:32Z mthomas $"); /* ** skstream.h ** ** An interface around file descriptors, which allows for buffered ** reading and writing, as well as compression. ** */ #include "rwpack.h" /* The stream object itself */ struct _skstream; typedef struct _skstream skstream_t; /* What we are attempting to do with the stream */ typedef enum { SK_IO_READ = 1, SK_IO_WRITE = 2, SK_IO_APPEND = 4 } skstream_mode_t; /* What type of content the stream contains */ typedef enum { /* stream contains line-oriented text */ SK_CONTENT_TEXT = 1, /* stream contains a SiLK file header and data */ SK_CONTENT_SILK = 2, /* stream contains binary data other than SiLK */ SK_CONTENT_OTHERBINARY = 4 } skcontent_t; /* Return values that most skStream*() functions return */ typedef enum { SKSTREAM_OK = 0, /* The last command was completed successfully. */ SKSTREAM_ERR_ALLOC, /* Memory could not be allocated. */ SKSTREAM_ERR_BAD_MAGIC, /* The file's header does not contain the SiLK magic number---for * files that contain SK_CONTENT_SILK. */ SKSTREAM_ERR_CLOSED, /* Attempt to operate on a file that is already closed. Once * closed, a stream can only be destroyed; re-opening is not yet * supported. */ SKSTREAM_ERR_EOF, /* Value returned by skStreamGetLine() when the input is * exhausted. */ SKSTREAM_ERR_FILE_EXISTS, /* Attempt to open a stream for writing that is bound to an * existing file. */ SKSTREAM_ERR_INVALID_INPUT, /* An argument to a function is invalid: passing skStreamFDOpen() * a value of -1, passing too long a pathname ti skStreamBind(), * using an supported SiLK file format. */ SKSTREAM_ERR_IOBUF, /* Error with internal buffering. */ SKSTREAM_ERR_ISTERMINAL, /* Attempt to read or write binary data on a terminal (tty) */ SKSTREAM_ERR_LONG_LINE, /* Returned by skStreamGetLine() when an input line is longer than * the specified buffer size. */ SKSTREAM_ERR_NOPAGER, /* Attempt to invoke the paging program failed. */ SKSTREAM_ERR_NOT_BOUND, /* Attempt to open a stream that is not bound to a pathname. */ SKSTREAM_ERR_NOT_OPEN, /* Attempt to read or write from a stream that has not yet been * opened. */ SKSTREAM_ERR_NULL_ARGUMENT, /* An argument to the function is NULL or empty */ SKSTREAM_ERR_PREV_BOUND, /* The stream is already bound to a pathname. */ SKSTREAM_ERR_PREV_DATA, /* Attempt to operate on a stream that has already had data * written-to/read-from it. */ SKSTREAM_ERR_PREV_OPEN, /* The stream is already open. */ SKSTREAM_ERR_READ, /* There was an error reading from the stream. */ SKSTREAM_ERR_RLOCK, /* Could not get a read lock on the stream. */ SKSTREAM_ERR_SYS_FDOPEN, /* The call to fdopen() failed. */ SKSTREAM_ERR_SYS_LSEEK, /* The call to lseek() failed. */ SKSTREAM_ERR_SYS_OPEN, /* The call to open() failed. */ SKSTREAM_ERR_SYS_MKSTEMP, /* The call to mkstemp() failed. */ SKSTREAM_ERR_UNSUPPORT_COMPRESS, /* The stream is compressed with a unsupported compression mode; * for example, you're operating on a gzipped file but SiLK was * not linked with gzip. */ SKSTREAM_ERR_UNSUPPORT_CONTENT, /* The file's content type does not support the action: attempt to * skStreamRead() on a SK_CONTENT_TEXT stream, attempt to * skStreamPrint() to a binary or SiLK stream, etc. */ SKSTREAM_ERR_UNSUPPORT_IOMODE, /* The file's read/write status does not support the action: an * attempt to write to "stdin", an attempt to appending to a * FIFO. */ SKSTREAM_ERR_WLOCK, /* Could not get a read lock on the stream. */ SKSTREAM_ERR_WRITE, /* There was an error writing to the stream. */ SKSTREAM_ERR_IO = -1 /* Value returned skStreamRead() and skStreamWrite() when an error * has occured. */ } skstream_err_t; int skStreamBind( skstream_t *stream, const char *pathname); /* * Set 'stream' to operate on the file specified in 'pathname'; * 'pathname' may also be one of "stdin", "stdout", or "stderr". * Return SKSTREAM_OK on success, or one of these error codes: * * SKSTREAM_ERR_PREV_BOUND * SKSTREAM_ERR_INVALID_INPUT * SKSTREAM_ERR_ISTERMINAL * SKSTREAM_ERR_UNSUPPORT_IOMODE */ int skStreamCheckCompmethod( skstream_t *stream, sk_msg_fn_t err_fn); /* * Check that the compression method used by 'stream' is available. * Return SKSTREAM_OK if it is. If it is not, return * SKSTREAM_ERR_UNSUPPORT_COMPRESS; in addition, if 'err_fn' is * provided, print an error message using that function. */ int skStreamClose( skstream_t *stream); /* * Flush any data on the 'stream' and closes the underlying file * descriptor. Return SKSTREAM_OK on success, or one of these * error codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_CLOSED * SKSTREAM_ERR_NOT_OPEN * SKSTREAM_ERR_WRITE * SKSTREAM_ERR_IOBUF */ int skStreamCreate( skstream_t **new_stream, skstream_mode_t read_write_append, skcontent_t content_type); /* * Create a new stream at the location pointed to by 'new_stream'; * the action to perform on 'stream' is determined by * 'read_write_append', and 'content_type' specified the content of * 'stream'. Return SKSTREAM_OK on success, or one of these error * codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_ALLOC */ int skStreamDestroy( skstream_t **stream); /* * Closes the stream at '*stream', if open, destroys the stream * pointed at by 'stream' and sets '*stream' to NULL. If 'stream' * is NULL or its value is NULL, no action is taken and the * function returns. Return SKSTREAM_OK on success, or any of the * error codes listed by skStreamClose(). */ int skStreamFDOpen( skstream_t *stream, int file_desc); /* * Associate 'stream' with the previously opened file descriptor * 'file_desc'. The 'stream' must have been previously bound to a * filename. Return SKSTREAM_OK on success, or one of these error * codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_NOT_BOUND * SKSTREAM_ERR_PREV_OPEN * SKSTREAM_ERR_CLOSED * SKSTREAM_ERR_INVALID_INPUT * SKSTREAM_ERR_UNSUPPORT_COMPRESS * SKSTREAM_ERR_ALLOC */ int skStreamFlush( skstream_t *stream); /* * Flush any data in the stream's buffers to disk; has no effect on * a stream open for reading. Return SKSTREAM_OK on success, or * one of these error codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_NOT_OPEN */ sk_compmethod_t skStreamGetCompressionMethod( skstream_t *stream); /* * Return the compression method used on 'stream'. */ int skStreamGetLine( skstream_t *stream, char *out_buffer, size_t buf_size, int *line_count); /* * Read a line of text from 'stream' and store it in 'out_buffer', * a character array of buf_size characters. If 'line_count' is * non-NULL, it's value will be INCREMENTED by the number of lines * read, typically 1. The line will be truncated at the newline * character---the newline will not be returned. Return * SKSTREAM_OK on success, or SKSTREAM_ERR_EOF at the end of file. * * Lines containing only whitespace are ignored. If the stream's * comment character has been set, comments are stripped from the * input as well, and lines containing only comments are ignored. * * If a line is longer than 'buf_size', the line is ignored and * SKSTREAM_ERR_LONG_LINE is returned. The value in 'out_buffer' * will be random. * * This function requires that 'stream' be an SK_IO_READ stream * that has a content type of SK_CONTENT_TEXT. * * In addition to the above return values, the function may also * return: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_NOT_OPEN * SKSTREAM_ERR_CLOSED * SKSTREAM_ERR_UNSUPPORT_CONTENT * SKSTREAM_ERR_UNSUPPORT_IOMODE * SKSTREAM_ERR_SYS_FDOPEN */ const char *skStreamGetPager( const skstream_t *stream); /* * For an open stream, returns the name of the paging program if it * is being used, or NULL if a pager is not in use. For a stream * that is not yet open, returns the name of the paging program * which MAY be used, or NULL if paging has not been requested. */ const char *skStreamGetPathname( const skstream_t *stream); /* * Return the pathname to which 'stream' has been bound, or NULL if * the stream is unbound. */ fileFormat_t skStreamGetSilkFormat( const skstream_t *stream); /* * Return the SiLK file output format for the stream. */ fileVersion_t skStreamGetSilkVersion( const skstream_t *stream); /* * Return the version number of the SiLK file associated with the * stream. */ int skStreamIsNativeByteOrder( const skstream_t *stream); /* * Return 1 if the stream is in native byte order, or 0 if it is * not. Assumes the 'stream' refers to a SiLK file. */ int skStreamLockFile( skstream_t *stream); /* * Block until the stream has a lock on the file associated with * 'stream'. Return SKSTREAM_OK on success or if the stream is * not-seekable, or one of the following error codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_NOT_OPEN * SKSTREAM_ERR_CLOSED * SKSTREAM_ERR_RLOCK * SKSTREAM_ERR_WLOCK */ int skStreamMakeTemp( skstream_t *stream); /* * Pass the pathname associated with 'stream' to the mkstemp() * system call to create a temporary file. Return SKSTREAM_OK on * success, or one of the following error codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_NOT_BOUND * SKSTREAM_ERR_PREV_OPEN * SKSTREAM_ERR_CLOSED * SKSTREAM_ERR_ALLOC * SKSTREAM_ERR_UNSUPPORT_IOMODE * SKSTREAM_ERR_SYS_MKSTEMP */ int skStreamOpen( skstream_t *stream); /* * Open the file associated with 'stream'. Note that * skStreamOpen() must be called even when the stream has been * bound to a standard stream, i.e., "stdin", "stdout", or * "stderr". For an output stream, the target file must not * previously exist, unless it is a FIFO or a character special * file, i.e., "/dev/null". * * Return SKSTREAM_OK on success, or one of the following error * codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_NOT_BOUND * SKSTREAM_ERR_PREV_OPEN * SKSTREAM_ERR_CLOSED * SKSTREAM_ERR_ALLOC * SKSTREAM_ERR_SYS_OPEN * SKSTREAM_ERR_FILE_EXISTS * SKSTREAM_ERR_UNSUPPORT_IOMODE * SKSTREAM_ERR_UNSUPPORT_COMPRESS */ int skStreamPageOutput( skstream_t *stream, const char *pager); /* * Allow 'stream' to display its output a screenful at a time by * invoking the program named by 'pager' and pass the output of * 'stream' through it. This function requires that 'stream' be an * SK_IO_WRITE stream that has a content type of SK_CONTENT_TEXT. * * 'stream' may be open or not-yet-open; if open, no data can have * been written to 'stream' yet. If 'stream' is already open, this * function will invoke the pager; otherwise, the pager will be * invoked on the first attempt to skStreamPrint() to 'stream'. * * Return SKSTREAM_OK on success, or one of the following error * codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_CLOSED * SKSTREAM_ERR_ATTRIBUTE_FIXED * SKSTREAM_ERR_ALLOC * SKSTREAM_ERR_SYS_FDOPEN * SKSTREAM_ERR_UNSUPPORT_IOMODE * SKSTREAM_ERR_UNSUPPORT_CONTENT */ #ifdef TEST_PRINTF_FORMATS #define skStreamPrint(stream, ...) printf(__VA_ARGS__) #else int skStreamPrint( skstream_t *stream, const char *format, ...); #endif /* * Perform printf()-style formatting and write the result to * 'stream'. On the first call to this funtion for 'stream', the * pager for 'stream' will be invoked if the paging program was set * and output would be to a terminal. This function requires that * 'stream' be an SK_IO_WRITE stream that has a content type of * SK_CONTENT_TEXT. * * Return SKSTREAM_OK on success, or one of the following error * codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_CLOSED * SKSTREAM_ERR_NOT_OPEN * SKSTREAM_ERR_WRITE * SKSTREAM_ERR_UNSUPPORT_IOMODE * SKSTREAM_ERR_UNSUPPORT_CONTENT */ void skStreamPrintLastErr( const skstream_t *stream, int err_code, sk_msg_fn_t err_fn); /* * Print, using the function pointed to by err_fn, a description of * the last error that occured on 'stream', where 'err_code' is the * return code that a function returned. 'stream' may be NULL. */ ssize_t skStreamRead( skstream_t *stream, void *buf, size_t count); /* * Attempt to read 'count' bytes from 'stream', putting the data * into 'buf'. Return the number of bytes actually read, 0 for end * of file, and -1 on error. * * The function will use a buffered reader, gzread(), or raw read() * as appropriate. For a raw read(), the function continue to call * read() until it has read 'count' bytes or read() returns 0 or * -1. */ int skStreamReadSilkHeader( skstream_t *stream, void *hdr, size_t hdr_size); /* * Attempt to read 'hdr_size' bytes from 'stream', putting the data * into 'hdr'. If fewer than 'hdr_size' bytes are read, return * SKSTREAM_ERR_READ. This function requires that 'stream' contain * SK_CONTENT_SILK and that it's mode be either SK_IO_READ or * SK_IO_APPEND. * * An attempt to read the header multiple times will result in * SKSTREAM_ERR_PREV_DATA. * * Return SKSTREAM_OK on success, or one of the following error * codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_CLOSED * SKSTREAM_ERR_NOT_OPEN * SKSTREAM_ERR_READ * SKSTREAM_ERR_ALLOC * SKSTREAM_ERR_PREV_DATA * SKSTREAM_ERR_BAD_MAGIC * SKSTREAM_ERR_UNSUPPORT_IOMODE * SKSTREAM_ERR_UNSUPPORT_CONTENT */ int skStreamSetByteOrder( skstream_t *stream, silk_endian_t byte_order); /* * Set the byte order for the data on 'stream' to 'byte_order. * This function requires that 'stream' be an SK_IO_WRITE stream * that contains SK_CONTENT_SILK. Return SKSTREAM_OK on success, * or one of the following error codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_UNSUPPORT_CONTENT * SKSTREAM_ERR_UNSUPPORT_IOMODE */ int skStreamSetCommentStart( skstream_t *stream, char *comment_start); /* * Set the comment string for a textual input file to * 'comment_start'. This function requires that 'stream' be an * SK_IO_READ stream that contains SK_CONTENT_TEXT. Return * SKSTREAM_OK on success, or one of the following error codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_ALLOC * SKSTREAM_ERR_UNSUPPORT_CONTENT * SKSTREAM_ERR_UNSUPPORT_IOMODE */ int skStreamSetCompressionMethod( skstream_t *stream, uint8_t comp_method); /* * Set the compression mode for 'stream' to 'comp_method.' This * function requires that 'stream' be an SK_IO_WRITE stream that * contains SK_CONTENT_SILK. Return SKSTREAM_OK on success, or one * of the following error codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_INVALID_INPUT * SKSTREAM_ERR_UNSUPPORT_CONTENT * SKSTREAM_ERR_UNSUPPORT_IOMODE * SKSTREAM_ERR_UNSUPPORT_COMPRESS */ int skStreamSetSilkFormat( skstream_t *stream, fileFormat_t file_format); /* * Set the file output format for 'stream' to 'file_format'. This * function requires that 'stream' be an SK_IO_WRITE stream that * contains SK_CONTENT_SILK. Return SKSTREAM_OK on success, or one * of the following error codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_INVALID_INPUT * SKSTREAM_ERR_UNSUPPORT_CONTENT * SKSTREAM_ERR_UNSUPPORT_IOMODE */ int skStreamSetSilkVersion( skstream_t *stream, fileVersion_t version); /* * Set the version of the file output format for 'stream' to * 'version'. This function requires that 'stream' be an * SK_IO_WRITE stream that contains SK_CONTENT_SILK. Return * SKSTREAM_OK on success, or one of the following error codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_UNSUPPORT_CONTENT * SKSTREAM_ERR_UNSUPPORT_IOMODE */ int skStreamUnbind( skstream_t *stream); /* * Closes the stream at 'stream', if open, and unbinds the stream * from the filename. If 'stream' is NULL, no action is taken and * the function returns. Return SKSTREAM_OK on success, or any of * the error codes listed by skStreamClose(). * * Currently, a stream cannot be re-bound, so this function is of * limited utility. */ ssize_t skStreamWrite( skstream_t *stream, const void *buf, size_t count); /* * Attempt to write 'count' bytes from 'buf' to 'stream'. Return * the number of bytes actually written or -1 on error. * * The function will use a buffered writer, gzwrite(), or raw * write() as appropriate. For a raw write(), the function * continue to call write() until it has written 'count' bytes or * write() returns -1. */ int skStreamWriteSilkHeader( skstream_t *stream, void *hdr, size_t hdr_size); /* * Attempt to write 'hdr_size' bytes from 'buf' to 'stream', with * the following caveat: the first eight bytes of 'hdr' will be * modified to contain the SiLK magic file number, and the values * that were specified in the calls to skStreamSetByteOrder(), * skStreamSetSilkFormat(), skStreamSetSilkVersion(), and * skStreamSetCompressionMethod(). * * If 'hdr' is shorter than eight bytes, return * SKSTREAM_ERR_INVALID_INPUT. If fewer than 'hdr_size' bytes were * written, return SKSTREAM_ERR_WRITE. This function requires that * 'stream' be an SK_IO_WRITE stream containing SK_CONTENT_SILK. * * An attempt to write the header multiple times will result in * SKSTREAM_ERR_PREV_DATA. * * Return SKSTREAM_OK on success, or one of the following error * codes: * * SKSTREAM_ERR_NULL_ARGUMENT * SKSTREAM_ERR_CLOSED * SKSTREAM_ERR_NOT_OPEN * SKSTREAM_ERR_INVALID_INPUT * SKSTREAM_ERR_WRITE * SKSTREAM_ERR_ALLOC * SKSTREAM_ERR_PREV_DATA * SKSTREAM_ERR_UNSUPPORT_IOMODE * SKSTREAM_ERR_UNSUPPORT_CONTENT */ #endif /* _SKSTREAM_H */ /* ** Local Variables: ** mode:c ** indent-tabs-mode:nil ** c-basic-offset:4 ** End: */