diff --git a/compressed_archive/unarr/compressed_archive.cpp b/compressed_archive/unarr/compressed_archive.cpp index 98709cb0..e03ac8ef 100644 --- a/compressed_archive/unarr/compressed_archive.cpp +++ b/compressed_archive/unarr/compressed_archive.cpp @@ -4,21 +4,22 @@ #include #include "extract_delegate.h" - -extern"C" { #include -} CompressedArchive::CompressedArchive(const QString & filePath, QObject *parent) : QObject(parent),valid(false),tools(true),numFiles(0),ar(NULL),stream(NULL) { //open file - stream = ar_open_file(filePath.toStdString().c_str()); + #ifdef Q_OS_WIN + stream = ar_open_file_w((wchar_t *)filePath.utf16()); + #else + stream = ar_open_file(filePath.toLocal8Bit().constData()); + #endif if (!stream) { return; } - + //open archive ar = ar_open_rar_archive(stream); //TODO: build unarr with 7z support and test this! @@ -30,9 +31,9 @@ CompressedArchive::CompressedArchive(const QString & filePath, QObject *parent) { return; } - + //initial parse - while (ar_parse_entry(ar)) + while (ar_parse_entry(ar)) { //make sure we really got a file header if (ar_entry_get_size(ar) > 0) @@ -43,7 +44,7 @@ CompressedArchive::CompressedArchive(const QString & filePath, QObject *parent) } } if (!ar_at_eof(ar)) - { + { //fail if the initial parse didn't reach EOF //this might be a bit too drastic qDebug() << "Error while parsing archive"; @@ -84,11 +85,11 @@ int CompressedArchive::getNumFiles() void CompressedArchive::getAllData(const QVector & indexes, ExtractDelegate * delegate) { - if (indexes.isEmpty()) + if (indexes.isEmpty()) return; - + QByteArray buffer; - + int i=0; while (i < indexes.count()) { @@ -102,7 +103,7 @@ void CompressedArchive::getAllData(const QVector & indexes, ExtractDele else { delegate->crcError(indexes.at(i)); //we could not extract it... - } + } i++; } } diff --git a/compressed_archive/unarr/unarr-wrapper.pri b/compressed_archive/unarr/unarr-wrapper.pri index be06f62a..4f54e409 100644 --- a/compressed_archive/unarr/unarr-wrapper.pri +++ b/compressed_archive/unarr/unarr-wrapper.pri @@ -6,10 +6,11 @@ HEADERS += $$PWD/extract_delegate.h \ SOURCES += $$PWD/compressed_archive.cpp \ -unix:!macx:exists (/usr/include/unarr.h) { +unix:!macx { message(Using system provided unarr installation) - LIBS+=-lunarr - DEFINES+=use_unarr + CONFIG += link_pkgconfig + PKGCONFIG += libunarr + DEFINES += use_unarr } else:macx:exists (../../dependencies/unarr/macx/libunarr.a) { message(Found prebuilt unarr library in dependencies directory.) @@ -19,22 +20,26 @@ else:macx:exists (../../dependencies/unarr/macx/libunarr.a) { } else:win32:exists (../../dependencies/unarr/win/unarr.h) { - message(Found prebuilt unarr library in dependencies directory.) - INCLUDEPATH += $$PWD/../../dependencies/unarr/win - LIBS += -L../../dependencies/unarr/win/ -lunarr - DEFINES+=use_unarr - } + message(Found prebuilt unarr library in dependencies directory.) + INCLUDEPATH += $$PWD/../../dependencies/unarr/win + contains(QMAKE_TARGET.arch, x86_64): { + LIBS += -L$$PWD/../../dependencies/unarr/win/x64 -lunarr + } else { + LIBS += -L$$PWD/../../dependencies/unarr/win/x86 -lunarr + } + DEFINES+=use_unarr UNARR_IS_SHARED_LIBRARY + } else:exists ($$PWD/unarr-master) { message(Found unarr source-code) message(Unarr will be build as a part of YACReader) - + #qmake based unarr build system #this should only be used for testing or as a last resort include(unarr.pro) DEFINES+=use_unarr } - else { +else { error(Missing dependency: unarr decrompression backend. Please install libunarr on your system\ or provide a copy of the unarr source code in compressed_archive/unarr/unarr-master) } diff --git a/config.pri b/config.pri index b72e464a..ddf87384 100644 --- a/config.pri +++ b/config.pri @@ -30,7 +30,7 @@ CONFIG(no_opengl) { CONFIG += unarr } win32 { - CONFIG += 7zip + CONFIG += unarr } } diff --git a/dependencies/unarr/macx/libunarr.a b/dependencies/unarr/macx/libunarr.a index 5a6992b7..955f6954 100644 Binary files a/dependencies/unarr/macx/libunarr.a and b/dependencies/unarr/macx/libunarr.a differ diff --git a/dependencies/unarr/macx/unarr.h b/dependencies/unarr/macx/unarr.h index 0400747c..4999fd55 100644 --- a/dependencies/unarr/macx/unarr.h +++ b/dependencies/unarr/macx/unarr.h @@ -4,9 +4,41 @@ #ifndef unarr_h #define unarr_h +#ifdef __cplusplus +extern "C" { +#endif + #include #include #include + + +/* macros for shared library usage */ + +#if defined (UNARR_IS_SHARED_LIBRARY) +#if defined (_WIN32) + +#if defined (UNARR_EXPORT_SYMBOLS) +#define UNARR_EXPORT __declspec(dllexport) +#else +#define UNARR_EXPORT __declspec(dllimport) +#endif // UNARR_EXPORT_SYMBOLS + +#else // _WIN32 + +#if defined (UNARR_EXPORT_SYMBOLS) +#define UNARR_EXPORT __attribute__((visibility("default"))) +#else +#define UNARR_EXPORT +#endif // UNARR_EXPORT_SYMBOLS +#endif // _WIN32 + +#else // defined UNARR_IS_SHARED_LIBRARY +#define UNARR_EXPORT + +#endif // UNARR_IS_SHARED_LIBRARY + + typedef int64_t off64_t; typedef int64_t time64_t; @@ -17,78 +49,82 @@ typedef int64_t time64_t; typedef struct ar_stream_s ar_stream; /* opens a read-only stream for the given file path; returns NULL on error */ -ar_stream *ar_open_file(const char *path); +UNARR_EXPORT ar_stream *ar_open_file(const char *path); #ifdef _WIN32 -ar_stream *ar_open_file_w(const wchar_t *path); +UNARR_EXPORT ar_stream *ar_open_file_w(const wchar_t *path); #endif /* opens a read-only stream for the given chunk of memory; the pointer must be valid until ar_close is called */ -ar_stream *ar_open_memory(const void *data, size_t datalen); +UNARR_EXPORT ar_stream *ar_open_memory(const void *data, size_t datalen); #ifdef _WIN32 typedef struct IStream IStream; /* opens a read-only stream based on the given IStream */ -ar_stream *ar_open_istream(IStream *stream); +UNARR_EXPORT ar_stream *ar_open_istream(IStream *stream); #endif /* closes the stream and releases underlying resources */ -void ar_close(ar_stream *stream); +UNARR_EXPORT void ar_close(ar_stream *stream); /* tries to read 'count' bytes into buffer, advancing the read offset pointer; returns the actual number of bytes read */ -size_t ar_read(ar_stream *stream, void *buffer, size_t count); +UNARR_EXPORT size_t ar_read(ar_stream *stream, void *buffer, size_t count); /* moves the read offset pointer (same as fseek); returns false on failure */ -bool ar_seek(ar_stream *stream, off64_t offset, int origin); +UNARR_EXPORT bool ar_seek(ar_stream *stream, off64_t offset, int origin); /* shortcut for ar_seek(stream, count, SEEK_CUR); returns false on failure */ -bool ar_skip(ar_stream *stream, off64_t count); +UNARR_EXPORT bool ar_skip(ar_stream *stream, off64_t count); /* returns the current read offset (or 0 on error) */ -off64_t ar_tell(ar_stream *stream); +UNARR_EXPORT off64_t ar_tell(ar_stream *stream); /***** common/unarr *****/ typedef struct ar_archive_s ar_archive; /* frees all data stored for the given archive; does not close the underlying stream */ -void ar_close_archive(ar_archive *ar); +UNARR_EXPORT void ar_close_archive(ar_archive *ar); /* reads the next archive entry; returns false on error or at the end of the file (use ar_at_eof to distinguish the two cases) */ -bool ar_parse_entry(ar_archive *ar); +UNARR_EXPORT bool ar_parse_entry(ar_archive *ar); /* reads the archive entry at the given offset as returned by ar_entry_get_offset (offset 0 always restarts at the first entry); should always succeed */ -bool ar_parse_entry_at(ar_archive *ar, off64_t offset); +UNARR_EXPORT bool ar_parse_entry_at(ar_archive *ar, off64_t offset); /* reads the (first) archive entry associated with the given name; returns false if the entry couldn't be found */ -bool ar_parse_entry_for(ar_archive *ar, const char *entry_name); +UNARR_EXPORT bool ar_parse_entry_for(ar_archive *ar, const char *entry_name); /* returns whether the last ar_parse_entry call has reached the file's expected end */ -bool ar_at_eof(ar_archive *ar); +UNARR_EXPORT bool ar_at_eof(ar_archive *ar); /* returns the name of the current entry as UTF-8 string; this pointer is only valid until the next call to ar_parse_entry; returns NULL on failure */ -const char *ar_entry_get_name(ar_archive *ar); +UNARR_EXPORT const char *ar_entry_get_name(ar_archive *ar); /* returns the stream offset of the current entry for use with ar_parse_entry_at */ -off64_t ar_entry_get_offset(ar_archive *ar); +UNARR_EXPORT off64_t ar_entry_get_offset(ar_archive *ar); /* returns the total size of uncompressed data of the current entry; read exactly that many bytes using ar_entry_uncompress */ -size_t ar_entry_get_size(ar_archive *ar); +UNARR_EXPORT size_t ar_entry_get_size(ar_archive *ar); /* returns the stored modification date of the current entry in 100ns since 1601/01/01 */ -time64_t ar_entry_get_filetime(ar_archive *ar); +UNARR_EXPORT time64_t ar_entry_get_filetime(ar_archive *ar); /* WARNING: don't manually seek in the stream between ar_parse_entry and the last corresponding ar_entry_uncompress call! */ /* uncompresses the next 'count' bytes of the current entry into buffer; returns false on error */ -bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count); +UNARR_EXPORT bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count); /* copies at most 'count' bytes of the archive's global comment (if any) into buffer; returns the actual amout of bytes copied (or, if 'buffer' is NULL, the required buffer size) */ -size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count); +UNARR_EXPORT size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count); /***** rar/rar *****/ /* checks whether 'stream' could contain RAR data and prepares for archive listing/extraction; returns NULL on failure */ -ar_archive *ar_open_rar_archive(ar_stream *stream); +UNARR_EXPORT ar_archive *ar_open_rar_archive(ar_stream *stream); /***** tar/tar *****/ /* checks whether 'stream' could contain TAR data and prepares for archive listing/extraction; returns NULL on failure */ -ar_archive *ar_open_tar_archive(ar_stream *stream); +UNARR_EXPORT ar_archive *ar_open_tar_archive(ar_stream *stream); /***** zip/zip *****/ /* checks whether 'stream' could contain ZIP data and prepares for archive listing/extraction; returns NULL on failure */ /* set deflatedonly for extracting XPS, EPUB, etc. documents where non-Deflate compression methods are not supported by specification */ -ar_archive *ar_open_zip_archive(ar_stream *stream, bool deflatedonly); +UNARR_EXPORT ar_archive *ar_open_zip_archive(ar_stream *stream, bool deflatedonly); /***** _7z/_7z *****/ /* checks whether 'stream' could contain 7Z data and prepares for archive listing/extraction; returns NULL on failure */ -ar_archive *ar_open_7z_archive(ar_stream *stream); +UNARR_EXPORT ar_archive *ar_open_7z_archive(ar_stream *stream); +#ifdef __cplusplus +} #endif + +#endif //unarr_h diff --git a/dependencies/unarr/win/unarr.h b/dependencies/unarr/win/unarr.h new file mode 100644 index 00000000..4999fd55 --- /dev/null +++ b/dependencies/unarr/win/unarr.h @@ -0,0 +1,130 @@ +/* Copyright 2015 the unarr project authors (see AUTHORS file). + License: LGPLv3 */ + +#ifndef unarr_h +#define unarr_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + + +/* macros for shared library usage */ + +#if defined (UNARR_IS_SHARED_LIBRARY) +#if defined (_WIN32) + +#if defined (UNARR_EXPORT_SYMBOLS) +#define UNARR_EXPORT __declspec(dllexport) +#else +#define UNARR_EXPORT __declspec(dllimport) +#endif // UNARR_EXPORT_SYMBOLS + +#else // _WIN32 + +#if defined (UNARR_EXPORT_SYMBOLS) +#define UNARR_EXPORT __attribute__((visibility("default"))) +#else +#define UNARR_EXPORT +#endif // UNARR_EXPORT_SYMBOLS +#endif // _WIN32 + +#else // defined UNARR_IS_SHARED_LIBRARY +#define UNARR_EXPORT + +#endif // UNARR_IS_SHARED_LIBRARY + + +typedef int64_t off64_t; +typedef int64_t time64_t; + +#define UNARR_API_VERSION 100 + +/***** common/stream *****/ + +typedef struct ar_stream_s ar_stream; + +/* opens a read-only stream for the given file path; returns NULL on error */ +UNARR_EXPORT ar_stream *ar_open_file(const char *path); +#ifdef _WIN32 +UNARR_EXPORT ar_stream *ar_open_file_w(const wchar_t *path); +#endif +/* opens a read-only stream for the given chunk of memory; the pointer must be valid until ar_close is called */ +UNARR_EXPORT ar_stream *ar_open_memory(const void *data, size_t datalen); +#ifdef _WIN32 +typedef struct IStream IStream; +/* opens a read-only stream based on the given IStream */ +UNARR_EXPORT ar_stream *ar_open_istream(IStream *stream); +#endif + +/* closes the stream and releases underlying resources */ +UNARR_EXPORT void ar_close(ar_stream *stream); +/* tries to read 'count' bytes into buffer, advancing the read offset pointer; returns the actual number of bytes read */ +UNARR_EXPORT size_t ar_read(ar_stream *stream, void *buffer, size_t count); +/* moves the read offset pointer (same as fseek); returns false on failure */ +UNARR_EXPORT bool ar_seek(ar_stream *stream, off64_t offset, int origin); +/* shortcut for ar_seek(stream, count, SEEK_CUR); returns false on failure */ +UNARR_EXPORT bool ar_skip(ar_stream *stream, off64_t count); +/* returns the current read offset (or 0 on error) */ +UNARR_EXPORT off64_t ar_tell(ar_stream *stream); + +/***** common/unarr *****/ + +typedef struct ar_archive_s ar_archive; + +/* frees all data stored for the given archive; does not close the underlying stream */ +UNARR_EXPORT void ar_close_archive(ar_archive *ar); +/* reads the next archive entry; returns false on error or at the end of the file (use ar_at_eof to distinguish the two cases) */ +UNARR_EXPORT bool ar_parse_entry(ar_archive *ar); +/* reads the archive entry at the given offset as returned by ar_entry_get_offset (offset 0 always restarts at the first entry); should always succeed */ +UNARR_EXPORT bool ar_parse_entry_at(ar_archive *ar, off64_t offset); +/* reads the (first) archive entry associated with the given name; returns false if the entry couldn't be found */ +UNARR_EXPORT bool ar_parse_entry_for(ar_archive *ar, const char *entry_name); +/* returns whether the last ar_parse_entry call has reached the file's expected end */ +UNARR_EXPORT bool ar_at_eof(ar_archive *ar); + +/* returns the name of the current entry as UTF-8 string; this pointer is only valid until the next call to ar_parse_entry; returns NULL on failure */ +UNARR_EXPORT const char *ar_entry_get_name(ar_archive *ar); +/* returns the stream offset of the current entry for use with ar_parse_entry_at */ +UNARR_EXPORT off64_t ar_entry_get_offset(ar_archive *ar); +/* returns the total size of uncompressed data of the current entry; read exactly that many bytes using ar_entry_uncompress */ +UNARR_EXPORT size_t ar_entry_get_size(ar_archive *ar); +/* returns the stored modification date of the current entry in 100ns since 1601/01/01 */ +UNARR_EXPORT time64_t ar_entry_get_filetime(ar_archive *ar); +/* WARNING: don't manually seek in the stream between ar_parse_entry and the last corresponding ar_entry_uncompress call! */ +/* uncompresses the next 'count' bytes of the current entry into buffer; returns false on error */ +UNARR_EXPORT bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count); + +/* copies at most 'count' bytes of the archive's global comment (if any) into buffer; returns the actual amout of bytes copied (or, if 'buffer' is NULL, the required buffer size) */ +UNARR_EXPORT size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count); + +/***** rar/rar *****/ + +/* checks whether 'stream' could contain RAR data and prepares for archive listing/extraction; returns NULL on failure */ +UNARR_EXPORT ar_archive *ar_open_rar_archive(ar_stream *stream); + +/***** tar/tar *****/ + +/* checks whether 'stream' could contain TAR data and prepares for archive listing/extraction; returns NULL on failure */ +UNARR_EXPORT ar_archive *ar_open_tar_archive(ar_stream *stream); + +/***** zip/zip *****/ + +/* checks whether 'stream' could contain ZIP data and prepares for archive listing/extraction; returns NULL on failure */ +/* set deflatedonly for extracting XPS, EPUB, etc. documents where non-Deflate compression methods are not supported by specification */ +UNARR_EXPORT ar_archive *ar_open_zip_archive(ar_stream *stream, bool deflatedonly); + +/***** _7z/_7z *****/ + +/* checks whether 'stream' could contain 7Z data and prepares for archive listing/extraction; returns NULL on failure */ +UNARR_EXPORT ar_archive *ar_open_7z_archive(ar_stream *stream); + +#ifdef __cplusplus +} +#endif + +#endif //unarr_h diff --git a/dependencies/unarr/win/x64/unarr.dll b/dependencies/unarr/win/x64/unarr.dll new file mode 100644 index 00000000..02ba76bb Binary files /dev/null and b/dependencies/unarr/win/x64/unarr.dll differ diff --git a/dependencies/unarr/win/x64/unarr.lib b/dependencies/unarr/win/x64/unarr.lib new file mode 100644 index 00000000..8307c439 Binary files /dev/null and b/dependencies/unarr/win/x64/unarr.lib differ diff --git a/dependencies/unarr/win/x86/unarr.dll b/dependencies/unarr/win/x86/unarr.dll new file mode 100644 index 00000000..8d04bddb Binary files /dev/null and b/dependencies/unarr/win/x86/unarr.dll differ diff --git a/dependencies/unarr/win/x86/unarr.lib b/dependencies/unarr/win/x86/unarr.lib new file mode 100644 index 00000000..d19b74cd Binary files /dev/null and b/dependencies/unarr/win/x86/unarr.lib differ