#ifndef	ACL_FILE_INCLUDE_H
#define	ACL_FILE_INCLUDE_H

#include "acl_define.h"
#include "acl_vstream.h"
#include <stdarg.h>

#ifdef	__cplusplus
extern "C" {
#endif

/**
 * ļͶ
 */
typedef struct ACL_FILE {
	ACL_VSTREAM *fp;	/**< ָ */
	unsigned int status;	/**< ļ״̬ */
#define	ACL_FILE_EOF		(1 << 0)
	int   errnum;		/**< ļĳ */
} ACL_FILE;

#define	ACL_FPATH(fp)	ACL_VSTREAM_PATH((fp)->fp)
#define	ACL_FSTREAM(fp)	((fp)->fp)

/**
 * 򿪻򴴽һļжд
 * @param filename {const char*} ļ
 * @param mode {const char*} 򿪱־.
 *  r or rb: ֻʽѾļ
 *  w or wb: ֻдʽѴļջֻдʽļ
 *  a or ab: βֻдʽѴļ򴴽ļ
 *  r+ or rb+: ԶдʽѴļ
 *  w+ or wb+: ԶдʽѴļջ򴴽ļ
 *  a+ or ab+: βӶдʽѴļ򴴽ļ
 */
ACL_API ACL_FILE *acl_fopen(const char *filename, const char *mode);

/**
 * رһļ
 * @param fp {ACL_FILE*} ļ
 */
ACL_API int acl_fclose(ACL_FILE *fp);

/**
 * ļĴ
 * @param fp {ACL_FILE*} ļ
 */
ACL_API void acl_clearerr(ACL_FILE *fp);

/**
 * жǷ񵽴ļβ
 * @param fp {ACL_FILE*} ļ
 * @return {int} 0: ; !0: 
 */
ACL_API int acl_feof(ACL_FILE *fp);

/**
 * ļжȡһЩ̶ȵݿ
 * @param buf {void*} ڴ滺ַ
 * @param size {size_t} ÿݿ鳤
 * @param nitems {size_t} ݿ
 * @param fp {ACL_FILE*} ļ
 * @return {size_t} ݿ, 򷵻 EOF
 */
ACL_API size_t acl_fread(void *buf, size_t size, size_t nitems, ACL_FILE *fp);

/**
 * ļжȡһ
 * @param buf {char*} ַ
 * @param size {int} buf ռС
 * @param fp {ACL_FILE*} ļ
 * @return {char*} NULL: δ; !NULL: 
 */
ACL_API char *acl_fgets(char *buf, int size, ACL_FILE *fp);

/**
 * ļжȡһݣصβ "\r\n"
 * @param buf {char*} ַ
 * @param size {int} buf ռС
 * @param fp {ACL_FILE*} ļ
 * @return {char*} NULL: δ; !NULL: 
 */
ACL_API char *acl_fgets_nonl(char *buf, int size, ACL_FILE *fp);

/**
 * ļжȡһַ
 * @param fp {ACL_FILE*} ļ
 * @return {int} EOF: ļβ; !EOF: ȷһַ ASCII 
 */
ACL_API int acl_fgetc(ACL_FILE *fp);
#define	acl_getc	acl_fgetc

/**
 * ӱ׼жȡһ
 * @param buf {char*} ַ
 * @param size {int} buf ռС
 * @return {char*} NULL: ; !NULL: Ӧ buf ַͬ
 */
ACL_API char *acl_gets(char *buf, size_t size);

/**
 * ӱ׼жȡһ, β "\r\n"
 * @param buf {char*} ַ
 * @param size {int} buf ռС
 * @return {char*} NULL: ; !NULL: Ӧ buf ַͬ
 */
ACL_API char *acl_gets_nonl(char *buf, size_t size);

/**
 * ӱ׼жȡһַ
 * @return {int} EOF: ļβ; !EOF: ȷһַ ASCII 
 */
ACL_API int acl_getchar(void);

/**
 * ļдθʽ
 * @param fp {ACL_FILE*} ļ
 * @param fmt {const char*} θʽ
 * @param ... 
 * @return {size_t} ݳ, 򷵻 EOF
 */
ACL_API int ACL_PRINTF(2, 3) acl_fprintf(ACL_FILE *fp, const char *fmt, ...);

/**
 * ļдθʽ
 * @param fp {ACL_FILE*} ļ
 * @param fmt {const char*} θʽ
 * @param ap {va_list} б
 * @return {size_t} ݳ, 򷵻 EOF
 */
ACL_API int acl_vfprintf(ACL_FILE *fp, const char *fmt, va_list ap);

/**
 * ļдһЩ̶ȵݿ
 * @param ptr {const void*} ݵַ
 * @param size {size_t} ÿݿ鳤
 * @param nitems {size_t} ݿ
 * @param fp {ACL_FILE*} ļָ
 * @return {size_t} ݿ, 򷵻 EOF
 */
ACL_API size_t acl_fwrite(const void *ptr, size_t size, size_t nitems, ACL_FILE *fp);

/**
 * ļдݲԶβ "\r\n"
 * @param s {const char*} ַַ
 * @param fp {ACL_FILE*} ļָ
 * @return {int} д( "\r\n"), 򷵻 EOF
 */
ACL_API int acl_fputs(const char *s, ACL_FILE *fp);

/**
 * ׼дθʽ
 * @param fmt {const char*} θʽ
 * @param ... 
 * @return {size_t} ݳ, 򷵻 EOF
 */
ACL_API int ACL_PRINTF(1, 2) acl_printf(const char *fmt, ...);

/**
 * ׼дθʽ
 * @param fmt {const char*} θʽ
 * @param ap {va_list} б
 * @return {size_t} ݳ, 򷵻 EOF
 */
ACL_API int acl_vprintf(const char *fmt, va_list ap);

/**
 * ļдһֽ
 * @param c {int} һ ASCII 
 * @param fp {ACL_FILE*} ļָ
 * @return {int} д, 򷵻 EOF
 */
ACL_API int acl_putc(int c, ACL_FILE *fp);
#define	acl_fputc	acl_putc

/**
 * ׼дݲԶβ "\r\n"
 * @param s {const char*} ַַ
 * @return {int} д( "\r\n"), 򷵻 EOF
 */
ACL_API int acl_puts(const char *s);

/**
 * ļдһֽ
 * @param c {int} һ ASCII 
 * @return {int} д, 򷵻 EOF
 */
ACL_API int acl_putchar(int c);

/**
 * λļλ
 * @param fp {ACL_FILE*} ļ
 * @param offset {acl_off_t} ƫλ
 * @param whence {int} ƫƷ, SEEK_SET, SEEK_CUR, SEEK_END
 * @return ret {acl_off_t}, ret >= 0: ȷ, ret < 0: 
 */
ACL_API acl_off_t acl_fseek(ACL_FILE *fp, acl_off_t offset, int whence);

/**
 * õǰļָļеλ
 * @param fp {ACL_FILE*} ļ
 * @return {acl_off_t} ֵ -1 ʾ
 */
ACL_API acl_off_t acl_ftell(ACL_FILE *fp);

#ifdef	__cplusplus
}
#endif

#endif
