diff --git a/code/ryzom/client/src/login_patch.cpp b/code/ryzom/client/src/login_patch.cpp
index c942071d0..37cbddcbd 100644
--- a/code/ryzom/client/src/login_patch.cpp
+++ b/code/ryzom/client/src/login_patch.cpp
@@ -54,6 +54,7 @@
#include "login.h"
#include "user_agent.h"
+#include "seven_zip/seven_zip.h"
#ifndef RY_BG_DOWNLOADER
#include "client_cfg.h"
@@ -2625,7 +2626,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
// try to unpack the file
try
{
- if (!CPatchManager::unpackLZMA(pPM->ClientPatchPath+lzmaFile, OutFilename+".tmp"))
+ if (!unpackLZMA(pPM->ClientPatchPath+lzmaFile, OutFilename+".tmp"))
{
// fallback to standard patch method
usePatchFile = true;
@@ -3087,7 +3088,7 @@ bool CPatchManager::download(const std::string& patchFullname, const std::string
&& patchName.substr(patchName.size() - zsStrLength) == zsStr)
{
std::string outFilename = patchName.substr(0, patchName.size() - zsStrLength);
- CPatchManager::unpack7Zip(patchName, outFilename);
+ unpack7Zip(patchName, outFilename);
pPM->deleteFile(patchName);
pPM->renameFile(outFilename, sourceFullname);
}
@@ -3449,7 +3450,7 @@ void CInstallThread::run()
std::string outFilename = patchName.substr(0, patchName.size() - zsStrLength);
std::string localOutFilename = CPath::standardizeDosPath(outFilename);
- if ( CPatchManager::unpackLZMA(patchName, localOutFilename) )
+ if ( unpackLZMA(patchName, localOutFilename) )
{
pPM->deleteFile(patchName);
pPM->renameFile(outFilename, sourceName);
diff --git a/code/ryzom/client/src/login_patch.h b/code/ryzom/client/src/login_patch.h
index 9fdf907e8..c7f0f4509 100644
--- a/code/ryzom/client/src/login_patch.h
+++ b/code/ryzom/client/src/login_patch.h
@@ -331,10 +331,6 @@ private:
void clearDataScanLog();
static void getCorruptedFileInfo(const SFileToPatch &ftp, ucstring &sTranslate);
- // utility func to decompress a monofile 7zip archive
- static bool unpack7Zip(const std::string &sevenZipFile, const std::string &destFileName);
- // utility func to decompress a single LZMA packed file
- static bool unpackLZMA(const std::string &sevenZipFile, const std::string &destFileName);
static bool downloadAndUnpack(const std::string& patchPath, const std::string& sourceFilename, const std::string& extractPath, const std::string& tmpDirectory, uint32 timestamp);
// Forward message to Installation Software
void onFileInstallFinished();
diff --git a/code/ryzom/client/src/login_patch_seven_zip.cpp b/code/ryzom/client/src/login_patch_seven_zip.cpp
deleted file mode 100644
index 306c0607f..000000000
--- a/code/ryzom/client/src/login_patch_seven_zip.cpp
+++ /dev/null
@@ -1,468 +0,0 @@
-// Ryzom - MMORPG Framework
-// Copyright (C) 2010 Winch Gate Property Limited
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program 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 Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-//
-// Includes
-//
-
-#include "stdpch.h"
-#include "login_patch.h"
-
-#define RZ_USE_SEVENZIP 1
-#define RZ_USE_NEW_LZMA
-
-#ifdef RZ_USE_SEVENZIP
-
-#ifdef RZ_USE_NEW_LZMA
-
-#include "seven_zip/7z.h"
-#include "seven_zip/7zAlloc.h"
-#include "seven_zip/7zBuf.h"
-#include "seven_zip/7zCrc.h"
-#include "seven_zip/7zFile.h"
-#include "seven_zip/7zVersion.h"
-#include "seven_zip/LzmaDec.h"
-
-#else
-
-#include "seven_zip/7zCrc.h"
-#include "seven_zip/7zIn.h"
-#include "seven_zip/7zExtract.h"
-#include "seven_zip/LzmaDecode.h"
-
-#endif
-
-//
-// Namespaces
-//
-
-using namespace std;
-using namespace NLMISC;
-
-
-#ifdef RZ_USE_NEW_LZMA
-
-/// Input stream class for 7zip archive
-class CNel7ZipInStream : public ISeekInStream
-{
- NLMISC::IStream *_Stream;
-
-public:
- /// Constructor, only allow file stream because 7zip will 'seek' in the stream
- CNel7ZipInStream(NLMISC::IStream *s)
- : _Stream(s)
- {
- Read = readFunc;
- Seek = seekFunc;
- }
-
- // the read function called by 7zip to read data
- static SRes readFunc(void *object, void *buffer, size_t *size)
- {
- try
- {
- CNel7ZipInStream *me = (CNel7ZipInStream*)object;
- uint len = (uint)*size;
- me->_Stream->serialBuffer((uint8*)buffer, len);
- return SZ_OK;
- }
- catch (...)
- {
- return SZ_ERROR_READ;
- }
- }
-
- // the seek function called by seven zip to seek inside stream
- static SRes seekFunc(void *object, Int64 *pos, ESzSeek origin)
- {
- try
- {
- CNel7ZipInStream *me = (CNel7ZipInStream*)object;
- sint32 offset = (sint32)*pos;
- bool ret = me->_Stream->seek(offset, (NLMISC::IStream::TSeekOrigin)origin);
-
- if (ret)
- {
- *pos = (Int64)me->_Stream->getPos();
- return SZ_OK;
- }
- }
- catch (...)
- {
- }
-
- return SZ_ERROR_READ;
- }
-};
-
-#else
-
-/// Input stream class for 7zip archive
-class CNel7ZipInStream : public _ISzInStream
-{
- NLMISC::IStream *_Stream;
-
-public:
- /// Constructor, only allow file stream because 7zip will 'seek' in the stream
- CNel7ZipInStream(NLMISC::IStream *s)
- : _Stream(s)
- {
- Read = readFunc;
- Seek = seekFunc;
- }
-
- // the read function called by 7zip to read data
- static SZ_RESULT readFunc(void *object, void *buffer, size_t size, size_t *processedSize)
- {
- try
- {
- CNel7ZipInStream *me = (CNel7ZipInStream*)object;
- me->_Stream->serialBuffer((uint8*)buffer, (uint)size);
- *processedSize = size;
- return SZ_OK;
- }
- catch (...)
- {
- return SZE_FAIL;
- }
- }
-
- // the seek function called by seven zip to seek inside stream
- static SZ_RESULT seekFunc(void *object, CFileSize pos)
- {
- try
- {
- CNel7ZipInStream *me = (CNel7ZipInStream*)object;
- bool ret= me->_Stream->seek(pos, NLMISC::IStream::begin);
- if (ret)
- return SZ_OK;
- else
- return SZE_FAIL;
- }
- catch (...)
- {
- return SZE_FAIL;
- }
- }
-};
-
-#endif
-
-#endif
-
-bool CPatchManager::unpack7Zip(const std::string &sevenZipFile, const std::string &destFileName)
-{
-#ifdef RZ_USE_SEVENZIP
- nlinfo("Uncompressing 7zip archive '%s' to '%s'", sevenZipFile.c_str(), destFileName.c_str());
-
- // init seven zip
- ISzAlloc allocImp;
- allocImp.Alloc = SzAlloc;
- allocImp.Free = SzFree;
-
- ISzAlloc allocTempImp;
- allocTempImp.Alloc = SzAllocTemp;
- allocTempImp.Free = SzFreeTemp;
-
- // wrap file in a CIFile
- CIFile input(sevenZipFile);
- CNel7ZipInStream inStr(&input);
-
-#ifdef RZ_USE_NEW_LZMA
-
- CLookToRead lookStream;
- lookStream.realStream = &inStr;
- LookToRead_CreateVTable(&lookStream, False);
- LookToRead_Init(&lookStream);
-
- CrcGenerateTable();
-
- CSzArEx db;
- SzArEx_Init(&db);
-
- // unpack the file using the 7zip API
- SRes res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
-
- if (res != SZ_OK)
- {
- nlerror("Failed to open archive file %s", sevenZipFile.c_str());
- return false;
- }
-
- if (db.NumFiles != 1)
- {
- nlerror("Seven zip archive with more than 1 file are unsupported");
- return false;
- }
-
- UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
- Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
- size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
-
- size_t offset;
- size_t outSizeProcessed = 0;
-
- // get the first file
- res = SzArEx_Extract(&db, &lookStream.s, 0,
- &blockIndex, &outBuffer, &outBufferSize,
- &offset, &outSizeProcessed,
- &allocImp, &allocTempImp);
-
- // get the length of first file
- size_t nameLen = SzArEx_GetFileNameUtf16(&db, 0, NULL);
-
- ucstring filename;
- filename.resize(nameLen);
-
- // write filename into ucstring
- SzArEx_GetFileNameUtf16(&db, 0, &filename[0]);
-
- // write the extracted file
- FILE *outputHandle = fopen(destFileName.c_str(), "wb+");
-
- if (outputHandle == 0)
- {
- nlerror("Can not open output file '%s'", destFileName.c_str());
- return false;
- }
-
- UInt32 processedSize = (UInt32)fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle);
-
- if (processedSize != outSizeProcessed)
- {
- nlerror("Failed to write %u char to output file '%s'", outSizeProcessed-processedSize, destFileName.c_str());
- return false;
- }
-
- fclose(outputHandle);
-
- IAlloc_Free(&allocImp, outBuffer);
-
- // free 7z context
- SzArEx_Free(&db, &allocImp);
-
-#else
-
- InitCrcTable();
-
- CArchiveDatabaseEx db;
- SzArDbExInit(&db);
-
- // unpack the file using the 7zip API
- SZ_RESULT res = SzArchiveOpen(&inStr, &db, &allocImp, &allocTempImp);
-
- if (res != SZ_OK)
- {
- nlerror("Failed to open archive file %s", sevenZipFile.c_str());
- return false;
- }
-
- if (db.Database.NumFiles != 1)
- {
- nlerror("Seven zip archive with more than 1 file are unsupported");
- return false;
- }
-
- UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
- Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
- size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
-
- size_t offset = 0;
- size_t outSizeProcessed = 0;
-
- // get the first file
- res = SzExtract(&inStr, &db, 0,
- &blockIndex, &outBuffer, &outBufferSize,
- &offset, &outSizeProcessed,
- &allocImp, &allocTempImp);
-
- // write the extracted file
- FILE *outputHandle = fopen(destFileName.c_str(), "wb+");
-
- if (outputHandle == 0)
- {
- nlerror("Can not open output file '%s'", destFileName.c_str());
- return false;
- }
-
- UInt32 processedSize = (UInt32)fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle);
-
- if (processedSize != outSizeProcessed)
- {
- nlerror("Failed to write %u char to output file '%s'", outSizeProcessed-processedSize, destFileName.c_str());
- return false;
- }
-
- fclose(outputHandle);
- allocImp.Free(outBuffer);
-
- // free 7z context
- SzArDbExFree(&db, allocImp.Free);
-
-#endif
-
- // ok, all is fine, file is unpacked
- return true;
-#else
- return false;
-#endif
-}
-
-bool CPatchManager::unpackLZMA(const std::string &lzmaFile, const std::string &destFileName)
-{
-#ifdef RZ_USE_SEVENZIP
- nldebug("unpackLZMA : decompression the lzma file '%s' into output file '%s", lzmaFile.c_str(), destFileName.c_str());
-
- CIFile inStream(lzmaFile);
- uint32 inSize = inStream.getFileSize();
-
-#ifdef RZ_USE_NEW_LZMA
-
- if (inSize < LZMA_PROPS_SIZE + 8)
- {
- nlwarning("Invalid file size, too small file '%s'", lzmaFile.c_str());
- return false;
- }
-
- // read the compressed file in buffer
- auto_ptr inBuffer = auto_ptr(new uint8[inSize]);
- inStream.serialBuffer(inBuffer.get(), inSize);
-
- uint8 *pos = inBuffer.get();
-
- pos += LZMA_PROPS_SIZE;
-
- // read the output file size
- size_t fileSize = 0;
-
- for (int i = 0; i < 8; ++i)
- {
- if (pos >= inBuffer.get()+inSize)
- {
- nlassert(false);
- return false;
- }
-
- fileSize |= ((UInt64)*pos++) << (8 * i);
- }
-
- // allocators
- ISzAlloc allocImp;
- allocImp.Alloc = SzAlloc;
- allocImp.Free = SzFree;
-
- CLzmaDec state;
- LzmaDec_Construct(&state);
-
- // allocate and decode props and probs
- SRes res = LzmaDec_Allocate(&state, inBuffer.get(), LZMA_PROPS_SIZE, &allocImp);
-
- if (res != 0)
- {
- nlwarning("Failed to decode lzma properies in file '%s'!", lzmaFile.c_str());
- return false;
- }
-
- // allocate the output buffer
- auto_ptr outBuffer = auto_ptr(new uint8[fileSize]);
-
- // in and out file sizes
- SizeT outProcessed = fileSize;
- SizeT inProcessed = (SizeT)(inSize-(pos-inBuffer.get()));
-
- LzmaDec_Init(&state);
-
- // decompress the file in memory
- ELzmaStatus status;
- res = LzmaDec_DecodeToBuf(&state, (Byte*)outBuffer.get(), &outProcessed, (Byte*)pos, &inProcessed, LZMA_FINISH_ANY, &status);
-
- // free memory
- LzmaDec_Free(&state, &allocImp);
-
- if (res != 0 || outProcessed != fileSize)
- {
- nlwarning("Failed to decode lzma file '%s' with status %d", lzmaFile.c_str(), (sint)status);
- return false;
- }
-
-#else
-
- auto_ptr inBuffer = auto_ptr(new uint8[inSize]);
- inStream.serialBuffer(inBuffer.get(), inSize);
-
- CLzmaDecoderState state;
-
- uint8 *pos = inBuffer.get();
-
- // read the lzma properties
- int res = LzmaDecodeProperties(&state.Properties, (unsigned char*) pos, LZMA_PROPERTIES_SIZE);
- if (res != 0)
- {
- nlwarning("Failed to decode lzma properies in file '%s'!", lzmaFile.c_str());
- return false;
- }
-
- if (inSize < LZMA_PROPERTIES_SIZE + 8)
- {
- nlwarning("Invalid file size, too small file '%s'", lzmaFile.c_str());
- return false;
- }
-
- // alloc the probs, making sure they are deleted in function exit
- size_t nbProb = LzmaGetNumProbs(&state.Properties);
- auto_ptr probs = auto_ptr(new CProb[nbProb]);
- state.Probs = probs.get();
-
- pos += LZMA_PROPERTIES_SIZE;
-
- // read the output file size
- size_t fileSize = 0;
- for (int i = 0; i < 8; i++)
- {
- if (pos >= inBuffer.get()+inSize)
- {
- nlassert(false);
- return false;
- }
- fileSize |= ((UInt64)*pos++) << (8 * i);
- }
-
- SizeT outProcessed = 0;
- SizeT inProcessed = 0;
-
- // allocate the output buffer
- auto_ptr outBuffer = auto_ptr(new uint8[fileSize]);
-
- // decompress the file in memory
- res = LzmaDecode(&state, (unsigned char*) pos, (SizeT)(inSize-(pos-inBuffer.get())), &inProcessed, (unsigned char*)outBuffer.get(), (SizeT)fileSize, &outProcessed);
-
- if (res != 0 || outProcessed != fileSize)
- {
- nlwarning("Failed to decode lzma file '%s'", lzmaFile.c_str());
- return false;
- }
-
-#endif
-
- // store on output buffer
- COFile outStream(destFileName);
- outStream.serialBuffer(outBuffer.get(), (uint)fileSize);
-
- return true;
-#else
- return false;
-#endif
-}
diff --git a/code/ryzom/client/src/seven_zip/seven_zip.cpp b/code/ryzom/client/src/seven_zip/seven_zip.cpp
new file mode 100644
index 000000000..84a7eaace
--- /dev/null
+++ b/code/ryzom/client/src/seven_zip/seven_zip.cpp
@@ -0,0 +1,357 @@
+// Ryzom - MMORPG Framework
+// Copyright (C) 2010 Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#include "seven_zip.h"
+
+#include "nel/misc/types_nl.h"
+#include "nel/misc/file.h"
+#include "nel/misc/path.h"
+
+#include "7z.h"
+#include "7zAlloc.h"
+#include "7zCrc.h"
+#include "7zVersion.h"
+#include "LzmaLib.h"
+
+#include
+
+//
+// Namespaces
+//
+
+using namespace std;
+using namespace NLMISC;
+
+
+/// Input stream class for 7zip archive
+class CNel7ZipInStream : public ISeekInStream
+{
+ NLMISC::IStream *_Stream;
+
+public:
+ /// Constructor, only allow file stream because 7zip will 'seek' in the stream
+ CNel7ZipInStream(NLMISC::IStream *s)
+ : _Stream(s)
+ {
+ Read = readFunc;
+ Seek = seekFunc;
+ }
+
+ // the read function called by 7zip to read data
+ static SRes readFunc(void *object, void *buffer, size_t *size)
+ {
+ try
+ {
+ CNel7ZipInStream *me = (CNel7ZipInStream*)object;
+ uint len = (uint)*size;
+ me->_Stream->serialBuffer((uint8*)buffer, len);
+ return SZ_OK;
+ }
+ catch (...)
+ {
+ return SZ_ERROR_READ;
+ }
+ }
+
+ // the seek function called by seven zip to seek inside stream
+ static SRes seekFunc(void *object, Int64 *pos, ESzSeek origin)
+ {
+ try
+ {
+ CNel7ZipInStream *me = (CNel7ZipInStream*)object;
+ sint32 offset = (sint32)*pos;
+ bool ret = me->_Stream->seek(offset, (NLMISC::IStream::TSeekOrigin)origin);
+
+ if (ret)
+ {
+ *pos = (Int64)me->_Stream->getPos();
+ return SZ_OK;
+ }
+ }
+ catch (...)
+ {
+ }
+
+ return SZ_ERROR_READ;
+ }
+};
+
+bool unpack7Zip(const std::string &sevenZipFile, const std::string &destFileName)
+{
+ nlinfo("Uncompressing 7zip archive '%s' to '%s'", sevenZipFile.c_str(), destFileName.c_str());
+
+ // init seven zip
+ ISzAlloc allocImp;
+ allocImp.Alloc = SzAlloc;
+ allocImp.Free = SzFree;
+
+ ISzAlloc allocTempImp;
+ allocTempImp.Alloc = SzAllocTemp;
+ allocTempImp.Free = SzFreeTemp;
+
+ // wrap file in a CIFile
+ CIFile input(sevenZipFile);
+ CNel7ZipInStream inStr(&input);
+
+ CLookToRead lookStream;
+ lookStream.realStream = &inStr;
+ LookToRead_CreateVTable(&lookStream, False);
+ LookToRead_Init(&lookStream);
+
+ CrcGenerateTable();
+
+ CSzArEx db;
+ SzArEx_Init(&db);
+
+ // unpack the file using the 7zip API
+ SRes res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
+
+ if (res != SZ_OK)
+ {
+ nlerror("Failed to open archive file %s", sevenZipFile.c_str());
+ return false;
+ }
+
+ if (db.NumFiles != 1)
+ {
+ nlerror("Seven zip archive with more than 1 file are unsupported");
+ return false;
+ }
+
+ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
+ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
+ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
+
+ size_t offset;
+ size_t outSizeProcessed = 0;
+
+ // get the first file
+ res = SzArEx_Extract(&db, &lookStream.s, 0,
+ &blockIndex, &outBuffer, &outBufferSize,
+ &offset, &outSizeProcessed,
+ &allocImp, &allocTempImp);
+
+ // get the length of first file
+ size_t nameLen = SzArEx_GetFileNameUtf16(&db, 0, NULL);
+
+ ucstring filename;
+ filename.resize(nameLen);
+
+ // write filename into ucstring
+ SzArEx_GetFileNameUtf16(&db, 0, &filename[0]);
+
+ // write the extracted file
+ FILE *outputHandle = fopen(destFileName.c_str(), "wb+");
+
+ if (outputHandle == 0)
+ {
+ nlerror("Can not open output file '%s'", destFileName.c_str());
+ return false;
+ }
+
+ UInt32 processedSize = (UInt32)fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle);
+
+ if (processedSize != outSizeProcessed)
+ {
+ nlerror("Failed to write %u char to output file '%s'", outSizeProcessed-processedSize, destFileName.c_str());
+ return false;
+ }
+
+ fclose(outputHandle);
+
+ IAlloc_Free(&allocImp, outBuffer);
+
+ // free 7z context
+ SzArEx_Free(&db, &allocImp);
+
+ // ok, all is fine, file is unpacked
+ return true;
+}
+
+bool unpackLZMA(const std::string &lzmaFile, const std::string &destFileName)
+{
+ nldebug("unpackLZMA: decompress LZMA file '%s' to '%s", lzmaFile.c_str(), destFileName.c_str());
+
+ // open input file
+ CIFile inStream(lzmaFile);
+ uint32 inSize = inStream.getFileSize();
+
+ if (inSize < LZMA_PROPS_SIZE + 8)
+ {
+ nlwarning("unpackLZMA: Invalid file size, too small file '%s'", lzmaFile.c_str());
+ return false;
+ }
+
+ // allocate input buffer for props
+ auto_ptr propsBuffer = auto_ptr(new uint8[LZMA_PROPS_SIZE]);
+
+ // size of LZMA content
+ inSize -= LZMA_PROPS_SIZE + 8;
+
+ // allocate input buffer for lzma data
+ auto_ptr inBuffer = auto_ptr(new uint8[inSize]);
+
+ uint64 fileSize = 0;
+
+ try
+ {
+ // read props
+ inStream.serialBuffer(propsBuffer.get(), LZMA_PROPS_SIZE);
+
+ // read uncompressed size
+ inStream.serial(fileSize);
+
+ // read lzma content
+ inStream.serialBuffer(inBuffer.get(), inSize);
+ }
+ catch(const EReadError &e)
+ {
+ nlwarning("unpackLZMA: Error while reading '%s': %s", lzmaFile.c_str(), e.what());
+ return false;
+ }
+
+ // allocate the output buffer
+ auto_ptr outBuffer = auto_ptr(new uint8[fileSize]);
+
+ // in and out file sizes
+ SizeT outProcessed = (SizeT)fileSize;
+ SizeT inProcessed = (SizeT)inSize;
+
+ // decompress the file in memory
+ sint res = LzmaUncompress(outBuffer.get(), &outProcessed, inBuffer.get(), &inProcessed, propsBuffer.get(), LZMA_PROPS_SIZE);
+
+ if (res != 0 || outProcessed != fileSize)
+ {
+ nlwarning("unpackLZMA: Failed to decode lzma file '%s' with status %d", lzmaFile.c_str(), res);
+ return false;
+ }
+
+ // store on output buffer
+ COFile outStream(destFileName);
+
+ try
+ {
+ // write content
+ outStream.serialBuffer(outBuffer.get(), (uint)fileSize);
+ }
+ catch(const EFile &e)
+ {
+ nlwarning("unpackLZMA: Error while writing '%s': %s", destFileName.c_str(), e.what());
+ CFile::deleteFile(destFileName);
+ return false;
+ }
+
+ return true;
+}
+
+bool packLZMA(const std::string &srcFileName, const std::string &lzmaFileName)
+{
+ nldebug("unpackLZMA: compress '%s' to LZMA file '%s", srcFileName.c_str(), lzmaFileName.c_str());
+
+ // open file
+ CIFile inStream(srcFileName);
+ size_t inSize = inStream.getFileSize();
+
+ // file empty
+ if (!inSize)
+ {
+ nlwarning("packLZMA: File '%s' not found or empty", srcFileName.c_str());
+ return false;
+ }
+
+ // allocate input buffer
+ auto_ptr inBuffer = auto_ptr(new uint8[inSize]);
+
+ try
+ {
+ // read file in buffer
+ inStream.serialBuffer(inBuffer.get(), inSize);
+ }
+ catch(const EReadError &e)
+ {
+ nlwarning("packLZMA: Error while reading '%s': %s", srcFileName.c_str(), e.what());
+ return false;
+ }
+
+ // allocate output buffer
+ size_t outSize = (11 * inSize / 10) + 65536; // worst case = 1.1 * size + 64K
+ auto_ptr outBuffer = auto_ptr(new uint8[outSize]);
+
+ // allocate buffer for props
+ size_t outPropsSize = LZMA_PROPS_SIZE;
+ auto_ptr outProps = auto_ptr(new uint8[outPropsSize]);
+
+ // compress with best compression and other default settings
+ sint res = LzmaCompress(outBuffer.get(), &outSize, inBuffer.get(), inSize, outProps.get(), &outPropsSize, 9, 1 << 24, 3, 0, 2, 32, 1);
+
+ switch(res)
+ {
+ case SZ_OK:
+ {
+ // store on output buffer
+ COFile outStream(lzmaFileName);
+
+ // unable to create file
+ if (!outStream.isOpen())
+ {
+ nlwarning("packLZMA: Unable to create '%s'", srcFileName.c_str());
+ return false;
+ }
+
+ try
+ {
+ // write props
+ outStream.serialBuffer(outProps.get(), (uint)outPropsSize);
+
+ // write uncompressed size
+ uint64 uncompressSize = inSize;
+ outStream.serial(uncompressSize);
+
+ // write content
+ outStream.serialBuffer(outBuffer.get(), (uint)outSize);
+ }
+ catch(const EFile &e)
+ {
+ nlwarning("packLZMA: Error while writing '%s': %s", lzmaFileName.c_str(), e.what());
+ CFile::deleteFile(lzmaFileName);
+ return false;
+ }
+
+ return true;
+ }
+
+ case SZ_ERROR_MEM:
+ nlwarning("packLZMA: Memory allocation error while compressing '%s' (input buffer size: %u, output buffer size: %u)", srcFileName.c_str(), (uint)inSize, (uint)outSize);
+ break;
+
+ case SZ_ERROR_PARAM:
+ nlwarning("packLZMA: Incorrect parameter while compressing '%s'", srcFileName.c_str());
+ break;
+
+ case SZ_ERROR_OUTPUT_EOF:
+ nlwarning("packLZMA: Output buffer overflow while compressing '%s' (input buffer size: %u, output buffer size: %u)", srcFileName.c_str(), (uint)inSize, (uint)outSize);
+ break;
+
+ case SZ_ERROR_THREAD:
+ nlwarning("packLZMA: Errors in multithreading functions (only for Mt version)");
+ break;
+
+ default:
+ nlwarning("packLZMA: Unknown error (%d) while compressing '%s'", res, srcFileName.c_str());
+ }
+
+ return false;
+}
diff --git a/code/ryzom/client/src/seven_zip/seven_zip.h b/code/ryzom/client/src/seven_zip/seven_zip.h
new file mode 100644
index 000000000..e471a9ac0
--- /dev/null
+++ b/code/ryzom/client/src/seven_zip/seven_zip.h
@@ -0,0 +1,31 @@
+// Ryzom - MMORPG Framework
+// Copyright (C) 2010 Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#ifndef SEVEN_ZIP_H
+#define SEVEN_ZIP_H
+
+#include
+
+// utility func to decompress a monofile 7zip archive
+bool unpack7Zip(const std::string &sevenZipFileName, const std::string &destFileName);
+
+// utility func to decompress a single LZMA packed file
+bool unpackLZMA(const std::string &lzmaFileName, const std::string &destFileName);
+
+// utility func to compress a single file to LZMA packed file
+bool packLZMA(const std::string &srcFileName, const std::string &lzmaFileName);
+
+#endif