1
0
forked from 0ad/0ad
0ad/source/lib/res/file.h
janwas 94316413db rough initial implementation of revised L3 file block cache. works, considerable speedup.
also: async routines now fill a control block, instead of returning a
handle (that's now done by VFS)

This was SVN commit r1001.
2004-08-15 21:50:29 +00:00

169 lines
4.8 KiB
C
Executable File

// file layer on top of POSIX.
// provides streaming support and caching.
//
// Copyright (c) 2004 Jan Wassenberg
//
// This file is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This file 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
// General Public License for more details.
//
// Contact info:
// Jan.Wassenberg@stud.uni-karlsruhe.de
// http://www.stud.uni-karlsruhe.de/~urkt/
#ifndef FILE_H
#define FILE_H
struct File
{
#ifdef PARANOIA
u32 magic;
#endif
// keep offset of flags and size members in sync with struct ZFile!
// it is accessed by VFS and must be the same for both (union).
// dirty, but necessary because VFile is pushing the HDATA size limit.
uint flags;
off_t size;
u32 fn_hash;
void* mapping;
uint map_refs;
int fd;
};
enum
{
// write-only access; otherwise, read only
FILE_WRITE = 0x01,
// the file's contents aren't cached at a higher level; do so here.
// we keep the file open (until the cache is "full enough"). if it
// is loaded, we keep the buffer there to satisfy later loads.
FILE_CACHE = 0x04,
// random access hint
// FILE_RANDOM = 0x08,
FILE_NO_AIO = 0x10,
FILE_CACHE_BLOCK = 0x20
};
// convert to/from our portable path representation,
// e.g. for external libraries that require the real filename.
// note: also removes/adds current directory.
extern int file_make_native_path(const char* path, char* n_path);
extern int file_make_portable_path(const char* n_path, char* path);
// set current directory to rel_path, relative to the path to the executable,
// which is taken from argv0.
//
// example: executable in "$install_dir/system"; desired root dir is
// "$install_dir/data" => rel_path = "../data".
//
// this is necessary because the current directory is unknown at startup
// (e.g. it isn't set when invoked via batch file), and this is the
// easiest portable way to find our install directory.
//
// can only be called once, by design (see source). rel_path is trusted.
extern int file_rel_chdir(const char* argv0, const char* rel_path);
// called for each entry in a directory.
// name is the complete path (see below); it's a directory iff size < 0.
typedef int(*FileCB)(const char* const name, const ssize_t size, const uintptr_t user);
// for all files and dirs in <dir> (but not its subdirs!):
// call <cb>, passing <user> and the entries's name (not path!)
extern int file_enum(const char* dir, FileCB cb, uintptr_t user);
extern int file_stat(const char* path, struct stat*);
extern int file_open(const char* fn, uint flags, File* f);
extern int file_close(File* f);
//
// memory mapping
//
// map the entire file <f> into memory. if already currently mapped,
// return the previous mapping (reference-counted).
// output parameters are zeroed on failure.
//
// the mapping will be removed (if still open) when its file is closed.
// however, map/unmap calls should still be paired so that the mapping
// may be removed when no longer needed.
//
// rationale: reference counting is required for zip_map: several
// Zip "mappings" each reference one ZArchive's actual file mapping.
// implement it here so that we also get refcounting for normal files.
extern int file_map(File* f, void*& p, size_t& size);
// decrement the reference count for the mapping belonging to file <f>.
// fail if there are no references; remove the mapping if the count reaches 0.
//
// the mapping will be removed (if still open) when its file is closed.
// however, map/unmap calls should still be paired so that the mapping
// may be removed when no longer needed.
extern int file_unmap(File* f);
//
// async IO
//
struct FileIO
{
u64 block_id;
// set by file_start_io when in block-cache mode, otherwise 0.
aiocb* cb;
// large (144 bytes) on Linux; cannot store here.
// allocated in file_start_io.
size_t padding;
size_t user_size;
bool our_buf;
bool from_cache;
bool given_to_cache;
bool return_called;
};
extern int file_start_io(File* f, off_t ofs, size_t size, void* buf, FileIO* io);
// indicates if the given IO has completed.
// return value: 0 if pending, 1 if complete, < 0 on error.
extern int file_io_complete(FileIO* io);
extern int file_wait_io(FileIO* io, void*& p, size_t& size);
extern int file_discard_io(FileIO* io);
// return value:
// < 0: failed; abort transfer.
// >= 0: bytes output; continue.
typedef ssize_t(*FileIOCB)(uintptr_t ctx, void* p, size_t size);
extern ssize_t file_io(File* f, off_t ofs, size_t size, void** p, FileIOCB cb = 0, uintptr_t ctx = 0);
#endif // #ifndef FILE_H