/*
** 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:
*/
