#ifndef INCLUDED_READ_H
#define INCLUDED_READ_H
/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */
/*======================================================================
Copyright (C) 2004,2005,2009 Walter Doekes <walter+tthsum@wjd.nu>
This file is part of tthsum.

tthsum 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 3 of the License, or
(at your option) any later version.

tthsum 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 tthsum.  If not, see <http://www.gnu.org/licenses/>.
======================================================================*/

/**
 * Functions to read streams of data, usually from files. It exposes
 * an opaque rofile struct that you can pass around without having to
 * worry about what type of thing it is you're reading. Features: the
 * read operations guarantee to return multiples of 1024 bytes, except
 * for the last read (at EOF).
 */

#include "types.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * The read-only file stream object, forward declaration of opaque object.
 */
struct rofile;

/**
 * Construct a rofile object from in-memory data.
 */
struct rofile* rofopen_mem(const char* data, unsigned length);

/**
 * Construct a rofile object from a file. The reads will use native memory
 * map functions.
 */
struct rofile* rofopen_mmap(const char* filename);

/**
 * Construct a rofile object from an open file descriptor. The reads will use
 * the read(2) syscall.
 */
struct rofile* rofopen_sysfd(int fd);

/**
 * A shortcut to rofopen_sysfd which opens stdin.
 */
struct rofile* rofopen_sysfd_stdin();

/**
 * Construct a rofile object from a file. The reads will use the read(2)
 * syscall.
 */
struct rofile* rofopen_sysfile(const char* filename);

/**
 * Get info from the rofile struct. The blocksize specifies the sizes you'll
 * get with rofread, except for the last read.
 */
void rofinfo(unsigned* blocksize, uint64_t* filesize, struct rofile* stream);

/**
 * Get the next block of data. Returns 1 when there is data, 0 when there is
 * not and -1 if an error occurred. rofread will _always_ return blocksize
 * data, unless the file reaches EOF.
 */
int rofread(const char** next, unsigned* size, struct rofile* stream);

/**
 * Close the file opened with one of the rofopen functions.
 */
void rofclose(struct rofile* stream);

/**
 * Read the entire contents of the rofile and close it afterwards. Returns the
 * contents as a malloc'ed string or NULL on failure. It will accept a NULL as
 * argument so you can safely use one of the rofopen functions as argument.
 */
char* rof_readall(struct rofile* stream, unsigned* length);

#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */

#endif /* INCLUDED_READ_H */
