/**
 * @file libcomprex/fp.h File Pointers
 * 
 * $Id: fp.h,v 1.6 2003/01/12 07:19:08 chipx86 Exp $
 *
 * @Copyright (C) 2001-2003 The GNUpdate Project.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 */
#ifndef _LIBCOMPREX_FP_H_
#define _LIBCOMPREX_FP_H_

#ifdef __cplusplus
extern "C" {
#endif

typedef struct _CxFP CxFP; /**< A file pointer. */

/**
 * A file pointer.
 */
struct _CxFP
{
	CxFile *file;            /**< The associated file.              */
	CxArchive *archive;      /**< The associated archive, if any.   */

	CxAccessMode accessMode; /**< The file access mode.             */

	long pos;                /**< The current position in the file. */

	int eof;                 /**< The EOF status.                   */

	int error;               /**< The current error.                */
	char *errStr;            /**< The error string.                 */

	void *moduleData;        /**< Module-specific data.             */

	unsigned int refCount;   /**< The reference count.              */

	struct
	{
		/**
		 * The read function.
		 */
		size_t (*read)(void *ptr, size_t size, size_t nmemb, CxFP *fp);

		/**
		 * The write function.
		 */
		size_t (*write)(const void *ptr, size_t size, size_t nmemb,
						CxFP *fp);

		/**
		 * The seek function.
		 */
		void (*seek)(CxFP *fp, long offset, int whence);

		/**
		 * The rewind function.
		 */
		void (*rewind)(CxFP *fp);

		/**
		 * The close function.
		 */
		void (*close)(CxFP *fp);

	} ops;
};

/**
 * Creates a file pointer structure.
 * 
 * @return A new file pointer structure.
 *
 * @see cxClose()
 */
CxFP *cxNewFp(void);

/**
 * Sets the access mode of the specified file pointer.
 *
 * @param fp   The file pointer.
 * @param mode The access mode.
 *
 * @see cxGetFpAccessMode()
 */
void cxSetFpAccessMode(CxFP *fp, CxAccessMode mode);

/**
 * Sets the read function for this file pointer.
 *
 * This should work just like libc's fread() function, but with a CxFP
 * instead of a FILE. It must read from the file stored in the archive.
 *
 * This function must be in the following format:
 *
 * @code
 * size_t readFunction(void *ptr, size_t size, size_t nmemb, CxFP *fp)
 * {
 *     ...
 * }
 * @endcode
 *
 * The name of the function can be changed, of course.
 * 
 * @param fp  The file pointer.
 * @param fnc The read function.
 *
 * @see cxSetCloseFunc()
 * @see cxSetSeekFunc()
 * @see cxSetWriteFunc()
 */
void cxSetReadFunc(CxFP *fp, size_t (*fnc)(void *, size_t, size_t, CxFP *));

/**
 * Sets the write function for this file pointer.
 *
 * This should work just like libc's fwrite() function, but with a CxFP
 * instead of a FILE. It must write to the file stored in the archive.
 *
 * This function must be in the following format:
 *
 * @code
 * size_t writeFunction(const void *ptr, size_t size, size_t nmemb, CxFP *fp)
 * {
 *     ...
 * }
 * @endcode
 *
 * The name of the function can be changed, of course.
 * 
 * @param fp  The file pointer.
 * @param fnc The write function.
 *
 * @see cxSetCloseFunc()
 * @see cxSetReadFunc()
 * @see cxSetSeekFunc()
 */
void cxSetWriteFunc(CxFP *fp, size_t (*fnc)(const void *, size_t, size_t,
											CxFP *));

/**
 * Sets the seek function for this file pointer.
 *
 * This should work just like libc's fseek() function, but with a CxFP
 * instead of a FILE. It must seek to the specified location in the file.
 *
 * This function must be in the following format:
 *
 * @code
 * void seekFunction(CxFP *fp, long offset, int whence)
 * {
 *     ...
 * }
 * @endcode
 *
 * The name of the function can be changed, of course.
 * 
 * @param fp  The file pointer.
 * @param fnc The seek function.
 *
 * @see cxSetCloseFunc()
 * @see cxSetReadFunc()
 * @see cxSetWriteFunc()
 */
void cxSetSeekFunc(CxFP *fp, void (*fnc)(CxFP *, long, int));

/**
 * Sets the close function for this file pointer.
 *
 * This should destroy the module-specific content associated with this
 * file pointer in the @c moduleData variable.
 *
 * This function must be in the following format:
 *
 * @code
 * void closeFunction(CxFP *fp)
 * {
 *     ...
 * }
 * @endcode
 *
 * The name of the function can be changed, of course.
 * 
 * @param fp  The file pointer.
 * @param fnc The close function.
 *
 * @see cxSetReadFunc()
 * @see cxSetSeekFunc()
 * @see cxSetWriteFunc()
 */
void cxSetCloseFunc(CxFP *fp, void (*fnc)(CxFP *));

/**
 * Sets the current error number and string.
 *
 * @param fp     The file pointer.
 * @param errnum The error number.
 * @param errstr The error string.
 */
void cxSetError(CxFP *fp, int errnum, const char *errstr);

/**
 * Returns the access mode of the specified file pointer.
 *
 * @param fp The file pointer.
 *
 * @return The file's access mode.
 * 
 * @see cxSetFpAccessMode()
 */
CxAccessMode cxGetFpAccessMode(CxFP *fp);

#ifdef __cplusplus
}
#endif

#endif /* _LIBCOMPREX_FP_H_ */
