1
0
forked from 0ad/0ad

no message

This was SVN commit r27.
This commit is contained in:
janwas 2003-11-05 16:52:41 +00:00
parent b27731c9cc
commit 88bbb5148a
9 changed files with 334 additions and 235 deletions

View File

@ -119,9 +119,9 @@ int build_font(const char* in_ttf, const char* out_fnt, const char* out_raw, int
#endif
static void font_dtor(HDATA* hd)
static void font_dtor(void* p)
{
FONT* font = (FONT*)hd->internal;
FONT* font = (FONT*)p;
glDeleteLists(font->list_base, 96);
}
@ -131,7 +131,7 @@ u32 font_load(const char* fn)
void* p;
size_t size;
HDATA* hd;
Handle h = res_load(fn, RES_FONT, font_dtor, p, size, hd);
Handle h = res_load(fn, H_FONT, font_dtor, p, size, hd);
if(!h)
return 0;
@ -191,7 +191,7 @@ u32 font_load(const char* fn)
u = 0.f, v += th;
}
FONT* font = (FONT*)hd->internal;
FONT* font = (FONT*)hd->user;
font->tex = tex;
font->list_base = list_base;
@ -201,10 +201,10 @@ u32 font_load(const char* fn)
int font_bind(const Handle h)
{
HDATA* hd = h_data(h, RES_FONT);
HDATA* hd = h_data(h, H_FONT);
if(!hd)
return -1;
FONT* font = (FONT*)hd->internal;
FONT* font = (FONT*)hd->user;
tex_bind(font->tex);
glListBase(font->list_base);

View File

@ -14,15 +14,20 @@
struct MEM
{
uint type;
void* org_p; // MEM_HEAP only
size_t size; // MEM_POOL only
// MEM_HEAP only
void* org_p;
// MEM_POOL only
size_t ofs;
size_t size;
};
static void heap_dtor(HDATA* hd)
static void heap_dtor(void* p)
{
MEM* mem = (MEM*)hd->internal;
MEM* mem = (MEM*)p;
free(mem->org_p);
}
@ -43,13 +48,12 @@ static size_t pool_pos;
static const size_t POOL_CAP = 64*MB; // TODO: user editable
static void pool_dtor(HDATA* hd)
static void pool_dtor(void* p)
{
MEM* mem = (MEM*)hd->internal;
MEM* mem = (MEM*)p;
ssize_t pool_ofs = (u8*)hd->p - (u8*)pool;
// at end of pool? if so, 'free' it
if(pool_ofs + mem->size == pool_pos)
if(mem->ofs + mem->size == pool_pos)
pool_pos -= mem->size;
}
@ -70,6 +74,7 @@ static void* pool_alloc(const size_t size, const uint align, MEM& mem)
void* p = (u8*)pool + ofs;
mem.size = size;
mem.ofs = ofs;
pool_pos = ofs+size;
return p;
@ -77,13 +82,13 @@ static void* pool_alloc(const size_t size, const uint align, MEM& mem)
static void mem_dtor(HDATA* hd)
static void mem_dtor(void* p)
{
MEM* mem = (MEM*)hd->internal;
MEM* mem = (MEM*)p;
if(mem->type == MEM_HEAP)
heap_dtor(hd);
heap_dtor(p);
else if(mem->type == MEM_POOL)
pool_dtor(hd);
pool_dtor(p);
}
@ -93,11 +98,11 @@ void* mem_alloc(size_t size, const MemType type, const uint align, Handle* ph)
size = 1;
HDATA* hd;
Handle h = h_alloc(0, RES_MEM, mem_dtor, &hd);
Handle h = h_alloc(0, H_MEM, mem_dtor, &hd);
if(!h)
return 0;
MEM& mem = (MEM&)hd->internal;
MEM& mem = (MEM&)hd->user;
void* p;
if(type == MEM_HEAP)
@ -106,7 +111,7 @@ void* mem_alloc(size_t size, const MemType type, const uint align, Handle* ph)
p = pool_alloc(size, align, mem);
else
{
h_free(h, RES_MEM);
h_free(h, H_MEM);
return 0;
}
@ -123,8 +128,8 @@ int mem_free(void* p)
return 1;
HDATA* hd;
Handle h = h_find(p, RES_MEM, &hd);
Handle h = h_find(p, H_MEM, &hd);
if(h)
return h_free(h, RES_MEM);
return h_free(h, H_MEM);
return -1;
}

View File

@ -40,6 +40,35 @@
#define ONCE(code) { static bool done; if(!done) { code; }; done = true; }
template<bool>
struct cassert_checker
{
cassert_checker(...) { }
};
template<> struct cassert_checker<false> { };
#define cassert(expr, id) {\
struct CASSERT_##id { };\
typedef cassert_checker<(expr)> type;\
type temp = type(CASSERT_##id());\
(void)sizeof(temp);\
}
const u32 KB = 1 << 10;
const u32 MB = 1 << 20;

View File

@ -26,67 +26,30 @@
#include "posix.h"
#include "misc.h"
#include "res.h"
#include "mem.h"
#include "vfs.h"
// handle (32 bits)
// .. make sure this is the same handle we opened
static const uint TAG_BITS = 16;
// .. index into array => = log2(max open handles)
static const uint IDX_BITS = 12;
static const uint OWNER_BITS = 4;
static const uint TYPE_BITS = 4;
static const uint REF_BITS = 8;
struct Res
{
u32 key;
u32 tag : TAG_BITS;
u32 type : TYPE_BITS;
u32 owner : OWNER_BITS;
u32 refs : REF_BITS;
};
static const ulong res_array_cap = 1ul << IDX_BITS;
static const uint owner_cap = 1ul << OWNER_BITS;
// static allocation for simplicity; mem usage isn't significant
static Res res_array[res_array_cap];
static int first_free = -1;
static int max_idx = -1; // index of last in-use entry
static const ulong hdata_cap = 1ul << HIDX_BITS;
static const uint type_cap = 1ul << HTYPE_BITS;
// array of pages for better locality, less fragmentation
static const uint PAGE_SIZE = 4096;
static const uint hdata_per_page = PAGE_SIZE / sizeof(HDATA);
static const uint num_pages = res_array_cap / hdata_per_page;
static const uint num_pages = hdata_cap / hdata_per_page;
static HDATA* pages[num_pages];
static void(*dtors[owner_cap])(HDATA*);
static int first_free = -1; // don't want to scan array every h_alloc
static int last_in_use = -1; // don't search unused entries
static Handle handle(const int idx)
{
const Res& r = res_array[idx];
return (r.tag) << IDX_BITS | (u32)idx;
}
static int h_idx(const Handle h, const uint owner)
{
int idx = h & ((1 << IDX_BITS)-1);
const Res& r = res_array[idx];
u32 tag = h >> IDX_BITS;
if(!tag || r.tag != tag || r.owner != owner)
return -1;
return idx;
}
static void(*dtors[type_cap])(void*);
// get pointer to handle data (non-contiguous array)
static HDATA* h_data(const int idx)
{
if(idx > hdata_cap)
return 0;
HDATA*& page = pages[idx / hdata_per_page];
if(!page)
{
@ -99,21 +62,62 @@ static HDATA* h_data(const int idx)
}
// get array index from handle
static int h_idx(const Handle h, const uint type)
{
const int idx = h & ((1 << HIDX_BITS)-1);
if(idx > last_in_use)
return -1;
const HDATA* hd = h_data(idx);
// cannot fail - it was successfully allocated
const u32 tag = h >> HIDX_BITS;
// note: tag = 0 marks unused entries => is invalid
if(!tag || hd->tag != tag || hd->type != type)
return -1;
return idx;
}
static Handle handle(const int idx)
{
const HDATA* hd = h_data(idx);
if(!hd) // out of memory
return 0;
return (hd->tag) << HIDX_BITS | (u32)idx;
}
static int h_free(const int idx)
{
Res& r = res_array[idx];
if(--r.refs)
HDATA* hd = h_data(idx);
if(!hd)
return -1;
// not the last reference
if(--hd->refs)
return 0;
HDATA* hd = h_data(idx);
if(hd)
// free its pointer
switch(hd->ptype)
{
if(dtors[r.owner])
dtors[r.owner](hd);
memset(hd, 0, sizeof(HDATA));
case PT_MEM:
mem_free(hd->p);
break;
case PT_MAP:
munmap(hd->p, hd->size);
break;
}
memset(&r, 0, sizeof(r));
// call its type's destructor
if(dtors[hd->type])
dtors[hd->type](hd);
memset(hd, 0, sizeof(HDATA));
if(first_free == -1 || idx < first_free)
first_free = idx;
@ -127,10 +131,10 @@ static void cleanup(void)
int i;
// close open handles
for(i = 0; i < max_idx; i++)
for(i = 0; i < last_in_use; i++)
h_free(i);
// free internal data space
// free hdata array
for(i = 0; i < (int)num_pages; i++)
{
free(pages[i]);
@ -139,20 +143,16 @@ static void cleanup(void)
}
Handle h_find(const void* p, uint owner, HDATA** phd)
Handle h_find(const void* p, uint type, HDATA** puser)
{
const Res* r = res_array;
for(int idx = 0; idx <= max_idx; idx++, r++)
for(int idx = 0; idx <= last_in_use; idx++)
{
if(r->owner != owner)
continue;
HDATA* hd = h_data(idx); // guaranteed valid
HDATA* hd = h_data(idx);
if(hd && hd->p == p)
if(hd->p == p && hd->type == type)
{
if(phd)
*phd = hd;
if(puser)
*puser = hd/*->user*/;
return handle(idx);
}
}
@ -161,26 +161,32 @@ Handle h_find(const void* p, uint owner, HDATA** phd)
}
Handle h_find(const u32 key, uint owner, HDATA** phd)
Handle h_find(const u32 key, uint type, HDATA** puser)
{
int idx;
const Res* r = res_array;
HDATA* hd;
// already have first free entry cached - just search
if(first_free != -1)
{
for(idx = 0; idx <= max_idx; idx++, r++)
if(r->key == key && r->owner == owner)
for(idx = 0; idx <= last_in_use; idx++)
{
hd = h_data(idx); // guaranteed valid
if(hd->key == key && hd->type == type)
goto found;
}
}
// search and remember first free entry (slower)
else
{
for(idx = 0; idx <= max_idx; idx++, r++)
if(!r->tag && first_free == -1)
for(idx = 0; idx <= last_in_use; idx++)
{
hd = h_data(idx); // guaranteed valid
if(!hd->tag && first_free == -1)
first_free = idx;
else if(r->key == key && r->owner == owner)
else if(hd->key == key && hd->type == type)
goto found;
}
}
// not found
@ -188,54 +194,77 @@ Handle h_find(const u32 key, uint owner, HDATA** phd)
found:
Handle h = handle(idx);
if(phd)
{
HDATA* hd = h_data(h, owner);
if(!hd)
return 0;
*phd = hd;
}
if(puser)
*puser = hd/*->user*/;
return h;
}
Handle h_alloc(const u32 key, const uint owner, DTOR dtor, HDATA** phd)
int h_assign(Handle h, u8* p, size_t size, bool mem)
{
HDATA* hd = h_data(h);
if(!hd)
return -1;
if(hd->p || hd->size || hd->ptype != PT_NONE)
{
assert(!"h_assign: field(s) already assigned");
return -1;
}
hd->p = p;
hd->size = size;
hd->ptype = mem? PT_MEM : PT_MAP;
return 0;
}
Handle h_alloc(const u32 key, const uint type, /*const size_t user_size,*/ DTOR dtor, HDATA** puser)
{
ONCE(atexit(cleanup))
if(owner >= owner_cap)
/*
if(user_size > HDATA_USER_SIZE)
{
assert(!"h_alloc: not enough space in entry for user data");
return 0;
}
*/
if(type >= type_cap)
{
assert(!"h_alloc: invalid type");
return 0;
}
if(dtor)
{
// registering a second dtor for owner
// if(dtors[owner] && dtors[owner] != dtor)
// return 0;
dtors[owner] = dtor;
// registering a second dtor for type
if(dtors[type] && dtors[type] != dtor)
{
assert(!"h_alloc: registering a second, different dtor for type");
return 0;
}
dtors[type] = dtor;
}
int idx;
Res* r = res_array;
HDATA* hd;
Handle h;
if(key)
{
h = h_find(key, owner, &hd);
// object already loaded?
Handle h = h_find(key, type, &hd);
if(h)
{
idx = h_idx(h, owner);
r = &res_array[idx];
// only way to decide whether this handle is new, or a reference
assert(hd->size != 0);
if(r->refs == (1ul << REF_BITS))
if(hd->refs == (1ul << HREF_BITS))
{
assert(!"h_alloc: too many references to a handle - increase REF_BITS");
return 0;
}
r->refs++;
hd->refs++;
return h;
}
}
@ -244,62 +273,57 @@ Handle h_alloc(const u32 key, const uint owner, DTOR dtor, HDATA** phd)
if(first_free != -1)
{
idx = first_free;
r = &res_array[idx];
hd = h_data(idx);
}
// search res_array for first entry
// search handle data for first free entry
else
for(idx = 0; idx < res_array_cap; idx++, r++)
if(!r->tag)
for(idx = 0; idx < hdata_cap; idx++)
{
hd = h_data(idx);
// not enough memory - abort (don't leave a hole in the array)
if(!hd)
return 0;
// found an empty entry - done
if(!hd->tag)
break;
}
// check if next entry is free
if(idx+1 < res_array_cap && !(r+1)->key)
first_free = idx+1;
else
first_free = -1;
if(idx >= res_array_cap)
if(idx >= hdata_cap)
{
assert(!"h_alloc: too many open handles (increase IDX_BITS)");
return 0;
}
if(idx > max_idx)
max_idx = idx;
// check if next entry is free
HDATA* hd2 = h_data(idx+1);
if(hd2 && hd2->tag == 0)
first_free = idx+1;
else
first_free = -1;
if(idx > last_in_use)
last_in_use = idx;
static u32 tag;
if(++tag >= (1 << TAG_BITS))
if(++tag >= (1 << HTAG_BITS))
{
assert(!"h_alloc: tag overflow - may not notice stale handle reuse (increase TAG_BITS)");
tag = 1;
}
r->key = key;
r->tag = tag;
r->owner = owner;
hd->key = key;
hd->tag = tag;
hd->type = type;
h = handle(idx);
// caller wants HDATA* returned
if(phd)
{
HDATA* hd = h_data(h, owner);
// not enough mem - fail
if(!hd)
{
h_free(h, owner);
return 0;
}
*phd = hd;
}
return h;
if(puser)
*puser = hd/*->user*/;
return handle(idx);
}
int h_free(const Handle h, const uint owner)
int h_free(const Handle h, const uint type)
{
int idx = h_idx(h, owner);
int idx = h_idx(h, type);
if(idx >= 0)
return h_free(idx);
return -1;
@ -307,9 +331,9 @@ int h_free(const Handle h, const uint owner)
HDATA* h_data(const Handle h, const uint owner)
HDATA* h_data(const Handle h, const uint type)
{
int idx = h_idx(h, owner);
int idx = h_idx(h, type);
if(idx >= 0)
return h_data(idx);
return 0;
@ -317,15 +341,16 @@ HDATA* h_data(const Handle h, const uint owner)
Handle res_load(const char* fn, uint type, DTOR dtor, void*& p, size_t& size, HDATA*& hd)
Handle res_load(const char* fn, uint type, DTOR dtor, void*& p, size_t& size, HDATA*& user)
{
p = 0;
size = 0;
hd = 0;
user = 0;
u32 fn_hash = fnv_hash(fn, strlen(fn));
// TODO: fn is usually a constant; pass fn len if too slow
HDATA* hd;
Handle h = h_alloc(fn_hash, type, dtor, &hd);
if(!h)
return 0;
@ -348,7 +373,7 @@ Handle res_load(const char* fn, uint type, DTOR dtor, void*& p, size_t& size, HD
hd->p = p;
hd->size = size;
user=hd;
return h;
}

View File

@ -22,50 +22,98 @@
#include "types.h"
// handle type (for 'type safety' - can't use a texture handle as a sound)
enum
{
RES_TEX = 1,
RES_FONT,
RES_SOUND,
RES_ZFILE,
RES_ZARCHIVE,
RES_VFILE,
RES_MMAP,
RES_MEM
// handle type (for 'type safety' - can't use a texture handle as a sound)
//
// rationale: we could use the destructor passed to res_load to identify
// the handle, but it's good to have a list of all types, and we avoid having
// to create empty destructors for handle types that wouldn't need them.
// finally, we save memory - this fits in a few bits, vs. needing a pointer.
enum HType
{
H_TEX = 1,
H_FONT = 2,
H_SOUND = 3,
H_ZFILE = 4,
H_ZARCHIVE = 5,
H_VFILE = 6,
H_MEM = 7,
NUM_HANDLE_TYPES
};
// handle's pointer type
enum PType
{
PT_NONE,
PT_MEM, // allocated by mem_alloc
PT_MAP // mapped by mmap
};
typedef unsigned long Handle;
// handle (32 bits)
// .. make sure this is the same handle we opened
const uint HTAG_BITS = 16;
// .. index into array => = log2(max open handles)
const uint HIDX_BITS = 12;
const int HDATA_INTERNAL_SIZE = 24;
// <= 32-TAG_BITS bits
const uint HTYPE_BITS = 4;
const uint PTYPE_BITS = 4;
const uint HREF_BITS = 8;
const int HDATA_USER_SIZE = 16;
// 32 bytes
struct HDATA
{
u32 key;
u32 tag : HTAG_BITS;
u32 type : HTYPE_BITS; // handle's type (e.g. texture, sound)
u32 ptype : PTYPE_BITS; // what does p point to?
u32 refs : HREF_BITS;
void* p;
size_t size;
u8 internal[HDATA_INTERNAL_SIZE];
u8 user[HDATA_USER_SIZE];
};
typedef void(*DTOR)(HDATA*);
extern Handle h_alloc(u32 key, uint type, DTOR dtor = 0, HDATA** phd = 0);
// 0 = invalid handle value.
typedef u32 Handle;
// destructor, registered by h_alloc for a given handle type.
// receives the user data associated with the handle.
typedef void(*DTOR)(void*);
// all functions check the passed tag (part of the handle) and type against
// the internal values. if they differ, an error is returned.
// allocate a new handle.
// if key is 0, or a (key, type) handle doesn't exist,
// the first free entry is used.
// otherwise, a handle to the existing object is returned,
// and HDATA.size != 0.
//// user_size is checked to make sure the user data fits in the handle data space.
// dtor is associated with type and called when the object is freed.
// handle data is initialized to 0; optionally, a pointer to it is returned.
extern Handle h_alloc(u32 key, uint type,/* size_t user_size,*/ DTOR dtor = 0, HDATA** puser = 0);
extern int h_free(Handle h, uint type);
// find and return a handle by type and associated key (typically filename hash)
// find and return a handle by type and key (typically filename hash)
// currently O(n).
extern Handle h_find(u32 key, uint type, HDATA** phd = 0);
extern Handle h_find(u32 key, uint type, HDATA** puser = 0);
// same as above, but search for a pointer the handle references
extern Handle h_find(const void* p, uint type, HDATA** phd = 0);
// same as above, but search for the handle's associated pointer
extern Handle h_find(const void* p, uint type, HDATA** puser = 0);
// get a handle's associated data.
// returns 0 if the handle is invalid, or <type> doesn't match
// return a pointer to handle data
extern HDATA* h_data(Handle h, uint type);
extern Handle res_load(const char* fn, uint type, DTOR dtor, void*& p, size_t& size, HDATA*& hd);
extern Handle res_load(const char* fn, uint type, DTOR dtor, void*& p, size_t& size, HDATA*& user);
#endif // #ifndef __RES_H__

View File

@ -153,8 +153,7 @@ static int dds_load(const char* fn, const u8* ptr, size_t size, TEX* tex)
tex->width = w;
tex->height = h;
tex->fmt = fmt;
tex->bpp = 0;
tex->s3tc_img_size = img_size;
tex->bpp = img_size / (w * h);
tex->ptr = img;
if(sizeof(DDSURFACEDESC2) != ddsd_size)
@ -589,9 +588,9 @@ static int jp2_load(const char* fn, const u8* ptr, size_t size, TEX* tex)
static void tex_dtor(HDATA* hd)
static void tex_dtor(void* p)
{
TEX* tex = (TEX*)hd->internal;
TEX* tex = (TEX*)p;
glDeleteTextures(1, &tex->id);
}
@ -603,11 +602,11 @@ Handle tex_load(const char* fn, TEX* ptex)
const u8* p;
size_t size;
HDATA* hd;
Handle h = res_load(fn, RES_TEX, tex_dtor, (void*&)p, size, hd);
Handle h = res_load(fn, H_TEX, tex_dtor, (void*&)p, size, hd);
if(!h)
return 0;
TEX* tex = (TEX*)hd->internal;
TEX* tex = (TEX*)hd->user;
if(!p)
goto already_loaded;
if(size < 4) // guarantee xxx_valid routines 4 bytes
@ -670,13 +669,13 @@ already_loaded:
int tex_bind(const Handle h)
{
HDATA* hd = h_data(h, RES_TEX);
HDATA* hd = h_data(h, H_TEX);
if(!hd)
{
glBindTexture(GL_TEXTURE_2D, 0);
return -1;
}
TEX* tex = (TEX*)hd->internal;
TEX* tex = (TEX*)hd->user;
glBindTexture(GL_TEXTURE_2D, tex->id);
return 0;
}
@ -687,10 +686,10 @@ uint tex_bpp = 32; // 16 or 32
int tex_upload(const Handle h, int filter, int int_fmt)
{
HDATA* hd = h_data(h, RES_TEX);
HDATA* hd = h_data(h, H_TEX);
if(!hd)
return -1;
TEX* tex = (TEX*)hd->internal;
TEX* tex = (TEX*)hd->user;
// greater than max supported tex dimension?
// no-op if oglInit not yet called
@ -726,7 +725,10 @@ int tex_upload(const Handle h, int filter, int int_fmt)
// S3TC compressed
if(tex->fmt >= GL_COMPRESSED_RGB_S3TC_DXT1_EXT &&
tex->fmt <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, tex->fmt, tex->width, tex->height, 0, tex->s3tc_img_size, tex->ptr);
{
int img_size = tex->width * tex->height * tex->bpp;
glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, tex->fmt, tex->width, tex->height, 0, img_size, tex->ptr);
}
// normal
else
{

View File

@ -21,20 +21,21 @@
#include "types.h"
#include "res.h"
#include "misc.h"
struct TEX
{
u32 width : 16;
u32 height : 16;
u32 fmt : 16;
u32 bpp : 8; // 0 if S3TC
u32 s3tc_img_size;
u32 bpp : 16;
const u8* ptr;
uint id;
};
// load and return a handle to the texture given in <fn>.
// supports RAW, BMP, JP2, PNG, TGA, DDS
// optionally returns a copy of information about the texture.

View File

@ -39,7 +39,7 @@ static const char cdfh_id[] = "PK\1\2"; // Central File Header identifier
static const char lfh_id[] = "PK\3\4"; // Local File Header identifier
// RES_ZFILE handle
// H_ZFILE handle
// location and size of an archived file
// no destructor
struct ZFILE
@ -50,11 +50,11 @@ struct ZFILE
};
// RES_ZARCHIVE handle
// H_ZARCHIVE handle
// information about a ZIP archive
struct ZARCHIVE
{
Handle hf; // actual ZIP file (RES_VFILE)
Handle hf; // actual ZIP file (H_VFILE)
// file lookup
u32 num_files;
@ -64,12 +64,12 @@ struct ZARCHIVE
};
static void zarchive_dtor(HDATA* hd)
static void zarchive_dtor(void* p)
{
ZARCHIVE* z = (ZARCHIVE*)hd->internal;
ZARCHIVE* za = (ZARCHIVE*)p;
vfs_close(z->hf);
z->hf = 0;
vfs_close(za->hf);
za->hf = 0;
}
@ -80,7 +80,7 @@ Handle zopen(const char* const fn)
// already loaded?
HDATA* hd;
Handle h = h_find(fn_hash, RES_ZFILE, &hd);
Handle h = h_find(fn_hash, H_ZFILE, &hd);
if(h)
return h;
@ -127,11 +127,11 @@ found_ecdr:
if(!mem)
goto fail;
h = h_alloc(fn_hash, RES_ZFILE, zarchive_dtor, &hd);
h = h_alloc(fn_hash, H_ZFILE, zarchive_dtor, &hd);
if(!h)
goto fail;
ZARCHIVE* const za = (ZARCHIVE*)hd->internal;
ZARCHIVE* const za = (ZARCHIVE*)hd->user;
za->hf = hf;
za->fn_hashs = (u32*)mem;
za->files = (ZFILE*)((u8*)mem + 4*num_files);
@ -186,19 +186,19 @@ found_ecdr:
void zclose(const Handle h)
{
if(h_data(h, RES_ZFILE))
h_free(h, RES_ZFILE);
if(h_data(h, H_ZFILE))
h_free(h, H_ZFILE);
else
h_free(h, RES_ZARCHIVE);
h_free(h, H_ZARCHIVE);
}
Handle zopen(Handle hz, const char* fn)
{
HDATA* hzd = h_data(hz, RES_ZFILE);
HDATA* hzd = h_data(hz, H_ZFILE);
if(!hzd)
return 0;
ZARCHIVE* za = (ZARCHIVE*)hzd->internal;
ZARCHIVE* za = (ZARCHIVE*)hzd->user;
// find its File descriptor
const u32 fn_hash = fnv_hash(fn, strlen(fn));
@ -217,7 +217,7 @@ Handle zopen(Handle hz, const char* fn)
//
HDATA* hfd;
Handle hf = h_alloc(fn_hash, RES_ZFILE, 0, &hfd);
Handle hf = h_alloc(fn_hash, H_ZFILE, 0, &hfd);
return hf;
}
@ -228,7 +228,7 @@ int zread(Handle hf, void*& p, size_t& size, size_t ofs)
if(!hfd)
return -1;
ZFILE* zf = (ZFILE*)hfd->internal;
ZFILE* zf = (ZFILE*)hfd->user;
const size_t ucsize = zf->ucsize;
const size_t csize = zf->csize;

View File

@ -31,20 +31,9 @@ struct PATH
static PATH* path_list;
static void vfile_dtor(HDATA* hd)
static void vfile_dtor(void* p)
{
VFILE* vf = (VFILE*)hd->internal;
// normal file
if(vf->fd != -1)
{
munmap(hd->p, hd->size);
hd->p = 0;
hd->size = 0;
close(vf->fd);
vf->fd = -1;
}
VFILE* vf = (VFILE*)p;
// in archive
if(vf->ha && vf->hz)
@ -232,12 +221,12 @@ u32 vfs_start_read(const Handle hf, size_t& ofs, void** buf)
{
HDATA* hfd = h_data(hf, 0);
if(!hfd)
return -1;
VFILE* vf = (VFILE*)hfd->internal;
return 0;
VFILE* vf = (VFILE*)hfd->user;
ssize_t bytes_left = hfd->size - ofs;
if(bytes_left < 0)
return -1;
return 0;
// TODO: thread safety
@ -250,7 +239,7 @@ u32 vfs_start_read(const Handle hf, size_t& ofs, void** buf)
if(i == NUM_SLOTS)
{
assert(!"vfs_start_read: too many active reads; increase NUM_SLOTS");
return -1;
return 0;
}
// mark it in use
@ -273,7 +262,7 @@ u32 vfs_start_read(const Handle hf, size_t& ofs, void** buf)
{
cb->aio_buf = mem_alloc(64*KB, MEM_HEAP, 64*KB);
if(!cb->aio_buf)
return -1;
return 0;
}
// align to 64 KB for speed
@ -328,7 +317,7 @@ int vfs_read(Handle h, void*& p, size_t& size, size_t ofs)
p = 0;
size = 0;
HDATA* hd = h_data(h, RES_VFILE);
HDATA* hd = h_data(h, H_VFILE);
if(hd)
{
if(ofs+size > hd->size)
@ -338,7 +327,7 @@ int vfs_read(Handle h, void*& p, size_t& size, size_t ofs)
size = hd->size - ofs;
return 0;
}
// RES_ZFILE
// H_ZFILE
else
return zread(h, p, size, ofs);
}