diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/replicant/nx/win/NXZipFile.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/replicant/nx/win/NXZipFile.cpp')
-rw-r--r-- | Src/replicant/nx/win/NXZipFile.cpp | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/Src/replicant/nx/win/NXZipFile.cpp b/Src/replicant/nx/win/NXZipFile.cpp new file mode 100644 index 00000000..71b00a51 --- /dev/null +++ b/Src/replicant/nx/win/NXZipFile.cpp @@ -0,0 +1,209 @@ +#include "NXFileObject.h" +#include <new> +#include "minizip/unzip.h" +#include <nx/nxfile.h> +#include <assert.h> + +class NXZipFile : NXFileObject +{ +public: + NXZipFile(unzFile zip_file); + ~NXZipFile(); + + /* NXFileObject implementation */ + ns_error_t Read(void *buffer, size_t bytes_requested, size_t *bytes_read); + ns_error_t Write(const void *buffer, size_t bytes); + ns_error_t Seek(uint64_t position); + ns_error_t Tell(uint64_t *position); + ns_error_t PeekByte(uint8_t *byte); + ns_error_t Sync(); + ns_error_t Truncate(); + // TODO(benski) implementation EOF + // TODO(benski) implement region locking +private: + unzFile zip_file; +}; + +NXZipFile::NXZipFile(unzFile zip_file) : zip_file(zip_file) +{ +} + +NXZipFile::~NXZipFile() +{ + if (zip_file) { + unzCloseCurrentFile(zip_file); + unzClose(zip_file); + zip_file=0; + } +} + +/* NXFileObject implementation */ +ns_error_t NXZipFile::Read(void *buffer, size_t bytes_requested, size_t *bytes_read) +{ + int zret = unzReadCurrentFile(zip_file, buffer, (unsigned int)bytes_requested); + if (zret == 0) { + if (bytes_read) { + *bytes_read = 0; + } + return NErr_EndOfFile; + } else if (zret > 0) { + if (bytes_read) { + *bytes_read = (size_t)zret; + } + return NErr_Success; + } else { + if (bytes_read) { + *bytes_read = 0; + } + return NErr_Error; + } +} + +ns_error_t NXZipFile::Write(const void *buffer, size_t bytes) +{ + return NErr_NotImplemented; +} + +ns_error_t NXZipFile::Seek(uint64_t position) +{ + // TODO(benski) error check) + unzSetOffset64(zip_file, position); + return NErr_Success; +} + +ns_error_t NXZipFile::Tell(uint64_t *position) +{ + *position = unzGetOffset64(zip_file); + return NErr_Success; +} + +ns_error_t NXZipFile::PeekByte(uint8_t *byte) +{ + return NErr_NotImplemented; +} + +ns_error_t NXZipFile::Sync() +{ + return NErr_NotImplemented; +} + +ns_error_t NXZipFile::Truncate() +{ + return NErr_NotImplemented; +} + +static voidpf ZCALLBACK unzip_nxfile_open OF((voidpf opaque, const void* filename, int mode)) +{ + nx_file_t f; + if (NXFileOpenFile(&f, (nx_uri_t)filename, nx_file_FILE_read_binary) != NErr_Success) { + return 0; + } + return f; +} + +static uLong ZCALLBACK unzip_nxfile_read OF((voidpf opaque, voidpf stream, void* buf, uLong size)) +{ + nx_file_t f = (nx_file_t)stream; + size_t bytes_read; + if (NXFileRead(f, buf, size, &bytes_read) != NErr_Success) { + return 0; + } + return (uLong)bytes_read; +} + +static int ZCALLBACK unzip_nxfile_close OF((voidpf opaque, voidpf stream)) +{ + NXFileRelease((nx_file_t)stream); + return 0; +} + + +static ZPOS64_T ZCALLBACK unzip_nxfile_tell OF((voidpf opaque, voidpf stream)) +{ + nx_file_t f = (nx_file_t)stream; + uint64_t position; + if (NXFileTell(f, &position) == NErr_Success) { + return (int64_t)position; + } else { + return -1; + } +} + +static long ZCALLBACK unzip_nxfile_seek OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int whence)) +{ + nx_file_t f = (nx_file_t)stream; + uint64_t position; + if (whence == SEEK_SET) { + position = offset; + } else if (whence == SEEK_CUR) { + ns_error_t err = NXFileTell(f, &position); + if (err != NErr_Success) { + return -1; + } + position += offset; + } else if (whence == SEEK_END) { + uint64_t length; + NXFileLength(f, &length); + position = length + offset; + } else { + return -1; + } + ns_error_t err = NXFileSeek(f, position); + if (err == NErr_Success) { + return 0; + } else { + return -1; + } +} +#if 0 + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; +#endif + +ns_error_t NXFileOpenZip(nx_file_t *out_file, nx_uri_t filename, nx_string_t extension_hint) +{ +#if 0 + typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; +#endif + + zlib_filefunc64_def file_func = {0, }; + file_func.zopen64_file = unzip_nxfile_open; + file_func.zread_file = unzip_nxfile_read; + file_func.ztell64_file = unzip_nxfile_tell; + file_func.zseek64_file = unzip_nxfile_seek; + file_func.zclose_file = unzip_nxfile_close; + + unzFile zip_file = unzOpen2_64(filename, &file_func); + if (zip_file == NULL) { + return NErr_Error; + } + + unzGoToFirstFile(zip_file); + // TODO(benski): look for filename with extension_hint as extension + // TODO(benski): search for anything with extension + unzOpenCurrentFile(zip_file); + + NXZipFile *nx_zip_file = new (std::nothrow) NXZipFile(zip_file); + if (!nx_zip_file) { + unzCloseCurrentFile(zip_file); + unzClose(zip_file); + return NErr_OutOfMemory; + } + *out_file = (nx_file_t)nx_zip_file; + return NErr_Success; +} |