/**
 * =========================================================================
 * File        : vfs_redirector.h
 * Project     : 0 A.D.
 * Description : 
 *
 * @author Jan.Wassenberg@stud.uni-karlsruhe.de
 * =========================================================================
 */

/*
 * Copyright (c) 2004-2006 Jan Wassenberg
 *
 * Redistribution and/or modification are also permitted under the
 * terms of the GNU General Public License as published by the
 * Free Software Foundation (version 2 or later, at your option).
 *
 * This program 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.
 */

#ifndef VFS_REDIRECTOR_H__
#define VFS_REDIRECTOR_H__

struct FileProvider_VTbl
{
	// FOURCC that is checked on each access to ensure this is a valid vtbl.
	u32 magic;
	// note: no need to store name of this provider for debugging purposes;
	// that can be deduced from the function pointers below.

	// directory entry enumeration
	// note: these don't really fit in with the other methods.
	// they make sense for both the VFS tree as well as the concrete
	// file providers underlying it. due to this overlap and to allow
	// file.cpp's next_ent function to access dir_filtered_next_ent,
	// it is included anyway.
	LibError (*dir_open)(const char* dir, DirIterator* di);
	LibError (*dir_next_ent)(DirIterator* di, DirEnt* ent);
	LibError (*dir_close)(DirIterator* di);

	// file objects
	LibError (*file_open)(const char* V_path, uint flags, TFile* tf, File* f);
	LibError (*file_close)(File* f);
	LibError (*file_validate)(const File* f);

	// IO
	LibError (*io_issue)(File* f, off_t ofs, size_t size, void* buf, FileIo* io);
	int      (*io_has_completed)(FileIo* io);
	LibError (*io_wait)(FileIo* io, void*& p, size_t& size);
	LibError (*io_discard)(FileIo* io);
	LibError (*io_validate)(const FileIo* io);
	ssize_t  (*io)(File* f, off_t ofs, size_t size, FileIOBuf* pbuf, FileIOCB cb, uintptr_t ctx);

	// file mapping
	LibError (*map)(File* f, void*& p, size_t& size);
	LibError (*unmap)(File* f);
};


extern LibError xdir_open(const char* dir, DirIterator* di);
extern LibError xdir_next_ent(DirIterator* di, DirEnt* ent);
extern LibError xdir_close(DirIterator* di);

extern bool     xfile_is_open(const File* f);
extern LibError xfile_open(const char* V_path, uint flags, TFile* tf, File* f);
extern LibError xfile_close(File* f);
extern LibError xfile_validate(const File* f);

extern LibError xfile_io_issue(File* f, off_t ofs, size_t size, void* buf, FileIo* io);
extern int      xfile_io_has_completed(FileIo* io);
extern LibError xfile_io_wait(FileIo* io, void*& p, size_t& size);
extern LibError xfile_io_discard(FileIo* io);
extern LibError xfile_io_validate(const FileIo* io);
extern ssize_t  xfile_io(File* f, off_t ofs, size_t size, FileIOBuf* pbuf, FileIOCB cb, uintptr_t ctx);

extern LibError xfile_map(File* f, void*& p, size_t& size);
extern LibError xfile_unmap(File* f);

#endif	//	#ifndef VFS_REDIRECTOR_H__
