#ifndef	VFS_CAT_H
#define VFS_CAT_H

#include <../arch/arch.h>
#include <../source/TAL/objbase.h>
#include <../source/vfs/iobase.h>
#include <../source/vfs/mbase.h>
#include <../source/vfs/fsbase.h>

/*
 * Generic data types for concatenated files.
 */

/*
 * Directory entry
 */
typedef struct vfs_dentry_s
{
	u32_t	pos;	/* position in concatenated file */
	u32_t	len;	/* length of data block */
	/*
	 * Name of block is variable sized; never use sizeof(vfs_dentry_t).
	 * Instead, use VFS_DENTRY_SIZE and VFS_DENTRY macros.
	 */
	char	name[14];
}	vfs_dentry_t, *vfs_dentry_p;

/*
 * Filesystem object
 */
typedef  struct vfs_catfs_s
{
	vfs_dev_t		vtbl;
	vhandle_t			dhandle;
	mutex_t			dhandle_lock;
	u8_t			*base; 			/* used if stream can be mmap()ed */
	char			volume_name[_MAX_PATH];
	u32_t			num_dentries;	/* directory size */
	u32_t			dentry_size;	/* size of each dentry */
	void_p			dir;			/* directory */
}	vfs_catfs_t, *vfs_catfs_p;

/*
 * File object: normal I/O via duplicate of local file handle.
 */
typedef struct vfs_catfs_bigport_s
{
	ioport_base_t	vtbl;
	vhandle_t		dhandle;	/* duplicate of fs->dhandle */
#if 0
	arch_vhandle_t		ahandle;	/* arch-specific handle for 'dhandle' */
#endif
	vfs_dentry_t	*dentry;
	u32_t			current_pos;
}	vfs_catfs_bigport_t, *vfs_catfs_bigport_p;

/*
 * File object: memory-mapped I/O
 */
typedef struct vfs_mapport_s
{
	io_section_t	section;
	u32_t 			(V_CALL	*inherited_destroy)(vhandle_t handle);
	vfs_dev_p		volume;		/* volume to decrement ref_count */
}	vfs_mapport_t, *vfs_mapport_p;

#define VFS_DENTRY_SIZE(name_chars) ((sizeof(u32_t)<<1) + (name_chars))

#define	VFS_DENTRY(base,index,dentry_size) \
		((vfs_dentry_p)(((u8_t*)(base)) + (index)*(dentry_size)))

/*
#define	VFS_ALLOC_DENTRIES(out,num_entries,name_chars) { \
		u32_t dir_len = num_entries * (2 * sizeof(u32_t) + name_chars); \
		out = (void*)memAlloc(dir_len); \
		memZero(out,dir_len); }
*/

#ifdef __cplusplus
extern "C" {
#endif	/* __cplusplus */
	/*
	 * Creates IO port for memory-mapped I/O. Increments volume's
	 * reference counter.
	 */
	vfs_mapport_p	V_CALL	vfsCreateMPort(vfs_dev_p volume,
		u32_t extra_memory,void *base,u32_t len);
	/*
	 * FS-specific directory must be read in after calling this routine.
	 * No more actions necessary.
	 * First parameter - 'in_stream' - used to mmap input space. File
	 * pointer can be in any place at time of call.
	 */
	vfs_catfs_p	V_CALL	vfsCreateCatFS(vhandle_t in_stream,
		u32_t num_dentries, u32_t name_maxlen);
#ifdef __cplusplus
}
#endif	/* __cplusplus */

#endif /* VFS_CAT_H */
