mirror of
https://github.com/1dot13/source.git
synced 2026-08-12 14:10:23 +02:00
- Added missing projects "VFS" & "export" to SVN
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4447 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* bfVFS : vfs/Ext/7z/vfs_7z_library.cpp
|
||||
* - implements Library interface, creates library object from uncompressed 7-zip archive files
|
||||
*
|
||||
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
|
||||
*
|
||||
* This file is part of the bfVFS library
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef VFS_WITH_7ZIP
|
||||
|
||||
#include <vfs/Ext/7z/vfs_7z_library.h>
|
||||
#include <vfs/Core/Location/vfs_lib_dir.h>
|
||||
#include <vfs/Core/File/vfs_lib_file.h>
|
||||
#include <vfs/Core/vfs_file_raii.h>
|
||||
|
||||
namespace sz
|
||||
{
|
||||
extern "C"
|
||||
{
|
||||
#include <7z.h>
|
||||
#include <7zCrc.h>
|
||||
#include <7zAlloc.h>
|
||||
//#include <Archive/7z/7zAlloc.h>
|
||||
//#include <Archive/7z/7zExtract.h>
|
||||
//#include <Archive/7z/7zIn.h>
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
/*** my 7z extensions ***/
|
||||
/********************************************************************************************/
|
||||
|
||||
namespace szExt
|
||||
{
|
||||
typedef struct CSzVfsFile
|
||||
{
|
||||
vfs::tReadableFile* file;
|
||||
} CSzVfsFile;
|
||||
|
||||
typedef struct CVfsFileInStream
|
||||
{
|
||||
sz::ISeekInStream s;
|
||||
CSzVfsFile file;
|
||||
} CVfsFileInStream;
|
||||
|
||||
|
||||
static sz::SRes VfsFileInStream_Read(void *pp, void *buf, ::size_t *size)
|
||||
{
|
||||
CVfsFileInStream *p = (CVfsFileInStream *)pp;
|
||||
::size_t to_read = *size;
|
||||
sz::SRes res;
|
||||
try
|
||||
{
|
||||
*size = (::size_t)p->file.file->read((vfs::Byte*)buf,to_read);
|
||||
res = SZ_OK;
|
||||
}
|
||||
catch(std::exception &ex)
|
||||
{
|
||||
VFS_LOG_ERROR(ex.what());
|
||||
res = SZ_ERROR_READ;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static sz::SRes VfsFileInStream_Seek(void *pp, sz::Int64 *pos, sz::ESzSeek origin)
|
||||
{
|
||||
CVfsFileInStream *p = (CVfsFileInStream *)pp;
|
||||
|
||||
vfs::IBaseFile::ESeekDir eSD;
|
||||
switch (origin)
|
||||
{
|
||||
case sz::SZ_SEEK_SET:
|
||||
eSD = vfs::IBaseFile::SD_BEGIN;
|
||||
break;
|
||||
case sz::SZ_SEEK_CUR:
|
||||
eSD = vfs::IBaseFile::SD_CURRENT;
|
||||
break;
|
||||
case sz::SZ_SEEK_END:
|
||||
eSD = vfs::IBaseFile::SD_END;
|
||||
break;
|
||||
default:
|
||||
return SZ_ERROR_PARAM;
|
||||
}
|
||||
vfs::offset_t _pos = (vfs::offset_t)(*pos);
|
||||
sz::SRes res;
|
||||
try
|
||||
{
|
||||
p->file.file->setReadPosition(_pos,eSD);
|
||||
*pos = p->file.file->getReadPosition();
|
||||
res = SZ_OK;
|
||||
}
|
||||
catch(std::exception& ex)
|
||||
{
|
||||
VFS_LOG_ERROR(ex.what());
|
||||
res = SZ_ERROR_READ;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void VfsFileInStream_CreateVTable(CVfsFileInStream *p)
|
||||
{
|
||||
p->s.Read = VfsFileInStream_Read;
|
||||
p->s.Seek = VfsFileInStream_Seek;
|
||||
}
|
||||
}; // end namespace szExt
|
||||
|
||||
/********************************************************************************************/
|
||||
/********************************************************************************************/
|
||||
/********************************************************************************************/
|
||||
|
||||
vfs::CUncompressed7zLibrary::CUncompressed7zLibrary(
|
||||
tReadableFile *libraryFile,
|
||||
vfs::Path const& mountPoint,
|
||||
bool ownFile,
|
||||
vfs::ObjBlockAllocator<vfs::CLibFile>* allocator)
|
||||
: vfs::CUncompressedLibraryBase(libraryFile, mountPoint, ownFile), _allocator(allocator)
|
||||
{
|
||||
}
|
||||
|
||||
vfs::CUncompressed7zLibrary::~CUncompressed7zLibrary()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#define k_Copy 0
|
||||
|
||||
sz::UInt64 GetSum(const sz::UInt64 *values, sz::UInt32 index)
|
||||
{
|
||||
sz::UInt64 sum = 0;
|
||||
sz::UInt32 i;
|
||||
for (i = 0; i < index; i++)
|
||||
{
|
||||
sum += values[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
bool vfs::CUncompressed7zLibrary::init()
|
||||
{
|
||||
if(!m_libraryFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
szExt::CVfsFileInStream archiveStream;
|
||||
sz::CLookToRead lookStream;
|
||||
sz::CSzArEx db;
|
||||
sz::SRes res;
|
||||
sz::ISzAlloc allocImp;
|
||||
sz::ISzAlloc allocTempImp;
|
||||
|
||||
vfs::COpenReadFile rfile(m_libraryFile);
|
||||
|
||||
archiveStream.file.file = m_libraryFile;
|
||||
|
||||
szExt::VfsFileInStream_CreateVTable(&archiveStream);
|
||||
sz::LookToRead_CreateVTable(&lookStream, False);
|
||||
|
||||
lookStream.realStream = &archiveStream.s;
|
||||
sz::LookToRead_Init(&lookStream);
|
||||
|
||||
allocImp.Alloc = sz::SzAlloc;
|
||||
allocImp.Free = sz::SzFree;
|
||||
|
||||
allocTempImp.Alloc = sz::SzAllocTemp;
|
||||
allocTempImp.Free = sz::SzFreeTemp;
|
||||
|
||||
sz::CrcGenerateTable();
|
||||
|
||||
sz::SzArEx_Init(&db);
|
||||
if( SZ_OK != (res = sz::SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp)) )
|
||||
{
|
||||
VFS_THROW(_BS(L"Could not open 7z archive [") << m_libraryFile->getPath() << L"]" << _BS::wget);
|
||||
}
|
||||
|
||||
vfs::TDirectory<ILibrary::tWriteType>* pLD = NULL;
|
||||
vfs::Path oDir, oFile;
|
||||
vfs::Path oDirPath;
|
||||
|
||||
const size_t FBUFFER_SIZE = 1024;
|
||||
std::vector<vfs::UInt16> fname_buffer;
|
||||
fname_buffer.resize(FBUFFER_SIZE);
|
||||
for(vfs::UInt32 i = 0; i < db.db.NumFiles; i++)
|
||||
{
|
||||
sz::CSzFileItem *f = db.db.Files + i;
|
||||
if (f->IsDir)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
size_t fsize = SzArEx_GetFileNameUtf16(&db, i, NULL);
|
||||
if(fsize >= fname_buffer.size())
|
||||
{
|
||||
fname_buffer.resize(fsize + 32);
|
||||
}
|
||||
fsize = SzArEx_GetFileNameUtf16(&db, i, &fname_buffer[0]);
|
||||
fname_buffer[fsize] = 0;
|
||||
vfs::Path sPath((wchar_t*)&fname_buffer[0]);
|
||||
sPath.splitLast(oDir,oFile);
|
||||
oDirPath = m_mountPoint;
|
||||
if(!oDir.empty())
|
||||
{
|
||||
oDirPath += oDir;
|
||||
}
|
||||
|
||||
// determine offset and size
|
||||
sz::UInt32 folderIndex = db.FileIndexToFolderIndexMap[i];
|
||||
|
||||
sz::CSzFolder *folder = db.db.Folders + folderIndex;
|
||||
sz::UInt64 unpackSizeSpec = sz::SzFolder_GetUnpackSize(folder);
|
||||
size_t unpackSize = (size_t)unpackSizeSpec;
|
||||
sz::UInt64 startOffset = sz::SzArEx_GetFolderStreamPos(&db, folderIndex, 0);
|
||||
|
||||
//const sz::UInt64 *packSizes = db.db.PackSizes + db.FolderStartPackStreamIndex[folderIndex];
|
||||
|
||||
//CSzCoderInfo *coder = &folder->Coders[0];
|
||||
//if (coder->MethodID == k_Copy)
|
||||
//{
|
||||
// UInt32 si = 0;
|
||||
// UInt64 offset;
|
||||
// UInt64 inSize;
|
||||
// offset = GetSum(packSizes, si);
|
||||
// inSize = packSizes[si];
|
||||
//}
|
||||
|
||||
// get or create according directory object
|
||||
tDirCatalogue::iterator it = m_dirs.find(oDirPath);
|
||||
if(it != m_dirs.end())
|
||||
{
|
||||
pLD = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLD = new vfs::CLibDirectory(oDir,oDirPath);
|
||||
m_dirs.insert(std::make_pair(oDirPath,pLD));
|
||||
}
|
||||
// create file
|
||||
vfs::CLibFile *pFile = vfs::CLibFile::create(oFile,pLD,this,_allocator);
|
||||
// add file to directory
|
||||
VFS_THROW_IFF( pLD->addFile(pFile), L"" );
|
||||
|
||||
// link file data struct to file object
|
||||
m_fileData.insert(std::make_pair(pFile,SFileData(unpackSize, (vfs::size_t)startOffset)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch(std::exception& ex)
|
||||
{
|
||||
VFS_LOG_ERROR(ex.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VFS_WITH_7ZIP
|
||||
@@ -0,0 +1,428 @@
|
||||
/*
|
||||
* bfVFS : vfs/Ext/7z/vfs_create_7z_library.cpp
|
||||
* - writes uncompressed 7z archive file
|
||||
*
|
||||
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
|
||||
*
|
||||
* This file is part of the bfVFS library
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef VFS_WITH_7ZIP
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <vfs/Core/vfs_types.h>
|
||||
|
||||
#include <vfs/Ext/7z/vfs_create_7z_library.h>
|
||||
#include <vfs/Core/vfs_file_raii.h>
|
||||
#include <vfs/Core/vfs_debug.h>
|
||||
|
||||
namespace sz
|
||||
{
|
||||
extern "C"
|
||||
{
|
||||
#include <7zCrc.h>
|
||||
#include <7z.h>
|
||||
//#include "Archive/7z/7zIn.h"
|
||||
}
|
||||
};
|
||||
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
namespace szExt
|
||||
{
|
||||
inline ::size_t WRITEBYTE(std::ostream& out, sz::Byte const& value)
|
||||
{
|
||||
out.write((char*)&value,sizeof(sz::Byte));
|
||||
return 1;
|
||||
}
|
||||
template<typename T>
|
||||
inline ::size_t WRITEALL(std::ostream& out, T const& value)
|
||||
{
|
||||
out.write((char*)&value,sizeof(T));
|
||||
return sizeof(T);
|
||||
}
|
||||
template<typename T>
|
||||
inline ::size_t WRITEBUFFER(std::ostream& out, T* value, ::size_t num_elements)
|
||||
{
|
||||
out.write((char*)value, num_elements*sizeof(T));
|
||||
return num_elements*sizeof(T);
|
||||
}
|
||||
|
||||
/**
|
||||
* "compress" numbers by removing heading zero-bytes
|
||||
* - add additional byte that represents a bit-vector of bytes within a 64-bit/8-byte number
|
||||
* - if the number is smaller than 128, use the extra byte to store the value
|
||||
*/
|
||||
template<typename T>
|
||||
inline ::size_t WRITE(std::ostream& out, T const& value)
|
||||
{
|
||||
::size_t count = 0;
|
||||
sz::Byte data[8];
|
||||
sz::Byte firstByte = 0;
|
||||
sz::Byte* b = (sz::Byte*)&value;
|
||||
::size_t SIZE = sizeof(T);
|
||||
b+= SIZE-1;
|
||||
vfs::Int32 i;
|
||||
for(i = (vfs::Int32)(SIZE-1); i>=0; --i)
|
||||
{
|
||||
if( (*b & 0xFF) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
b--;
|
||||
}
|
||||
if(i < 0)
|
||||
{
|
||||
count += WRITEBYTE(out,0);
|
||||
return count;
|
||||
}
|
||||
if(i == 0)
|
||||
{
|
||||
if(*b >= 0x80)
|
||||
{
|
||||
count += WRITEBYTE(out,0x80);
|
||||
}
|
||||
count += WRITEBYTE(out,*b);
|
||||
return count;
|
||||
}
|
||||
vfs::Int32 num = 0;
|
||||
for(;i >= 0; --i)
|
||||
{
|
||||
firstByte |= 1 << (8 - i - 1);
|
||||
data[i] = *b--;
|
||||
num++;
|
||||
}
|
||||
count += WRITEBYTE(out,firstByte);
|
||||
count += WRITEBUFFER(out,data,num);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
|
||||
vfs::CCreateUncompressed7zLibrary::CCreateUncompressed7zLibrary()
|
||||
: m_pLibFile(NULL)
|
||||
{
|
||||
sz::CrcGenerateTable();
|
||||
}
|
||||
|
||||
vfs::CCreateUncompressed7zLibrary::~CCreateUncompressed7zLibrary()
|
||||
{
|
||||
m_pLibFile = NULL;
|
||||
|
||||
m_lFileInfo.clear();
|
||||
m_mapDirInfo.clear();
|
||||
}
|
||||
|
||||
bool vfs::CCreateUncompressed7zLibrary::addFile(vfs::tReadableFile* pFile)
|
||||
{
|
||||
if(!pFile)
|
||||
{
|
||||
// at least nothing bad happened
|
||||
return true;
|
||||
}
|
||||
try
|
||||
{
|
||||
vfs::COpenReadFile infile(pFile);
|
||||
}
|
||||
catch(std::exception &ex)
|
||||
{
|
||||
std::wstringstream wss;
|
||||
wss << L"Could not open File \"" << pFile->getPath()() << L"\"";
|
||||
VFS_RETHROW(wss.str().c_str(), ex);
|
||||
}
|
||||
SFileInfo fi;
|
||||
vfs::Path filename = pFile->getPath();
|
||||
fi.name = filename.c_wcs();
|
||||
fi.size = pFile->getSize();
|
||||
if(m_lFileInfo.empty())
|
||||
{
|
||||
fi.offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SFileInfo const& fic = m_lFileInfo.back();
|
||||
fi.offset = fic.offset + fic.size;
|
||||
}
|
||||
|
||||
typedef std::vector<vfs::Byte> tByteVector;
|
||||
tByteVector data( (tByteVector::size_type)fi.size );
|
||||
VFS_THROW_IFF(fi.size == pFile->read(&data[0], (vfs::size_t)fi.size), L"");
|
||||
fi.CRC = sz::CrcCalc(&data[0],(::size_t)fi.size);
|
||||
m_ssFileStream.write(&data[0],(std::streamsize)fi.size);
|
||||
|
||||
m_lFileInfo.push_back(fi);
|
||||
|
||||
vfs::Path path,dummy;
|
||||
filename.splitLast(path,dummy);
|
||||
if(!path.empty())
|
||||
{
|
||||
tDirInfo::iterator it_find = m_mapDirInfo.find(path.c_wcs());
|
||||
if(it_find == m_mapDirInfo.end())
|
||||
{
|
||||
SFileInfo dir;
|
||||
dir.name = path.c_wcs();
|
||||
dir.offset = 0;
|
||||
dir.size = 0;
|
||||
dir.time_creation = 0;
|
||||
dir.time_last_access = 0;
|
||||
dir.time_write = 0;
|
||||
m_mapDirInfo.insert(std::make_pair(dir.name,dir));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vfs::CCreateUncompressed7zLibrary::writeLibrary(vfs::Path const& sLibName)
|
||||
{
|
||||
vfs::COpenWriteFile outfile(sLibName,true);
|
||||
return writeLibrary(&outfile.file());
|
||||
}
|
||||
bool vfs::CCreateUncompressed7zLibrary::writeLibrary(vfs::tWritableFile* pFile)
|
||||
{
|
||||
if(!pFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(m_lFileInfo.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_pLibFile = pFile;
|
||||
if(!m_pLibFile->isOpenWrite() && !m_pLibFile->openWrite(true,true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//
|
||||
writeNextHeader(m_ssInfoStream);
|
||||
//
|
||||
std::stringstream ssSigHeader;
|
||||
writeSignatureHeader(ssSigHeader);
|
||||
//
|
||||
m_pLibFile->write(ssSigHeader.str().c_str() , (vfs::size_t)ssSigHeader.str().length());
|
||||
//
|
||||
m_pLibFile->write(m_ssFileStream.str().c_str() , (vfs::size_t)m_ssFileStream.str().length());
|
||||
//
|
||||
m_pLibFile->write(m_ssInfoStream.str().c_str() , (vfs::size_t)m_ssInfoStream.str().length());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************************/
|
||||
|
||||
bool vfs::CCreateUncompressed7zLibrary::writeSignatureHeader(std::ostream& out)
|
||||
{
|
||||
::size_t count=0;
|
||||
|
||||
// #define k7zSignatureSize -> not in namespace sz
|
||||
count += szExt::WRITEBUFFER(out, sz::k7zSignature, k7zSignatureSize);
|
||||
|
||||
sz::Byte Major = 0, Minor = 2;
|
||||
count += szExt::WRITEALL(out, (sz::Byte)Major );
|
||||
count += szExt::WRITEALL(out, (sz::Byte)Minor );
|
||||
|
||||
sz::UInt32 StartHeaderCRC, NextHeaderCRC;
|
||||
|
||||
SFileInfo const& fi = m_lFileInfo.back();
|
||||
sz::UInt64 NextHeaderOffset = fi.offset + fi.size;
|
||||
sz::UInt64 NextHeaderSize = m_ssInfoStream.str().length()*sizeof(char);
|
||||
NextHeaderCRC = sz::CrcCalc(m_ssInfoStream.str().c_str(),(::size_t)NextHeaderSize);
|
||||
|
||||
std::stringstream sstemp;
|
||||
count += szExt::WRITEALL(sstemp, (sz::UInt64)NextHeaderOffset );
|
||||
count += szExt::WRITEALL(sstemp, (sz::UInt64)NextHeaderSize );
|
||||
count += szExt::WRITEALL(sstemp, (sz::UInt32)NextHeaderCRC );
|
||||
StartHeaderCRC = sz::CrcCalc(sstemp.str().c_str(), sstemp.str().length()*sizeof(char));
|
||||
|
||||
count += szExt::WRITEALL(out, (sz::UInt32)StartHeaderCRC );
|
||||
out << sstemp.str();
|
||||
|
||||
return true;
|
||||
}
|
||||
bool vfs::CCreateUncompressed7zLibrary::writeNextHeader(std::ostream& out)
|
||||
{
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdHeader);
|
||||
|
||||
// this->WriteArchiveProperties(out);
|
||||
|
||||
// this->WriteAdditionalStreamsInfo(out)
|
||||
|
||||
//
|
||||
this->writeMainStreamsInfo(out);
|
||||
|
||||
//
|
||||
this->writeFilesInfo(out);
|
||||
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdEnd );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vfs::CCreateUncompressed7zLibrary::writeMainStreamsInfo(std::ostream& out)
|
||||
{
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdMainStreamsInfo );
|
||||
|
||||
this->writePackInfo(out);
|
||||
|
||||
this->writeUnPackInfo(out);
|
||||
|
||||
this->writeSubStreamsInfo(out);
|
||||
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdEnd );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool vfs::CCreateUncompressed7zLibrary::writePackInfo(std::ostream& out)
|
||||
{
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdPackInfo );
|
||||
szExt::WRITE(out, (sz::UInt64)0 ); // data offset
|
||||
szExt::WRITE(out, (sz::UInt32)m_lFileInfo.size() );
|
||||
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdSize );
|
||||
std::list<SFileInfo>::iterator it = m_lFileInfo.begin();
|
||||
for(;it != m_lFileInfo.end(); ++it)
|
||||
{
|
||||
szExt::WRITE(out, (sz::UInt64)it->size );
|
||||
}
|
||||
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdEnd );
|
||||
return true;
|
||||
}
|
||||
bool vfs::CCreateUncompressed7zLibrary::writeUnPackInfo(std::ostream& out)
|
||||
{
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdUnpackInfo );
|
||||
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdFolder );
|
||||
szExt::WRITE(out, (sz::UInt64)m_lFileInfo.size() );
|
||||
szExt::WRITE(out, (sz::Byte)0 ); // External
|
||||
|
||||
std::list<SFileInfo>::iterator fit = m_lFileInfo.begin();
|
||||
for(;fit != m_lFileInfo.end(); ++fit)
|
||||
{
|
||||
this->writeFolder(out);
|
||||
}
|
||||
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdCodersUnpackSize );
|
||||
fit = m_lFileInfo.begin();
|
||||
for(;fit != m_lFileInfo.end(); ++fit)
|
||||
{
|
||||
szExt::WRITE(out, (sz::UInt64)fit->size );
|
||||
}
|
||||
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdEnd );
|
||||
|
||||
return true;
|
||||
}
|
||||
bool vfs::CCreateUncompressed7zLibrary::writeSubStreamsInfo(std::ostream& out)
|
||||
{
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdSubStreamsInfo );
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdCRC );
|
||||
|
||||
szExt::WRITE(out, (sz::Byte)1 ); // early out - all CRCs defined
|
||||
std::list<SFileInfo>::iterator fit = m_lFileInfo.begin();
|
||||
for(;fit != m_lFileInfo.end(); ++fit )
|
||||
{
|
||||
szExt::WRITEALL(out, (sz::UInt32)fit->CRC);
|
||||
}
|
||||
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdEnd );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vfs::CCreateUncompressed7zLibrary::writeFolder(std::ostream& out)
|
||||
{
|
||||
szExt::WRITE(out, (sz::UInt32)1 ); // NumCoders
|
||||
|
||||
szExt::WRITE(out, (sz::Byte)1 ); // MainByte
|
||||
|
||||
szExt::WRITE(out, (sz::Byte)0 ); // Methods
|
||||
|
||||
return true;
|
||||
}
|
||||
bool vfs::CCreateUncompressed7zLibrary::writeFilesInfo(std::ostream& out)
|
||||
{
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdFilesInfo );
|
||||
|
||||
vfs::UInt64 num_files = (m_lFileInfo.size()+m_mapDirInfo.size());
|
||||
szExt::WRITE(out, (sz::UInt64)num_files );
|
||||
|
||||
// empty stream -> pack info in bit-vector
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdEmptyStream );
|
||||
sz::UInt64 num_empty64 = num_files/8 + (num_files%8 == 0 ? 0 : 1);
|
||||
::size_t num_empty = (::size_t)num_empty64;
|
||||
VFS_THROW_IFF(num_empty == num_empty64, L"WTF");
|
||||
|
||||
sz::Byte *empty_vector = new sz::Byte[num_empty];
|
||||
memset(empty_vector,0,(::size_t)num_empty);
|
||||
for(::size_t e=m_lFileInfo.size(); e < num_files; ++e)
|
||||
{
|
||||
::size_t index = e / 8;
|
||||
empty_vector[index] |= 1 << (7 - e%8);
|
||||
}
|
||||
szExt::WRITE(out, (sz::UInt64)num_empty ); // size
|
||||
szExt::WRITEBUFFER(out, empty_vector, (::size_t)num_empty);
|
||||
delete[] empty_vector;
|
||||
|
||||
// names
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdName );
|
||||
::size_t count = 0;
|
||||
std::stringstream name_stream;
|
||||
count += szExt::WRITE(name_stream, (sz::Byte)0 ); // switch
|
||||
std::list<SFileInfo>::iterator fit = m_lFileInfo.begin();
|
||||
for(;fit != m_lFileInfo.end(); ++fit)
|
||||
{
|
||||
count += (::size_t)this->writeFileName(name_stream, fit->name);
|
||||
}
|
||||
std::map<vfs::String::str_t,SFileInfo>::iterator dit = m_mapDirInfo.begin();
|
||||
for(;dit != m_mapDirInfo.end(); ++dit)
|
||||
{
|
||||
count += (::size_t)this->writeFileName(name_stream, dit->second.name);
|
||||
}
|
||||
szExt::WRITE(out, (sz::UInt64)count ); // size
|
||||
szExt::WRITEBUFFER(out, name_stream.str().c_str(), name_stream.str().length() );
|
||||
|
||||
//szExt::WRITE(out, (sz::Byte)sz::k7zIdEmptyFile );
|
||||
//szExt::WRITE(out, (sz::Byte)sz::k7zIdCTime ); // create
|
||||
//szExt::WRITE(out, (sz::Byte)sz::k7zIdATime ); // last access
|
||||
//szExt::WRITE(out, (sz::Byte)sz::k7zIdMTime ); // write
|
||||
|
||||
//szExt::WRITE(out, (sz::Byte)sz::k7zIdWinAttributes );
|
||||
|
||||
szExt::WRITE(out, (sz::Byte)sz::k7zIdEnd );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
vfs::size_t vfs::CCreateUncompressed7zLibrary::writeFileName(std::ostream& out, vfs::String const& filename)
|
||||
{
|
||||
::size_t count = 0;
|
||||
VFS_THROW_IFF(filename.length(), L"zero length name");
|
||||
count += szExt::WRITEBUFFER(out, filename.c_str(), filename.length());
|
||||
count += szExt::WRITE(out, (sz::Byte)0);
|
||||
count += szExt::WRITE(out, (sz::Byte)0);
|
||||
return (vfs::size_t)count;
|
||||
}
|
||||
|
||||
#endif // VFS_WITH_7ZIP
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
## Ext
|
||||
|
||||
if(BFVFS_WITH_7ZIP)
|
||||
set(INCLUDE_Ext_7zip
|
||||
${MOD_INCLUDE}/7z/vfs_7z_library.h
|
||||
${MOD_INCLUDE}/7z/vfs_create_7z_library.h
|
||||
)
|
||||
set(SOURCE_Ext_7zip
|
||||
${MOD_SOURCE}/7z/vfs_7z_library.cpp
|
||||
${MOD_SOURCE}/7z/vfs_create_7z_library.cpp
|
||||
)
|
||||
source_group("Ext" FILES ${INCLUDE_Ext_7zip} ${SOURCE_Ext_7zip})
|
||||
endif()
|
||||
|
||||
if(BFVFS_WITH_SLF)
|
||||
set(INCLUDE_Ext_slf
|
||||
${MOD_INCLUDE}/slf/vfs_slf_library.h
|
||||
)
|
||||
set(SOURCE_Ext_slf
|
||||
${MOD_SOURCE}/slf/vfs_slf_library.cpp
|
||||
)
|
||||
source_group("Ext" FILES ${INCLUDE_Ext_slf} ${SOURCE_Ext_slf})
|
||||
endif()
|
||||
|
||||
set(${mod}_files
|
||||
${INCLUDE_Ext_7zip} ${SOURCE_Ext_7zip}
|
||||
${INCLUDE_Ext_slf} ${SOURCE_Ext_slf}
|
||||
CACHE INTERNAL ""
|
||||
)
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* bfVFS : vfs/Ext/slf/vfs_slf_library.cpp
|
||||
* - implements Library interface, creates library object from SLF archive files
|
||||
*
|
||||
* Copyright (C) 2008 - 2010 (BF) john.bf.smith@googlemail.com
|
||||
*
|
||||
* This file is part of the bfVFS library
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef VFS_WITH_SLF
|
||||
|
||||
#include <vfs/Ext/slf/vfs_slf_library.h>
|
||||
#include <vfs/Core/Location/vfs_lib_dir.h>
|
||||
#include <vfs/vfs_config.h>
|
||||
#include <vfs/Core/Interface/vfs_directory_interface.h>
|
||||
#include <vfs/Core/File/vfs_lib_file.h>
|
||||
#include <vfs/Core/vfs_file_raii.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace slf
|
||||
{
|
||||
typedef vfs::UInt32 DWORD;
|
||||
// copy from WinDef.h
|
||||
typedef struct _FILETIME {
|
||||
DWORD dwLowDateTime;
|
||||
DWORD dwHighDateTime;
|
||||
} FILETIME, *PFILETIME, *LPFILETIME;
|
||||
|
||||
typedef void* HANDLE;
|
||||
|
||||
const vfs::UInt32 FILENAME_SIZE = 256;
|
||||
const vfs::UInt32 PATH_SIZE = 80;
|
||||
|
||||
const vfs::UInt32 FILE_OK = 0;
|
||||
const vfs::UInt32 FILE_DELETED = 0xff;
|
||||
const vfs::UInt32 FILE_OLD = 1;
|
||||
const vfs::UInt32 FILE_DOESNT_EXIST = 0xfe;
|
||||
|
||||
struct LIBHEADER
|
||||
{
|
||||
vfs::Byte sLibName[ FILENAME_SIZE ];
|
||||
vfs::Byte sPathToLibrary[ FILENAME_SIZE ];
|
||||
vfs::Int32 iEntries;
|
||||
vfs::Int32 iUsed;
|
||||
vfs::UInt16 iSort;
|
||||
vfs::UInt16 iVersion;
|
||||
vfs::UByte fContainsSubDirectories;
|
||||
vfs::Int32 iReserved;
|
||||
};
|
||||
|
||||
struct DIRENTRY
|
||||
{
|
||||
vfs::Byte sFileName[ FILENAME_SIZE ];
|
||||
vfs::UInt32 uiOffset;
|
||||
vfs::UInt32 uiLength;
|
||||
vfs::UInt8 ubState;
|
||||
vfs::UInt8 ubReserved;
|
||||
FILETIME sFileTime;
|
||||
vfs::UInt16 usReserved2;
|
||||
};
|
||||
}; // end namespace slf
|
||||
|
||||
/********************************************************************************************/
|
||||
/********************************************************************************************/
|
||||
/********************************************************************************************/
|
||||
|
||||
vfs::CSLFLibrary::CSLFLibrary(tReadableFile *pLibraryFile, vfs::Path const& sMountPoint, bool bOwnFile)
|
||||
: vfs::CUncompressedLibraryBase(pLibraryFile,sMountPoint,bOwnFile)
|
||||
{};
|
||||
|
||||
vfs::CSLFLibrary::~CSLFLibrary()
|
||||
{
|
||||
}
|
||||
|
||||
bool vfs::CSLFLibrary::init()
|
||||
{
|
||||
if(!m_libraryFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
vfs::COpenReadFile rfile(m_libraryFile);
|
||||
|
||||
slf::LIBHEADER LibFileHeader;
|
||||
vfs::size_t bytesRead = m_libraryFile->read((vfs::Byte*)&LibFileHeader, sizeof( slf::LIBHEADER ));
|
||||
VFS_THROW_IFF(bytesRead == sizeof( slf::LIBHEADER ), L"");
|
||||
|
||||
vfs::Path oLibPath;
|
||||
//if the library has a path
|
||||
if( strlen( (char*)LibFileHeader.sPathToLibrary ) != 0 )
|
||||
{
|
||||
oLibPath = vfs::Path( LibFileHeader.sPathToLibrary );
|
||||
}
|
||||
else
|
||||
{
|
||||
//else the library name does not contain a path ( most likely either an error or it is the default path )
|
||||
oLibPath = vfs::Path( vfs::Const::EMPTY() );
|
||||
}
|
||||
if(m_mountPoint.empty())
|
||||
{
|
||||
m_mountPoint = oLibPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mountPoint += oLibPath;
|
||||
}
|
||||
|
||||
//place the file pointer at the begining of the file headers ( they are at the end of the file )
|
||||
m_libraryFile->setReadPosition(-( LibFileHeader.iEntries * (vfs::Int32)sizeof(slf::DIRENTRY) ), vfs::IBaseFile::SD_END);
|
||||
|
||||
//loop through the library and determine the number of files that are FILE_OK
|
||||
//ie. so we dont load the old or deleted files
|
||||
slf::DIRENTRY DirEntry;
|
||||
vfs::Path oDir, oFile;
|
||||
vfs::Path oDirPath;
|
||||
for(vfs::UInt32 uiLoop=0; uiLoop < (vfs::UInt32)LibFileHeader.iEntries; uiLoop++ )
|
||||
{
|
||||
//read in the file header
|
||||
//memset(&DirEntry,0,sizeof(DirEntry));
|
||||
bytesRead = m_libraryFile->read((Byte*)&DirEntry, sizeof( slf::DIRENTRY ));
|
||||
VFS_THROW_IFF(bytesRead == sizeof( slf::DIRENTRY ), L"");
|
||||
|
||||
if( DirEntry.ubState == slf::FILE_OK )
|
||||
{
|
||||
vfs::Path sPath(vfs::String::as_utf16(DirEntry.sFileName));
|
||||
sPath.splitLast(oDir,oFile);
|
||||
oDirPath = m_mountPoint;
|
||||
if(!oDir.empty())
|
||||
{
|
||||
oDirPath += oDir;
|
||||
}
|
||||
|
||||
// get or create according directory object
|
||||
vfs::TDirectory<ILibrary::tWriteType>* pLD = NULL;
|
||||
tDirCatalogue::iterator it = m_dirs.find(oDirPath);
|
||||
if(it != m_dirs.end())
|
||||
{
|
||||
pLD = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLD = new vfs::CLibDirectory(oDirPath,oDirPath);
|
||||
m_dirs.insert(std::make_pair(oDirPath,pLD));
|
||||
}
|
||||
// create file
|
||||
vfs::CLibFile *pFile = vfs::CLibFile::create(oFile,pLD,this);
|
||||
// add file to directory
|
||||
VFS_THROW_IFF(pLD->addFile(pFile), L"");
|
||||
|
||||
// link file data struct to file object
|
||||
m_fileData.insert(std::make_pair(pFile, SFileData(DirEntry.uiLength, DirEntry.uiOffset)));
|
||||
} // end if
|
||||
} // end for
|
||||
return true;
|
||||
}
|
||||
catch(std::exception& ex)
|
||||
{
|
||||
VFS_LOG_ERROR(ex.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VFS_WITH_SLF
|
||||
Reference in New Issue
Block a user