diff --git a/source/lib/res/file.cpp b/source/lib/res/file.cpp index e7a2357a32..a4875f6430 100755 --- a/source/lib/res/file.cpp +++ b/source/lib/res/file.cpp @@ -56,13 +56,13 @@ const size_t BLOCK_SIZE = 1ul << BLOCK_SIZE_LOG2; // * requests for part of a block are usually followed by another. -enum Conversion +static enum Conversion { TO_NATIVE, TO_PORTABLE }; -static int convert_path(const char* src, char* dst, Conversion conv = TO_NATIVE) +static int convert_path(char* dst, const char* src, Conversion conv = TO_NATIVE) { /* // if there's a platform with multiple-character DIR_SEP, @@ -103,9 +103,29 @@ static int convert_path(const char* src, char* dst, Conversion conv = TO_NATIVE) } +// set by file_rel_chdir static char n_root_dir[PATH_MAX]; static size_t n_root_dir_len; + +// return the native equivalent of the given portable path +// (i.e. convert all '/' to the platform's directory separator) +// makes sure length < PATH_MAX. +int file_make_native_path(const char* const path, char* const n_path) +{ + strcpy(n_path, n_root_dir); + return convert_path(n_path+n_root_dir_len, path, TO_NATIVE); +} + + +int file_make_portable_path(const char* const n_path, char* const path) +{ + if(strncmp(n_path, n_root_dir, n_root_dir_len) != 0) + return -1; + return convert_path(path, n_path+n_root_dir_len, TO_PORTABLE); +} + + // set current directory to rel_path, relative to the path to the executable, // which is taken from argv0. // @@ -164,7 +184,7 @@ int file_rel_chdir(const char* argv0, const char* const rel_path) msg = "realpath returned an invalid path?"; goto fail; } - CHECK_ERR(convert_path(rel_path, fn+1)); + CHECK_ERR(convert_path(fn+1, rel_path)); if(chdir(n_path) < 0) goto fail; @@ -194,25 +214,6 @@ fail: } -// return the native equivalent of the given portable path -// (i.e. convert all '/' to the platform's directory separator) -// makes sure length < PATH_MAX. -int file_make_native_path(const char* const path, char* const n_path) -{ - strcpy(n_path, n_root_dir); - return convert_path(path, n_path+n_root_dir_len, TO_NATIVE); -} - - -int file_make_portable_path(const char* const n_path, char* const path) -{ - if(strncmp(n_path, n_root_dir, n_root_dir_len) != 0) - return -1; - return convert_path(n_path+n_root_dir_len, path, TO_PORTABLE); -} - - - // need to store entries returned by readdir so they can be sorted. struct DirEnt { @@ -245,7 +246,7 @@ int file_enum(const char* const dir, const FileCB cb, const uintptr_t user) n_path[PATH_MAX] = '\0'; // will append filename to this, hence "path". // 0-terminate simplifies filename strncpy below. - CHECK_ERR(convert_path(dir, n_path)); + CHECK_ERR(convert_path(n_path, dir)); // all entries are enumerated (adding to this container), // std::sort-ed, then all passed to cb. @@ -335,7 +336,7 @@ int file_enum(const char* const dir, const FileCB cb, const uintptr_t user) int file_stat(const char* const path, struct stat* const s) { char n_path[PATH_MAX+1]; - CHECK_ERR(convert_path(path, n_path)); + CHECK_ERR(convert_path(n_path, path)); return stat(n_path, s); } @@ -427,7 +428,7 @@ int file_open(const char* const p_fn, const uint flags, File* const f) memset(f, 0, sizeof(File)); char n_fn[PATH_MAX]; - CHECK_ERR(convert_path(p_fn, n_fn)); + CHECK_ERR(convert_path(n_fn, p_fn)); if(!f) goto invalid_f; @@ -1132,6 +1133,23 @@ debug_out("file_io fd=%d size=%d ofs=%d\n", f->fd, raw_size, raw_ofs); const bool is_write = (f->flags & FILE_WRITE) != 0; + if(f->flags & FILE_NO_AIO) + { + // cut off at EOF if reading + if(!is_write) + { + const ssize_t bytes_left = f->size - raw_ofs; + if(bytes_left < 0) + return -1; + raw_size = MIN(raw_size, (size_t)bytes_left); + } + + lseek(f->fd, raw_ofs, SEEK_SET); + + return is_write? write(f->fd, *p, raw_size) : read(f->fd, *p, raw_size); + } + + // sanity checks. if(is_write) { @@ -1328,21 +1346,6 @@ debug_out("file_io fd=%d size=%d ofs=%d\n", f->fd, raw_size, raw_ofs); } -int file_uncached_io(File* f, off_t ofs, size_t size, void* p) -{ - CHECK_FILE(f); - - int fd = f->fd; - - lseek(fd, ofs, SEEK_SET); - - if(f->flags & FILE_WRITE) - return write(fd, p, size); - else - return read(fd, p, size); -} - - /////////////////////////////////////////////////////////////////////////////// // // memory mapping diff --git a/source/lib/res/file.h b/source/lib/res/file.h index 318419fd60..f3e4317f81 100755 --- a/source/lib/res/file.h +++ b/source/lib/res/file.h @@ -54,10 +54,12 @@ enum FILE_MEM_READONLY = 0x02, // don't cache the whole file, e.g. if kept in memory elsewhere anyway. - FILE_NOCACHE = 0x04, + FILE_NO_CACHE = 0x04, // random access hint - FILE_RANDOM = 0x08 + FILE_RANDOM = 0x08, + + FILE_NO_AIO = 0x10 }; @@ -143,7 +145,5 @@ typedef ssize_t(*FILE_IO_CB)(uintptr_t ctx, void* p, size_t size); extern ssize_t file_io(File* f, off_t ofs, size_t size, void** p, FILE_IO_CB cb = 0, uintptr_t ctx = 0); -extern int file_uncached_io(File* f, off_t ofs, size_t size, void* p); - #endif // #ifndef FILE_H diff --git a/source/lib/res/tex.cpp b/source/lib/res/tex.cpp index 83862d3480..4c3bd2bff0 100755 --- a/source/lib/res/tex.cpp +++ b/source/lib/res/tex.cpp @@ -472,7 +472,7 @@ static int bmp_encode(TexInfo* t, const char* fn, const u8* img, size_t img_size bih->biClrImportant = 0; memcpy(file+hdr_size, img, img_size); - vfs_uncached_store(fn, file, file_size); + vfs_store(fn, file, file_size, FILE_NO_AIO); mem_free(file); return 0; } @@ -705,7 +705,7 @@ static void png_write(png_struct* const png_ptr, u8* const data, const png_size_ { void* p = (void*)data; Handle hf = *(Handle*)png_ptr->io_ptr; - if(vfs_uncached_io(hf, length, &p) != length) + if(vfs_io(hf, length, &p) != length) png_error(png_ptr, "png_write: !"); } @@ -759,7 +759,7 @@ fail: break; } - hf = vfs_open(fn, FILE_WRITE); + hf = vfs_open(fn, FILE_WRITE|FILE_NO_AIO); if(hf < 0) { err = (int)hf;