Commit 55ed3cc4 authored by Jean-Philip Desjardins's avatar Jean-Philip Desjardins
Browse files

Initial 7z support.

parent 27c33b42
......@@ -13,6 +13,7 @@ set(PSF_PROJECT_NAME "PsfPlayer")
set(PSF_PROJECT_VERSION "1.05")
set(PSF_DEFINITIONS)
set(PSF_RAR_SUPPORT ON)
set(PSF_7Z_SUPPORT ON)
if(NOT TARGET PlayCore)
add_subdirectory(
......@@ -46,6 +47,16 @@ if(PSF_RAR_SUPPORT)
list(APPEND PROJECT_LIBS unrar)
endif()
if(PSF_7Z_SUPPORT)
if(NOT TARGET lzmasdk)
add_subdirectory(
${CMAKE_CURRENT_SOURCE_DIR}/../../../../Dependencies/build_cmake/lzmasdk-18.05
${CMAKE_CURRENT_BINARY_DIR}/lzmasdk-18.05
)
endif()
list(APPEND PROJECT_LIBS lzmasdk)
endif()
##PsfPlayerCore
set(PSFCORE_SRC_FILES
AppConfig.cpp
......@@ -81,6 +92,10 @@ if(PSF_RAR_SUPPORT)
list(APPEND PSFCORE_SRC_FILES PsfRarArchive.cpp)
list(APPEND PSF_DEFINITIONS -DRAR_SUPPORT)
endif()
if(PSF_7Z_SUPPORT)
list(APPEND PSFCORE_SRC_FILES Psf7zArchive.cpp)
list(APPEND PSF_DEFINITIONS -DSZ_SUPPORT)
endif()
if(TARGET_PLATFORM_MACOS)
set(PSFCORE_PLATFORM_SPECIFIC_SRC_FILES macosx_ui/PsfPlayer_Prefix.pch)
......
#include "Psf7zArchive.h"
#include <7zCrc.h>
#define kInputBufSize ((size_t)1 << 18)
static const ISzAlloc g_allocImp = { &SzAlloc, &SzFree };
static std::string ConvertUtf16ToAnsi(const std::vector<UInt16>& input)
{
std::string result;
for(int i = 0; i < input.size(); i++)
{
UInt16 inputChar = input[i];
if(inputChar == 0) break;
result += static_cast<char>(inputChar);
}
return result;
}
static std::string GetSzEntryFileName(CSzArEx* db, int entryIndex)
{
size_t len = SzArEx_GetFileNameUtf16(db, entryIndex, NULL);
std::vector<UInt16> wideFileName;
wideFileName.resize(len);
SzArEx_GetFileNameUtf16(db, entryIndex, wideFileName.data());
return ConvertUtf16ToAnsi(wideFileName);
}
CPsf7zArchive::CPsf7zArchive()
{
CrcGenerateTable();
//Initialize m_archiveStream
FileInStream_CreateVTable(&m_archiveStream);
File_Construct(&m_archiveStream.file);
//Initialize m_lookStream
LookToRead2_CreateVTable(&m_lookStream, False);
m_lookStream.buf = nullptr;
//Initialize m_archive
SzArEx_Init(&m_archive);
}
CPsf7zArchive::~CPsf7zArchive()
{
ISzAlloc_Free(&g_allocImp, m_outBuffer);
SzArEx_Free(&m_archive, &g_allocImp);
ISzAlloc_Free(&g_allocImp, m_lookStream.buf);
File_Close(&m_archiveStream.file);
}
void CPsf7zArchive::Open(const boost::filesystem::path& filePath)
{
if(InFile_Open(&m_archiveStream.file, filePath.string().c_str()))
{
throw std::runtime_error("Failed to open file.");
}
m_lookStream.buf = reinterpret_cast<Byte*>(ISzAlloc_Alloc(&g_allocImp, kInputBufSize));
m_lookStream.bufSize = kInputBufSize;
m_lookStream.realStream = &m_archiveStream.vt;
LookToRead2_Init(&m_lookStream);
SRes res = SzArEx_Open(&m_archive, &m_lookStream.vt, &g_allocImp, &g_allocImp);
if(res != SZ_OK)
{
throw std::runtime_error("Failed to open file.");
}
for(int i = 0; i < m_archive.NumFiles; i++)
{
unsigned isDir = SzArEx_IsDir(&m_archive, i);
if(isDir) continue;
FILEINFO fileInfo;
fileInfo.name = GetSzEntryFileName(&m_archive, i);
fileInfo.length = SzArEx_GetFileSize(&m_archive, i);
m_files.push_back(fileInfo);
}
}
void CPsf7zArchive::ReadFileContents(const char* fileName, void* buffer, unsigned int bufferLength)
{
int entryIndex =
[&] ()
{
for(int i = 0; i < m_archive.NumFiles; i++)
{
auto entryFileName = GetSzEntryFileName(&m_archive, i);
if(entryFileName.compare(fileName) == 0) return i;
}
return -1;
}();
if(entryIndex == -1)
{
throw std::runtime_error("Entry not found.");
}
size_t offset = 0;
size_t outSizeProcessed = 0;
SRes res = SzArEx_Extract(&m_archive, &m_lookStream.vt, entryIndex, &m_blockIndex, &m_outBuffer, &m_outBufferSize, &offset, &outSizeProcessed, &g_allocImp, &g_allocImp);
if(bufferLength != outSizeProcessed)
{
throw std::runtime_error("Entry size mismatch.");
}
memcpy(buffer, m_outBuffer + offset, outSizeProcessed);
}
#pragma once
#include <7z.h>
#include <7zAlloc.h>
#include <7zBuf.h>
#include <7zFile.h>
#include "PsfArchive.h"
class CPsf7zArchive : public CPsfArchive
{
public:
CPsf7zArchive();
virtual ~CPsf7zArchive();
void Open(const boost::filesystem::path&) override;
void ReadFileContents(const char*, void*, unsigned int) override;
private:
CFileInStream m_archiveStream;
CLookToRead2 m_lookStream;
CSzArEx m_archive;
UInt32 m_blockIndex = 0xFFFFFFFF;
Byte* m_outBuffer = nullptr;
size_t m_outBufferSize = 0;
};
......@@ -3,6 +3,9 @@
#include "PsfRarArchive.h"
#endif
#include "PsfZipArchive.h"
#ifdef SZ_SUPPORT
#include "Psf7zArchive.h"
#endif
#include "stricmp.h"
#include "make_unique.h"
......@@ -19,6 +22,12 @@ CPsfArchive::PsfArchivePtr CPsfArchive::CreateFromPath(const boost::filesystem::
{
result = std::make_unique<CPsfRarArchive>();
}
#endif
#ifdef SZ_SUPPORT
else if(!strcmp(extension.c_str(), ".7z"))
{
result = std::make_unique<CPsf7zArchive>();
}
#endif
else
{
......
......@@ -26,7 +26,7 @@
#define PSF_FILTER _T("PlayStation Sound Files (*.psf; *.minipsf)\0*.psf; *.minipsf\0")
#define PSF2_FILTER _T("PlayStation2 Sound Files (*.psf2; *.minipsf2)\0*.psf2; *.minipsf2\0")
#define PSFP_FILTER _T("PlayStation Portable Sound Files (*.psfp; *.minipsfp)\0*.psfp; *.minipsfp\0")
#define ARCHIVE_FILTER _T("Archived Sound Files (*.zip; *.rar)\0*.zip;*.rar\0")
#define ARCHIVE_FILTER _T("Archived Sound Files (*.zip; *.rar; *.7z)\0*.zip;*.rar\0")
#define TEXT_PLAY _T("Play")
#define TEXT_PAUSE _T("Pause")
......@@ -886,7 +886,7 @@ void CMainWindow::OnFileOpen()
{
Framework::Win32::CFileDialog dialog;
const TCHAR* filter =
_T("All Supported Files\0*.zip; *.rar; *.psf; *.minipsf; *.psf2; *.minipsf2; *.psfp; *.minipsfp;*") PLAYLIST_EXTENSION _T("\0") PLAYLIST_FILTER
_T("All Supported Files\0*.zip; *.rar; *.7z; *.psf; *.minipsf; *.psf2; *.minipsf2; *.psfp; *.minipsfp;*") PLAYLIST_EXTENSION _T("\0") PLAYLIST_FILTER
ARCHIVE_FILTER
PSF_FILTER
PSF2_FILTER
......@@ -900,7 +900,11 @@ void CMainWindow::OnFileOpen()
{
LoadPlaylist(filePath);
}
else if(!wcsicmp(fileExtension.c_str(), L".rar") || !wcsicmp(fileExtension.c_str(), L".zip"))
else if(
!wcsicmp(fileExtension.c_str(), L".rar") ||
!wcsicmp(fileExtension.c_str(), L".zip") ||
!wcsicmp(fileExtension.c_str(), L".7z")
)
{
LoadArchive(filePath);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment