This Trac instance is not used for development anymore!

We migrated our development workflow to git and Gitea.
To test the future redirection, replace trac by ariadne in the page URL.

Changeset 385 for ps


Ignore:
Timestamp:
06/03/04 15:57:00 (21 years ago)
Author:
janwas
Message:

documentation! w00t

Location:
ps/trunk/source/lib/res
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • ps/trunk/source/lib/res/vfs.cpp

    r373 r385  
    689689
    690690
     691// mount either a single archive or a directory into the VFS at
     692// <vfs_mount_point>, which is created if it does not yet exist.
     693// new files override the previous VFS contents if pri(ority) is higher.
     694// if <name> is a directory, all archives in that directory (but not
     695// its subdirs - see add_dirent_cb) are also mounted in alphabetical order.
     696// name = "." or "./" isn't allowed - see implementation for rationale.
    691697int vfs_mount(const char* const vfs_mount_point, const char* const name, const uint pri)
    692698{
     
    701707        }
    702708
     709    CHECK_PATH(name);
     710
     711    // TODO: disallow mounting parent directory of a previous mounting
     712
    703713    // disallow . because "./" isn't supported on Windows.
    704714    // the more important reason is that mount points must not overlap
     
    719729
    720730
     731// rebuild the VFS, i.e. re-mount everything. open files are not affected.
     732// necessary after loose files or directories change, so that the VFS
     733// "notices" the changes and updates file locations. res calls this after
     734// FAM reports changes; can also be called from the console after a
     735// rebuild command. there is no provision for updating single VFS dirs -
     736// it's not worth the trouble.
    721737int vfs_rebuild()
    722738{
     
    729745
    730746
     747// unmount a previously mounted item, and rebuild the VFS afterwards.
    731748int vfs_unmount(const char* name)
    732749{
     
    753770
    754771
    755 int vfs_realpath(const char* fn, char* full_path)
    756 {
    757     const FileLoc* loc;
    758     CHECK_ERR(tree_lookup(fn, &loc));
    759 
    760     if(loc->archive > 0)
    761     {
    762         const char* archive_fn = h_filename(loc->archive);
    763         if(!archive_fn)
    764             return -1;
    765         strncpy(full_path, archive_fn, PATH_MAX);
    766     }
    767     else
    768     {
    769         strncpy(full_path, loc->dir.c_str(), PATH_MAX);
    770     }
    771 
    772     return 0;
    773 }
    774 
    775 
    776 int vfs_stat(const char* fn, struct stat* s)
    777 {
    778     const FileLoc* loc;
    779     CHECK_ERR(tree_lookup(fn, &loc));
    780 
    781     if(loc->archive > 0)
    782         return zip_stat(loc->archive, fn, s);
    783     else
    784     {
    785         const char* dir = loc->dir.c_str();
    786         return file_stat(dir, s);
    787     }
    788 }
    789 
    790 
    791772struct VDir
    792773{
    793774    // we need to cache the complete contents of the directory:
    794     //
     775    // if we reference the real directory and it changes,
     776    // the c_str pointers may become invalid, and some files
     777    // may be returned out of order / not at all.
     778    // we copy the directory's subdirectory and file containers.
    795779    SubDirs* subdirs;
    796780    SubDirIt subdir_it;
     
    818802    CHECK_ERR(tree_lookup(path, 0, &dir));
    819803
     804    // rationale for copy: see VDir definition
    820805    vd->subdirs = new SubDirs(dir->subdirs);
    821806    vd->subdir_it = vd->subdirs->begin();
     
    826811
    827812
    828 Handle vfs_open_dir(const char* const path)
    829 {
    830     return h_alloc(H_VDir, path, 0);
    831 }
    832 
    833 
     813// open a directory for reading its entries via vfs_next_dirent.
     814// directory contents are cached here; subsequent changes to the dir
     815// are not returned by this handle. rationale: see VDir definition.
     816Handle vfs_open_dir(const char* const dir)
     817{
     818    return h_alloc(H_VDir, dir, 0);
     819}
     820
     821
     822// close the handle to a directory.
     823// all vfsDirEnt.name strings are now invalid.
    834824int vfs_close_dir(Handle& hd)
    835825{
     
    838828
    839829
    840 // filter:
    841 // 0: any file
    842 // ".": file without extension (filename doesn't contain '.')
    843 // ".ext": file with extension <ext> (which must not contain '.')
    844 // "/": subdirectory
     830// get the next directory entry (in alphabetical order) that matches filter.
     831// return 0 on success. filter values:
     832// - 0: any file;
     833// - ".": any file without extension (filename doesn't contain '.');
     834// - ".ext": any file with extension ".ext" (which must not contain '.');
     835// - "/": any subdirectory
    845836int vfs_next_dirent(const Handle hd, vfsDirEnt* ent, const char* const filter)
    846837{
    847838    H_DEREF(hd, VDir, vd);
    848839
    849     // interpret filter
     840    // interpret filter (paranoid)
    850841    bool filter_dir = false;
    851842    bool filter_no_ext = false;
     
    872863    }
    873864
     865    // rationale: the filename is currently stored internally as
     866    // std::string (=> less manual memory allocation). we don't want to
     867    // return a reference, because that would break C compatibility.
     868    // we're trying to avoid fixed-size buffers, so that is out as well.
     869    // finally, allocating a copy is not so good because it has to be
     870    // freed by the user (won't happen). returning a volatile pointer
     871    // to the string itself via c_str is the only remaining option.
    874872    const char* fn;
    875873
     
    915913
    916914
     915// return actual path to the specified file:
     916// "<real_directory>/fn" or "<archive_name>/fn".
     917int vfs_realpath(const char* fn, char* full_path)
     918{
     919    const FileLoc* loc;
     920    CHECK_ERR(tree_lookup(fn, &loc));
     921
     922    const char* dir;
     923
     924    // file is in normal directory
     925    if(loc->archive <= 0)
     926        dir = loc->dir.c_str();
     927    // file is in archive
     928    {
     929        // "dir" is the archive filename
     930        dir = h_filename(loc->archive);
     931        if(!dir)
     932            return -1;
     933    }
     934
     935    CHECK_ERR(path_append(full_path, dir, fn));
     936    return 0;
     937}
     938
     939
     940// return information about the specified file as in stat(2),
     941// most notably size. stat buffer is undefined on error.
     942int vfs_stat(const char* fn, struct stat* s)
     943{
     944    const FileLoc* loc;
     945    CHECK_ERR(tree_lookup(fn, &loc));
     946
     947    if(loc->archive > 0)
     948        return zip_stat(loc->archive, fn, s);
     949    else
     950    {
     951        // similar to realpath, but don't bother splitting it out.
     952        char path[VFS_MAX_PATH];
     953        path_append(path, loc->dir.c_str(), fn);
     954        return file_stat(path, s);
     955    }
     956}
     957
     958
    917959///////////////////////////////////////////////////////////////////////////////
    918960//
     
    10391081
    10401082
     1083// open the file for synchronous or asynchronous IO. write access is
     1084// requested via VFS_WRITE flag, and is not possible for files in archives.
    10411085Handle vfs_open(const char* fn, uint flags /* = 0 */)
    10421086{
     
    10521096
    10531097
     1098// close the handle to a file.
    10541099inline int vfs_close(Handle& h)
    10551100{
     
    10621107
    10631108
    1064 ssize_t vfs_io(Handle hf, off_t ofs, size_t size, void*& p)
     1109// try to transfer <size> bytes, starting at <ofs>, to/from the given file.
     1110// (read or write access was chosen at file-open time).
     1111// return bytes of actual data transferred, or a negative error code.
     1112// TODO: buffer types
     1113ssize_t vfs_io(const Handle hf, const off_t ofs, const size_t size, void*& p)
    10651114{
    10661115#ifdef PARANOIA
     
    10811130
    10821131
    1083 Handle vfs_load(const char* fn, void*& p, size_t& size)
     1132// load the entire file <fn> into memory; return a handle to the memory
     1133// and the buffer address/size. output parameters are zeroed on failure.
     1134Handle vfs_load(const char* const fn, void*& p, size_t& size)
    10841135{
    10851136#ifdef PARANOIA
     
    11451196
    11461197
     1198///////////////////////////////////////////////////////////////////////////////
    11471199//
    11481200// memory mapping
    11491201//
     1202///////////////////////////////////////////////////////////////////////////////
     1203
    11501204
    11511205// map the entire file <hf> into memory. if already currently mapped,
     
    11861240        return file_unmap(&vf->f);
    11871241}
     1242
     1243
     1244///////////////////////////////////////////////////////////////////////////////
     1245//
     1246// asynchronous I/O
     1247//
     1248///////////////////////////////////////////////////////////////////////////////
     1249
     1250
     1251// begin transferring <size> bytes, starting at <ofs>. get result
     1252// with vfs_wait_read; when no longer needed, free via vfs_discard_io.
     1253Handle vfs_start_io(Handle hf, off_t ofs, size_t size, void* buf)
     1254{
     1255    H_DEREF(hf, VFile, vf);
     1256    if(vf_flags(vf) & VF_ZIP)
     1257        ;
     1258
     1259    return 0;
     1260}
     1261
     1262
     1263// wait until the transfer <hio> completes, and return its buffer.
     1264// output parameters are zeroed on error.
     1265int vfs_wait_io(Handle hio, void*& p, size_t& size)
     1266{
     1267    p = 0;
     1268    size = 0;
     1269
     1270    return 0;
     1271}
     1272
     1273
     1274// finished with transfer <hio> - free its buffer (returned by vfs_wait_read)
     1275int vfs_discard_io(Handle& hio)
     1276{
     1277    return 0;
     1278}
  • ps/trunk/source/lib/res/vfs.h

    r373 r385  
    2121#define __VFS_H__
    2222
    23 #include "h_mgr.h"
     23#include "h_mgr.h"  // Handle
    2424#include "posix.h"  // struct stat
    2525
     26
     27//
     28// VFS tree
     29//
     30
    2631// the VFS doesn't require this length restriction - VFS internal storage
    27 // is not fixed-length. the purpose here is to allow fixed-sized path buffers
    28 // allocated on the stack.
    29 //
    30 // length includes trailing '\0'.
     32// is not fixed-length. the purpose here is to give an indication of how
     33// large fixed-size user buffers should be. length includes trailing '\0'.
    3134#define VFS_MAX_PATH 256
    3235
     36// VFS paths are of the form:
     37// "[dir/{subdir/}]file" or "[dir/{subdir/}]dir[/]".
     38// in English: '/' as path separator; trailing '/' allowed for dir names;
     39// no leading '/', since "" is the root dir.
     40
     41// mount either a single archive or a directory into the VFS at
     42// <vfs_mount_point>, which is created if it does not yet exist.
     43// new files override the previous VFS contents if pri(ority) is higher.
     44// if <name> is a directory, all archives in that directory (but not
     45// its subdirs - see add_dirent_cb) are also mounted in alphabetical order.
     46// name = "." or "./" isn't allowed - see implementation for rationale.
    3347extern int vfs_mount(const char* vfs_mount_point, const char* name, uint pri);
    34 extern int vfs_umount(const char* name);
    3548
    36 extern int vfs_stat(const char* fn, struct stat*);
     49// rebuild the VFS, i.e. re-mount everything. open files are not affected.
     50// necessary after loose files or directories change, so that the VFS
     51// "notices" the changes and updates file locations. res calls this after
     52// FAM reports changes; can also be called from the console after a
     53// rebuild command. there is no provision for updating single VFS dirs -
     54// it's not worth the trouble.
     55extern int vfs_rebuild();
     56
     57// unmount a previously mounted item, and rebuild the VFS afterwards.
     58extern int vfs_unmount(const char* name);
     59
     60
     61//
     62// directory entry
     63//
     64
     65// information about a directory entry, returned by vfs_next_dirent.
     66struct vfsDirEnt
     67{
     68    // name of directory entry - does not include path.
     69    // valid until the directory handle is closed. must not be modified!
     70    // rationale for pointer and invalidation: see vfs_next_dirent.
     71    const char* name;
     72};
     73
     74// open the directory for reading its entries via vfs_next_dirent.
     75// directory contents are cached here; subsequent changes to the dir
     76// are not returned by this handle. rationale: see VDir definition.
     77extern Handle vfs_open_dir(const char* dir);
     78
     79// close the handle to a directory.
     80// all vfsDirEnt.name strings are now invalid.
     81extern int vfs_close_dir(Handle& hd);
     82
     83// get the next directory entry (in alphabetical order) that matches filter.
     84// return 0 on success. filter values:
     85// - 0: any file;
     86// - ".": any file without extension (filename doesn't contain '.');
     87// - ".ext": any file with extension ".ext" (which must not contain '.');
     88// - "/": any subdirectory
     89extern int vfs_next_dirent(Handle hd, vfsDirEnt* ent, const char* filter);
     90
     91
     92//
     93// file
     94//
     95
     96// return actual path to the specified file:
     97// "<real_directory>/fn" or "<archive_name>/fn".
    3798extern int vfs_realpath(const char* fn, char* realpath);
    3899
    39 extern Handle vfs_load(const char* fn, void*& p, size_t& size);
     100// return information about the specified file as in stat(2),
     101// most notably size. stat buffer is undefined on error.
     102extern int vfs_stat(const char* fn, struct stat*);
    40103
     104// vfs_open flags - keep in sync with file.cpp flag definitions!
     105enum vfsOpenFlags
     106{
     107    // write-only access; otherwise, read only
     108    VFS_WRITE        = 0x01,
     109
     110    // buffers returned may be read-only (allows some caching optimizations)
     111    VFS_MEM_READONLY = 0x02,
     112
     113    // don't cache the whole file, e.g. if kept in memory elsewhere anyway.
     114    VFS_NOCACHE      = 0x04,
     115
     116    // random access hint
     117    VFS_RANDOM       = 0x08     
     118
     119};
     120
     121// open the file for synchronous or asynchronous IO. write access is
     122// requested via VFS_WRITE flag, and is not possible for files in archives.
    41123extern Handle vfs_open(const char* fn, uint flags = 0);
     124
     125// close the handle to a file.
    42126extern int vfs_close(Handle& h);
    43127
     
    66150
    67151//
    68 // directory entry enumeration
     152// asynchronous I/O
    69153//
    70154
    71 struct vfsDirEnt
    72 {
    73     // the filename is currently stored internally as std::string. returning as char* for C compat
    74     // stored internally as std::string. returning as char* for C compat
    75     // would mean we have to return a copy. we try to avoid fixed-size
    76     // buffers, so that leaves a reference.
    77     const char* name;
    78 };
     155// begin transferring <size> bytes, starting at <ofs>. get result
     156// with vfs_wait_read; when no longer needed, free via vfs_discard_io.
     157extern Handle vfs_start_io(Handle hf, off_t ofs, size_t size, void* buf);
    79158
    80 extern Handle vfs_open_dir(const char* path);
    81 extern int vfs_close_dir(Handle& hd);
    82 extern int vfs_next_dirent(Handle hd, vfsDirEnt* ent, const char* filter);
     159// wait until the transfer <hio> completes, and return its buffer.
     160// output parameters are zeroed on error.
     161extern int vfs_wait_io(Handle hio, void*& p, size_t& size);
     162
     163// finished with transfer <hio> - free its buffer (returned by vfs_wait_read).
     164extern int vfs_discard_io(Handle& hio);
    83165
    84166
    85167//
    86 // async read interface
     168// synchronous I/O
    87169//
    88170
    89 extern Handle vfs_start_read(const Handle hf, off_t ofs, size_t& advance, void* buf);
    90 extern int vfs_wait_read(Handle hr, void*& p, size_t& size);
    91 extern int vfs_discard_read(Handle& hr);
    92 
     171// try to transfer <size> bytes, starting at <ofs>.
     172// (read or write access was chosen at file-open time).
     173// return bytes of actual data transferred, or a negative error code.
     174// TODO: buffer types
    93175extern ssize_t vfs_io(Handle hf, off_t ofs, size_t size, void*& p);
    94176
    95 
    96 // keep in sync with File flags!
    97 
    98 enum
    99 {
    100     VFS_WRITE = 1,          // write-only access; otherwise, read only
    101     VFS_MEM_READONLY = 2,   // !want to be able to change in memory data
    102     VFS_NOCACHE = 4,        // don't cache whole file, e.g. if cached on a higher level
    103     VFS_RANDOM = 8          // random access hint, allow offset
    104 };
    105 
    106 
    107 
    108 extern int vfs_rebuild();
     177// load the entire file <fn> into memory; return a memory handle to the
     178// buffer and its address/size. output parameters are zeroed on failure.
     179extern Handle vfs_load(const char* fn, void*& p, size_t& size);
    109180
    110181
Note: See TracChangeset for help on using the changeset viewer.