diff --git a/src/gba/gba-savedata.c b/src/gba/gba-savedata.c index 83b0cb834..d1f39441f 100644 --- a/src/gba/gba-savedata.c +++ b/src/gba/gba-savedata.c @@ -142,7 +142,7 @@ void GBASavedataInitFlash(struct GBASavedata* savedata) { end = 0; savedata->data = anonymousMemoryMap(SIZE_CART_FLASH1M); } else { - end = savedata->vf->seek(savedata->vf, 0, SEEK_END); + end = savedata->vf->size(savedata->vf); if (end < SIZE_CART_FLASH512) { savedata->vf->truncate(savedata->vf, SIZE_CART_FLASH1M); flashSize = SIZE_CART_FLASH1M; @@ -168,7 +168,7 @@ void GBASavedataInitEEPROM(struct GBASavedata* savedata) { end = 0; savedata->data = anonymousMemoryMap(SIZE_CART_EEPROM); } else { - end = savedata->vf->seek(savedata->vf, 0, SEEK_END); + end = savedata->vf->size(savedata->vf); if (end < SIZE_CART_EEPROM) { savedata->vf->truncate(savedata->vf, SIZE_CART_EEPROM); } @@ -191,7 +191,7 @@ void GBASavedataInitSRAM(struct GBASavedata* savedata) { end = 0; savedata->data = anonymousMemoryMap(SIZE_CART_SRAM); } else { - end = savedata->vf->seek(savedata->vf, 0, SEEK_END); + end = savedata->vf->size(savedata->vf); if (end < SIZE_CART_SRAM) { savedata->vf->truncate(savedata->vf, SIZE_CART_SRAM); } diff --git a/src/gba/gba.c b/src/gba/gba.c index 922c84f3a..2fec3604a 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -445,7 +445,7 @@ void GBADetachDebugger(struct GBA* gba) { void GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char* fname) { gba->romVf = vf; - gba->pristineRomSize = vf->seek(vf, 0, SEEK_END); + gba->pristineRomSize = vf->size(vf); vf->seek(vf, 0, SEEK_SET); if (gba->pristineRomSize > SIZE_CART0) { gba->pristineRomSize = SIZE_CART0; diff --git a/src/platform/qt/VFileDevice.cpp b/src/platform/qt/VFileDevice.cpp index bf3e41982..62597a50b 100644 --- a/src/platform/qt/VFileDevice.cpp +++ b/src/platform/qt/VFileDevice.cpp @@ -27,9 +27,5 @@ qint64 VFileDevice::writeData(const char* data, qint64 maxSize) { } qint64 VFileDevice::size() const { - // TODO: Add size method to VFile so this can be actually const - ssize_t pos = m_vf->seek(m_vf, 0, SEEK_CUR); - qint64 size = m_vf->seek(m_vf, 0, SEEK_END); - m_vf->seek(m_vf, pos, SEEK_SET); - return size; + return m_vf->size(m_vf); } diff --git a/src/util/patch-ups.c b/src/util/patch-ups.c index 33f71cee2..f7fa1c4e6 100644 --- a/src/util/patch-ups.c +++ b/src/util/patch-ups.c @@ -31,7 +31,7 @@ bool loadPatchUPS(struct Patch* patch) { return false; } - size_t filesize = patch->vf->seek(patch->vf, 0, SEEK_END); + size_t filesize = patch->vf->size(patch->vf); uint32_t goodCrc32; patch->vf->seek(patch->vf, PATCH_CHECKSUM, SEEK_END); @@ -61,7 +61,7 @@ size_t _UPSOutputSize(struct Patch* patch, size_t inSize) { bool _UPSApplyPatch(struct Patch* patch, void* out, size_t outSize) { // TODO: Input checksum - size_t filesize = patch->vf->seek(patch->vf, 0, SEEK_END); + size_t filesize = patch->vf->size(patch->vf); patch->vf->seek(patch->vf, 4, SEEK_SET); _UPSDecodeLength(patch->vf); // Discard input size if (_UPSDecodeLength(patch->vf) != outSize) { diff --git a/src/util/vfs.c b/src/util/vfs.c index b50f610ad..55e7ec874 100644 --- a/src/util/vfs.c +++ b/src/util/vfs.c @@ -9,6 +9,7 @@ #include #include +#include #ifndef _WIN32 #include @@ -35,6 +36,7 @@ static ssize_t _vfdWrite(struct VFile* vf, const void* buffer, size_t size); static void* _vfdMap(struct VFile* vf, size_t size, int flags); static void _vfdUnmap(struct VFile* vf, void* memory, size_t size); static void _vfdTruncate(struct VFile* vf, size_t size); +static ssize_t _vfdSize(struct VFile* vf); static bool _vdClose(struct VDir* vd); static void _vdRewind(struct VDir* vd); @@ -73,6 +75,7 @@ struct VFile* VFileFromFD(int fd) { vfd->d.map = _vfdMap; vfd->d.unmap = _vfdUnmap; vfd->d.truncate = _vfdTruncate; + vfd->d.size = _vfdSize; return &vfd->d; } @@ -137,9 +140,12 @@ static void* _vfdMap(struct VFile* vf, size_t size, int flags) { createFlags = PAGE_READWRITE; mapFiles = FILE_MAP_WRITE; } - size_t location = lseek(vfd->fd, 0, SEEK_CUR); - size_t fileSize = lseek(vfd->fd, 0, SEEK_END); - lseek(vfd->fd, location, SEEK_SET); + size_t fileSize; + struct stat stat; + if (fstat(vfd->fd, &stat) < 0) { + return 0; + } + fileSize = stat.st_size; if (size > fileSize) { size = fileSize; } @@ -161,6 +167,15 @@ static void _vfdTruncate(struct VFile* vf, size_t size) { ftruncate(vfd->fd, size); } +static ssize_t _vfdSize(struct VFile* vf) { + struct VFileFD* vfd = (struct VFileFD*) vf; + struct stat stat; + if (fstat(vfd->fd, &stat) < 0) { + return -1; + } + return stat.st_size; +} + struct VDirEntryDE { struct VDirEntry d; struct dirent* ent; diff --git a/src/util/vfs.h b/src/util/vfs.h index 1ce7798fb..3394317c7 100644 --- a/src/util/vfs.h +++ b/src/util/vfs.h @@ -22,6 +22,7 @@ struct VFile { void* (*map)(struct VFile* vf, size_t size, int flags); void (*unmap)(struct VFile* vf, void* memory, size_t size); void (*truncate)(struct VFile* vf, size_t size); + ssize_t (*size)(struct VFile* vf); }; struct VDirEntry { diff --git a/src/util/vfs/vfs-zip.c b/src/util/vfs/vfs-zip.c index 182cfe256..02e6216fe 100644 --- a/src/util/vfs/vfs-zip.c +++ b/src/util/vfs/vfs-zip.c @@ -43,6 +43,7 @@ static ssize_t _vfzWrite(struct VFile* vf, const void* buffer, size_t size); static void* _vfzMap(struct VFile* vf, size_t size, int flags); static void _vfzUnmap(struct VFile* vf, void* memory, size_t size); static void _vfzTruncate(struct VFile* vf, size_t size); +static ssize_t _vfzSize(struct VFile* vf); static bool _vdzClose(struct VDir* vd); static void _vdzRewind(struct VDir* vd); @@ -229,6 +230,11 @@ void _vfzTruncate(struct VFile* vf, size_t size) { UNUSED(size); } +ssize_t _vfzSize(struct VFile* vf) { + struct VFileZip* vfz = (struct VFileZip*) vf; + return vfz->fileSize; +} + bool _vdzClose(struct VDir* vd) { struct VDirZip* vdz = (struct VDirZip*) vd; if (zip_close(vdz->z) < 0) { @@ -295,6 +301,7 @@ struct VFile* _vdzOpenFile(struct VDir* vd, const char* path, int mode) { vfz->d.map = _vfzMap; vfz->d.unmap = _vfzUnmap; vfz->d.truncate = _vfzTruncate; + vfz->d.size = _vfzSize; return &vfz->d; }