/*
 * Class for reading data from files, with base implementations
 * for reading local filesystem files and previous session files.
 * 
 * TODO this is kept private for now, it can be useful to make that
 * public later.
 */

#ifndef FILE_SRC_H_
#define FILE_SRC_H_

#include <sys/types.h>

struct data_source;

struct iso_file_src {
	
	/**
	 * Opens the file. 
	 * This should be called before any call to read_block().
	 * @return 1 on success, <= 0 on error
	 */
	int (*open)(struct iso_file_src *src);
	
	/**
	 * Close the file.
	 * This should be called when the iso_file_src is no more needed.
	 */
	void (*close)(struct iso_file_src *src);
	
	/** 
	 * Read data from the file in 2048 bytes chunks.
	 * 
	 * A pointer to the contents of the file will be updated, in such a way
	 * that each time this function is called, new data is read to the buffer.
	 * It behaves in the same way as usual read(2) call this way.
	 * 
	 * This always reads 2048 bytes, unless an EOF is found, or we reach the
	 * size previously returned by get_size(). In this case, the buffer is 
	 * completed with 0s.
	 * 
	 * @param buffer Buffer where the data will be written. Its size must
	 *               be at least 2048 bytes.
	 * @return
	 * 		1 if file contains more data. If we reach EOF before the expected
	 *      size, this keeps returning 1, and next blocks are filled with 0s.
	 * 	    0 when we reach the expected size, that in normal usage is also EOF
	 *      on file.
	 *      < 0 on error. If such case, next calls to read_block will keep
	 *      returning < 0 until we reach the expected size, filling blocks with
	 *      0s.
	 */
	int (*read_block)(struct iso_file_src *src, unsigned char *buffer);

	/** 
	 * Get the size in bytes of the file. 
	 * 
	 * This is set when the iso_file_src is created, and should not change. If
	 * the actual file size changes, it will be truncated or padding with 0s
	 * when the block is read
	 */
	off_t (*get_size)(struct iso_file_src *);

	/** Clean up the source specific data */
	void (*free_data)(struct iso_file_src *);

	/** Source specific data */
	void *data;
	
};

/**
 * Get a iso_file_src() for reading from a local filesystem file.
 */
struct iso_file_src* iso_file_src_from_path(const char *path);

/**
 * Get a iso_file_src() for reading from a previous image file.
 * @param src data_source to read from previous image. It is not freed, 
 *            so you need to free it when no more needed.
 * @param block block on image where file begins
 * @param nblocks number of block of the file
 */
struct iso_file_src* 
iso_file_src_from_prev_img(struct data_source* src, int block, off_t size);

/**
 * free a iso_file_src
 */
void iso_file_src_free(struct iso_file_src *src);


#endif /*FILE_SRC_H_*/