- file bugfix: truncate when opening for writing (problem reported by philip)
- file: now return size at close() time for use with VFS - zip: tested open speed, added [exec time] notes This was SVN commit r2075.
This commit is contained in:
parent
d60fc60a69
commit
e86001f45e
@ -530,7 +530,7 @@ int file_open(const char* p_fn, const uint flags, File* f)
|
||||
|
||||
int oflag = O_RDONLY;
|
||||
if(flags & FILE_WRITE)
|
||||
oflag = O_WRONLY | O_CREAT;
|
||||
oflag = O_WRONLY|O_CREAT|O_TRUNC;
|
||||
// read access requested
|
||||
else
|
||||
{
|
||||
@ -597,13 +597,17 @@ int file_close(File* f)
|
||||
if(f->mapping) // only free if necessary (unmap complains if not mapped)
|
||||
file_unmap(f);
|
||||
|
||||
// return final file size (required by VFS after writing files).
|
||||
// this is much easier than updating when writing, because we'd have
|
||||
// to add accounting code to both (sync and async) paths.
|
||||
f->size = lseek(f->fd, 0, SEEK_END);
|
||||
|
||||
// (check fd to avoid BoundsChecker warning about invalid close() param)
|
||||
if(f->fd != -1)
|
||||
{
|
||||
close(f->fd);
|
||||
f->fd = -1;
|
||||
}
|
||||
f->size = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -988,7 +992,6 @@ debug_out("file_io fd=%d size=%d ofs=%d\n", f->fd, data_size, data_ofs);
|
||||
data_size = MIN(data_size, (size_t)bytes_left);
|
||||
}
|
||||
|
||||
|
||||
bool temp = (data_buf == 0);
|
||||
|
||||
// sanity checks:
|
||||
|
@ -118,6 +118,9 @@ 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);
|
||||
|
||||
// note: final file size is calculated and returned in f->size.
|
||||
// see implementation for rationale.
|
||||
extern int file_close(File* f);
|
||||
|
||||
|
||||
|
@ -895,6 +895,8 @@ struct VFile
|
||||
|
||||
off_t ofs;
|
||||
|
||||
TFile* tf;
|
||||
|
||||
union
|
||||
{
|
||||
File f;
|
||||
@ -945,8 +947,18 @@ static void VFile_dtor(VFile* vf)
|
||||
if(flags & VF_ZIP)
|
||||
zip_close(&vf->zf);
|
||||
else
|
||||
{
|
||||
file_close(&vf->f);
|
||||
|
||||
// update file state in VFS tree
|
||||
// (must be done after close, since that calculates the size)
|
||||
if(flags & FILE_WRITE)
|
||||
{
|
||||
vf->tf->mtime = time(0);
|
||||
vf->tf->size = vf->f.size;
|
||||
}
|
||||
}
|
||||
|
||||
flags &= ~(VF_OPEN);
|
||||
}
|
||||
|
||||
@ -1001,6 +1013,7 @@ static int VFile_reload(VFile* vf, const char* v_path, Handle)
|
||||
|
||||
// success
|
||||
flags |= VF_OPEN;
|
||||
vf->tf = file;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -601,6 +601,8 @@ static TNode tree_root;
|
||||
static TDir* tree_root_dir = &tree_root.u.dir;
|
||||
|
||||
|
||||
// rationale: can't do this in tree_clear - we'd leak at exit.
|
||||
// calling from tree_add* is ugly as well, so require manual init.
|
||||
void tree_init()
|
||||
{
|
||||
tree_root_dir->init();
|
||||
|
@ -164,7 +164,7 @@ static int z_find_ecdr(const u8* file, size_t size, const u8*& ecdr_)
|
||||
if(*(u32*)ecdr == *(u32*)&ecdr_id)
|
||||
goto found_ecdr;
|
||||
|
||||
// jump crosses init, blah blah
|
||||
// goto scoping
|
||||
{
|
||||
// scan the last 66000 bytes of file for ecdr_id signature
|
||||
// (the Zip archive comment field, up to 64k, may follow ECDR).
|
||||
@ -232,6 +232,8 @@ enum z_extract_cdfh_ret
|
||||
// finally, advance to next CDFH.
|
||||
// return -1 on error (output params invalid), or 0 on success.
|
||||
// called by z_enum_files, which passes the output to lookup.
|
||||
//
|
||||
// [30ms]
|
||||
static int z_extract_cdfh(const u8* file, size_t size, // in
|
||||
const u8*& cdfh, const char*& fn, size_t& fn_len, ZLoc* loc) // out
|
||||
{
|
||||
@ -308,6 +310,7 @@ static int z_extract_cdfh(const u8* file, size_t size, // in
|
||||
// loc is only valid during the callback! must be copied or saved.
|
||||
typedef int(*CDFH_CB)(uintptr_t user, i32 idx, const char* fn, size_t fn_len, const ZLoc* loc);
|
||||
|
||||
|
||||
static int z_enum_files(const u8* file, const size_t size, const CDFH_CB cb, const uintptr_t user)
|
||||
{
|
||||
// find "End of Central Directory Record"
|
||||
@ -332,11 +335,13 @@ static int z_enum_files(const u8* file, const size_t size, const CDFH_CB cb, con
|
||||
// only incremented when valid, so we don't leave holes
|
||||
// in lookup's arrays (bad locality).
|
||||
|
||||
|
||||
for(i32 i = 0; i < num_entries; i++)
|
||||
{
|
||||
const char* fn;
|
||||
size_t fn_len;
|
||||
ZLoc loc;
|
||||
|
||||
int ret = z_extract_cdfh(file, size, cdfh, fn, fn_len, &loc);
|
||||
// valid file
|
||||
if(ret == Z_CDFH_FILE_OK)
|
||||
@ -425,6 +430,8 @@ struct LookupInfo
|
||||
// notes:
|
||||
// - fn (filename) is not necessarily 0-terminated!
|
||||
// - loc is only valid during the callback! must be copied or saved.
|
||||
//
|
||||
// [40ms]
|
||||
static int lookup_add_file_cb(uintptr_t user, i32 idx,
|
||||
const char* fn, size_t fn_len, const ZLoc* loc)
|
||||
{
|
||||
@ -673,6 +680,7 @@ fail_close:
|
||||
// somewhat slow - each file is added to an internal index.
|
||||
Handle zip_archive_open(const char* fn)
|
||||
{
|
||||
TIMER(zip_archive_open);
|
||||
return h_alloc(H_ZArchive, fn);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user