#ifndef ACL_ARGV_INCLUDE_H
#define ACL_ARGV_INCLUDE_H

# ifdef	__cplusplus
extern "C" {
# endif
#include "acl_define.h"
//#include <stdarg.h>
#include "acl_dbuf_pool.h"
#include "acl_iterator.h"

#define ACL_ARGV_END	((char *) 0)

/**
 * External interface.
 */
typedef struct ACL_ARGV ACL_ARGV;

struct ACL_ARGV {
	int     len;			/**< number of array elements */
	int     argc;			/**< array elements in use */
	char  **argv;			/**< string array */

	/* Ӽ */

	/* βַ (ڲַ̬) */
	void  (*push_back)(ACL_ARGV*, const char*);
	/* ͷӶ̬ (ڲַ̬)*/
	void  (*push_front)(ACL_ARGV*, const char*);
	/* βַ ( acl_myfree ͷ) */
	char *(*pop_back)(ACL_ARGV*);
	/* ͷַ ( acl_myfree ͷ) */
	char *(*pop_front)(ACL_ARGV*);

	/* for acl_iterator */

	/* ȡͷ */
	void *(*iter_head)(ACL_ITER*, const ACL_ARGV*);
	/* ȡһ */
	void *(*iter_next)(ACL_ITER*, const ACL_ARGV*);
	/* ȡβ */
	void *(*iter_tail)(ACL_ITER*, const ACL_ARGV*);
	/* ȡһ */
	void *(*iter_prev)(ACL_ITER*, const ACL_ARGV*);

	/* private */
	ACL_DBUF_POOL *dbuf;
};

/* in acl_argv.c */
/**
 * һַ̬
 * @param size {int} ̬ĳʼС
 * @return {ACL_ARGV*}
 */
ACL_API ACL_ARGV *acl_argv_alloc(int size);
ACL_API ACL_ARGV *acl_argv_alloc2(int size, ACL_DBUF_POOL *dbuf);

/**
 *  ACL_ARGV ı
 * @param argvp {ACL_ARGV*}
 */
ACL_API void acl_argv_iter_init(ACL_ARGV *argvp);

ACL_API void *acl_argv_iter_head(ACL_ITER *iter, const ACL_ARGV *argv);
ACL_API void *acl_argv_iter_next(ACL_ITER *iter, const ACL_ARGV *argv);
ACL_API void *acl_argv_iter_tail(ACL_ITER *iter, const ACL_ARGV *argv);
ACL_API void *acl_argv_iter_prev(ACL_ITER *iter, const ACL_ARGV *argv);

/**
 * ַ̬һַһNULLַʾ
 * @param argvp {ACL_ARGV*} ַָ̬
 * @param ... ַбһΪNULL, ʽ磺{s1}, {s2}, ..., NULL
 */
ACL_API void acl_argv_add(ACL_ARGV *argvp,...);

/**
 * ָλַָͬʱͷžɵַ
 * @param argvp {ACL_ARGV *} ַ̬
 * @param idx {int} ָ±λãӦԽ
 * @param value {const char *}  NULL ַ
 * @return {int}  -1 ʾ±Խ value Ϊ NULL0 ʾɹ
 */
ACL_API int acl_argv_set(const ACL_ARGV *argvp, int idx, const char *value);

/**
 * ַַ̬б
 * @param argvp {ACL_ARGV*} ַָ̬
 * @param ap {va_list} ɶַɵıб
 */
ACL_API void acl_argv_addv(ACL_ARGV *argvp, va_list ap);

/**
 * ֶַ̬γƵַб
 * @param argvp {ACL_ARGV*} ַָ̬
 * @param ... һгƵַб
 *  : {s1}, {len1}, {s2}, {len2}, ... NULL
 */
ACL_API void acl_argv_addn(ACL_ARGV *argvp,...);

/**
 * ֶַ̬γƵַб
 * @param argvp {ACL_ARGV*} ַָ̬
 * @param ap {va_list} һгƵַɵıб
 */
ACL_API void acl_argv_addnv(ACL_ARGV *argvp, va_list ap);

/**
 * ַ̬Ľλ
 * @param argvp {ACL_ARGV*} ַָ̬
 */
ACL_API void acl_argv_terminate(const ACL_ARGV *argvp);

/**
 * ͷַ̬
 * @param argvp {ACL_ARGV*} ַָ̬
 */
ACL_API void acl_argv_free(ACL_ARGV *argvp);

/**
 * ±λ÷Ӧַָ
 * @param argvp {ACL_ARGV*} ַָ̬
 * @param idx {int} ±λ
 * @return {char*} NULL: ±Խ磻!= NULL: ַָλ
 */
ACL_API char *acl_argv_index(const ACL_ARGV *argvp, int idx);

/**
 * صǰַ̬Ѿŵַ
 * @param argvp {ACL_ARGV*} ַָ̬
 * @return {int}
 */
ACL_API int acl_argv_size(const ACL_ARGV *argvp);

/* in acl_argv_split.c */
/**
 * Դַַָһַ̬
 * @param str {const char*} Դַ
 * @param delim {const char*} ַָ
 * @return {ACL_ARGV*}
 */
ACL_API ACL_ARGV *acl_argv_split(const char *str, const char *delim);

/**
 * Դַַָһַ̬飬ͬʱڴ
 * Ϊڴ
 * @param str {const char*} Դַ
 * @param delim {const char*} ַָ
 * @param dbuf {ACL_DBUF_POOL*} ڴض󣬿ΪգΪʱ
 *  ȱʡڴ䷽ʽ
 * @return {ACL_ARGV*}
 */
ACL_API ACL_ARGV *acl_argv_split3(const char *str, const char *delim,
	ACL_DBUF_POOL *dbuf);

/**
 * Դַַָһַ̬, ޶ָ
 * @param str {const char*} Դַ
 * @param delim {const char*} ַָ
 * @param n {size_t} ָ
 * @return {ACL_ARGV*}
 */
ACL_API ACL_ARGV *acl_argv_splitn(const char *str, const char *delim, size_t n);

/**
 * Դַַָһַ̬, ޶ָ
 * ͬʱڴضΪڴ
 * @param str {const char*} Դַ
 * @param delim {const char*} ַָ
 * @param n {size_t} ָ
 * @param dbuf {ACL_DBUF_POOL*} ڴض󣬿ΪգΪʱ
 *  ȱʡڴ䷽ʽ
 * @return {ACL_ARGV*}
 */
ACL_API ACL_ARGV *acl_argv_splitn4(const char *str, const char *delim,
	size_t n, ACL_DBUF_POOL *dbuf);

/**
 * Դַָֽһַ̬
 * @param argvp {ACL_ARGV*} ַָ̬
 * @param str {const char*} Դַ
 * @param delim {const char*} ַָ
 * @return {ACL_ARGV*}
 */
ACL_API ACL_ARGV *acl_argv_split_append(ACL_ARGV *argvp, const char *str,
	const char *delim);

/**
 * Դַָֽһַ̬, ޶ָ
 * @param argvp {ACL_ARGV*} ַָ̬
 * @param str {const char*} Դַ
 * @param delim {const char*} ַָ
 * @param n {size_t} ָ
 * @return {ACL_ARGV*}
 */
ACL_API ACL_ARGV *acl_argv_splitn_append(ACL_ARGV *argvp, const char *str,
	const char *delim, size_t n);

/**
 * Դַַָһַ̬飬 ""  '' õ
 * ַָ
 * @param str {const char*} Դַ
 * @param delim {const char*} ַָ
 * @return {ACL_ARGV*}
 */
ACL_API ACL_ARGV *acl_argv_quote_split(const char *str, const char *delim);

/**
 * Դַַָһַ̬飬 ""  '' õ
 * ַָнڴضΪڴ
 * @param str {const char*} Դַ
 * @param delim {const char*} ַָ
 * @param dbuf {ACL_DBUF_POOL*} ڴض󣬿ΪգΪʱ
 *  ȱʡڴ䷽ʽ
 * @return {ACL_ARGV*}
 */
ACL_API	ACL_ARGV *acl_argv_quote_split4(const char *str, const char *delim,
	ACL_DBUF_POOL *dbuf);

///////////////////////////////////////////////////////////////////////////////
// Чַָ㷨

typedef struct ACL_ARGV_VIEW ACL_ARGV_VIEW;

struct ACL_ARGV_VIEW {
	ACL_ARGV argv;

	/* ȡͷ */
	void *(*iter_head)(ACL_ITER*, const ACL_ARGV_VIEW*);
	/* ȡһ */
	void *(*iter_next)(ACL_ITER*, const ACL_ARGV_VIEW*);
	/* ȡβ */
	void *(*iter_tail)(ACL_ITER*, const ACL_ARGV_VIEW*);
	/* ȡһ */
	void *(*iter_prev)(ACL_ITER*, const ACL_ARGV_VIEW*);
};

/**
 * ʹ÷ַָеÿһַΪָԴַзָصĶֹֻ޸.
 * @param str {const char*} Դַ
 * @param delim {const char*} Դַзַַָгֵÿһ
 *  ַΪָ
 * @return {ACL_ARGV_VIEW*} ָĶԶNULLضֻ޸ģ
 *  ʹ ACL_ITER б.
 */
ACL_API ACL_ARGV_VIEW *acl_argv_view_split(const char *str, const char *delim);

/**
 *  ͷŷָ
 * @param view {ACL_ARGV_VIEW*}  acl_argv_view_split ķָ
 */
ACL_API void acl_argv_view_free(ACL_ARGV_VIEW *view);

# ifdef	__cplusplus
}
# endif

#endif
