From 88bbb5148a298549d367b8bd9a864f254ef4189e Mon Sep 17 00:00:00 2001 From: janwas Date: Wed, 5 Nov 2003 16:52:41 +0000 Subject: [PATCH] no message This was SVN commit r27. --- source/lib/font.cpp | 12 +- source/lib/mem.cpp | 39 +++--- source/lib/misc.h | 29 +++++ source/lib/res.cpp | 301 +++++++++++++++++++++++-------------------- source/lib/res.h | 94 ++++++++++---- source/lib/tex.cpp | 24 ++-- source/lib/tex.h | 7 +- source/lib/unzip.cpp | 34 ++--- source/lib/vfs.cpp | 29 ++--- 9 files changed, 334 insertions(+), 235 deletions(-) diff --git a/source/lib/font.cpp b/source/lib/font.cpp index 5094d0bd72..1271edadd6 100755 --- a/source/lib/font.cpp +++ b/source/lib/font.cpp @@ -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); diff --git a/source/lib/mem.cpp b/source/lib/mem.cpp index 1e5edddb36..f6734e7eee 100755 --- a/source/lib/mem.cpp +++ b/source/lib/mem.cpp @@ -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; } \ No newline at end of file diff --git a/source/lib/misc.h b/source/lib/misc.h index 11f0814dd9..dd8fac7674 100755 --- a/source/lib/misc.h +++ b/source/lib/misc.h @@ -40,6 +40,35 @@ #define ONCE(code) { static bool done; if(!done) { code; }; done = true; } + + +template +struct cassert_checker +{ + cassert_checker(...) { } +}; + +template<> struct cassert_checker { }; + +#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; diff --git a/source/lib/res.cpp b/source/lib/res.cpp index 0a1dcf34a0..50c913561a 100755 --- a/source/lib/res.cpp +++ b/source/lib/res.cpp @@ -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; } diff --git a/source/lib/res.h b/source/lib/res.h index 3e20cfbb36..32e4dc36ea 100755 --- a/source/lib/res.h +++ b/source/lib/res.h @@ -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 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__ diff --git a/source/lib/tex.cpp b/source/lib/tex.cpp index 7757c19503..093fb4fcda 100755 --- a/source/lib/tex.cpp +++ b/source/lib/tex.cpp @@ -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 { diff --git a/source/lib/tex.h b/source/lib/tex.h index 5f8624be16..7954b79f8b 100755 --- a/source/lib/tex.h +++ b/source/lib/tex.h @@ -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 . // supports RAW, BMP, JP2, PNG, TGA, DDS // optionally returns a copy of information about the texture. diff --git a/source/lib/unzip.cpp b/source/lib/unzip.cpp index b01184c71c..0986b26548 100755 --- a/source/lib/unzip.cpp +++ b/source/lib/unzip.cpp @@ -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; diff --git a/source/lib/vfs.cpp b/source/lib/vfs.cpp index 8c85375cdc..731d0cab90 100755 --- a/source/lib/vfs.cpp +++ b/source/lib/vfs.cpp @@ -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); }