PhysicsFS 2.0.3 imported.

This commit is contained in:
King_DuckZ 2014-02-12 23:59:58 +01:00
parent bcc0937726
commit 993311d151
459 changed files with 87785 additions and 0 deletions

View file

@ -0,0 +1,292 @@
// CreateCoder.cpp
#include "StdAfx.h"
#include "CreateCoder.h"
#include "../../Windows/PropVariant.h"
#include "../../Windows/Defs.h"
#include "FilterCoder.h"
#include "RegisterCodec.h"
static const unsigned int kNumCodecsMax = 64;
unsigned int g_NumCodecs = 0;
const CCodecInfo *g_Codecs[kNumCodecsMax];
void RegisterCodec(const CCodecInfo *codecInfo)
{
if (g_NumCodecs < kNumCodecsMax)
g_Codecs[g_NumCodecs++] = codecInfo;
}
#ifdef EXTERNAL_CODECS
static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res)
{
NWindows::NCOM::CPropVariant prop;
RINOK(codecsInfo->GetProperty(index, propID, &prop));
if (prop.vt == VT_EMPTY)
res = 1;
else if (prop.vt == VT_UI4)
res = prop.ulVal;
else
return E_INVALIDARG;
return S_OK;
}
static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res)
{
NWindows::NCOM::CPropVariant prop;
RINOK(codecsInfo->GetProperty(index, propID, &prop));
if (prop.vt == VT_EMPTY)
res = true;
else if (prop.vt == VT_BOOL)
res = VARIANT_BOOLToBool(prop.boolVal);
else
return E_INVALIDARG;
return S_OK;
}
HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs)
{
UInt32 num;
RINOK(codecsInfo->GetNumberOfMethods(&num));
for (UInt32 i = 0; i < num; i++)
{
CCodecInfoEx info;
NWindows::NCOM::CPropVariant prop;
RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop));
// if (prop.vt != VT_BSTR)
// info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);
// memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize);
if (prop.vt != VT_UI8)
{
continue; // old Interface
// return E_INVALIDARG;
}
info.Id = prop.uhVal.QuadPart;
prop.Clear();
RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop));
if (prop.vt == VT_BSTR)
info.Name = prop.bstrVal;
else if (prop.vt != VT_EMPTY)
return E_INVALIDARG;;
RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams));
RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams));
RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
externalCodecs.Add(info);
}
return S_OK;
}
#endif
bool FindMethod(
#ifdef EXTERNAL_CODECS
ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
#endif
const UString &name,
CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)
{
UInt32 i;
for (i = 0; i < g_NumCodecs; i++)
{
const CCodecInfo &codec = *g_Codecs[i];
if (name.CompareNoCase(codec.Name) == 0)
{
methodId = codec.Id;
numInStreams = codec.NumInStreams;
numOutStreams = 1;
return true;
}
}
#ifdef EXTERNAL_CODECS
if (externalCodecs)
for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
{
const CCodecInfoEx &codec = (*externalCodecs)[i];
if (codec.Name.CompareNoCase(name) == 0)
{
methodId = codec.Id;
numInStreams = codec.NumInStreams;
numOutStreams = codec.NumOutStreams;
return true;
}
}
#endif
return false;
}
bool FindMethod(
#ifdef EXTERNAL_CODECS
ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
#endif
CMethodId methodId, UString &name)
{
UInt32 i;
for (i = 0; i < g_NumCodecs; i++)
{
const CCodecInfo &codec = *g_Codecs[i];
if (methodId == codec.Id)
{
name = codec.Name;
return true;
}
}
#ifdef EXTERNAL_CODECS
if (externalCodecs)
for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
{
const CCodecInfoEx &codec = (*externalCodecs)[i];
if (methodId == codec.Id)
{
name = codec.Name;
return true;
}
}
#endif
return false;
}
HRESULT CreateCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId,
CMyComPtr<ICompressFilter> &filter,
CMyComPtr<ICompressCoder> &coder,
CMyComPtr<ICompressCoder2> &coder2,
bool encode, bool onlyCoder)
{
bool created = false;
UInt32 i;
for (i = 0; i < g_NumCodecs; i++)
{
const CCodecInfo &codec = *g_Codecs[i];
if (codec.Id == methodId)
{
if (encode)
{
if (codec.CreateEncoder)
{
void *p = codec.CreateEncoder();
if (codec.IsFilter) filter = (ICompressFilter *)p;
else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
else coder2 = (ICompressCoder2 *)p;
created = (p != 0);
break;
}
}
else
if (codec.CreateDecoder)
{
void *p = codec.CreateDecoder();
if (codec.IsFilter) filter = (ICompressFilter *)p;
else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
else coder2 = (ICompressCoder2 *)p;
created = (p != 0);
break;
}
}
}
#ifdef EXTERNAL_CODECS
if (!created && externalCodecs)
for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
{
const CCodecInfoEx &codec = (*externalCodecs)[i];
if (codec.Id == methodId)
{
if (encode)
{
if (codec.EncoderIsAssigned)
{
if (codec.IsSimpleCodec())
{
HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);
if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
return result;
if (!coder)
{
RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));
}
}
else
{
RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));
}
break;
}
}
else
if (codec.DecoderIsAssigned)
{
if (codec.IsSimpleCodec())
{
HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);
if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
return result;
if (!coder)
{
RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));
}
}
else
{
RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2));
}
break;
}
}
}
#endif
if (onlyCoder && filter)
{
CFilterCoder *coderSpec = new CFilterCoder;
coder = coderSpec;
coderSpec->Filter = filter;
}
return S_OK;
}
HRESULT CreateCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId,
CMyComPtr<ICompressCoder> &coder,
CMyComPtr<ICompressCoder2> &coder2,
bool encode)
{
CMyComPtr<ICompressFilter> filter;
return CreateCoder(
EXTERNAL_CODECS_LOC_VARS
methodId,
filter, coder, coder2, encode, true);
}
HRESULT CreateCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId,
CMyComPtr<ICompressCoder> &coder, bool encode)
{
CMyComPtr<ICompressFilter> filter;
CMyComPtr<ICompressCoder2> coder2;
return CreateCoder(
EXTERNAL_CODECS_LOC_VARS
methodId,
coder, coder2, encode);
}
HRESULT CreateFilter(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId,
CMyComPtr<ICompressFilter> &filter,
bool encode)
{
CMyComPtr<ICompressCoder> coder;
CMyComPtr<ICompressCoder2> coder2;
return CreateCoder(
EXTERNAL_CODECS_LOC_VARS
methodId,
filter, coder, coder2, encode, false);
}

View file

@ -0,0 +1,98 @@
// CreateCoder.h
#ifndef __CREATECODER_H
#define __CREATECODER_H
#include "Common/MyCom.h"
#include "Common/MyString.h"
#include "../ICoder.h"
#include "MethodId.h"
#ifdef EXTERNAL_CODECS
struct CCodecInfoEx
{
UString Name;
CMethodId Id;
UInt32 NumInStreams;
UInt32 NumOutStreams;
bool EncoderIsAssigned;
bool DecoderIsAssigned;
bool IsSimpleCodec() const { return NumOutStreams == 1 && NumInStreams == 1; }
CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {}
};
HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs);
#define PUBLIC_ISetCompressCodecsInfo public ISetCompressCodecsInfo,
#define QUERY_ENTRY_ISetCompressCodecsInfo MY_QUERYINTERFACE_ENTRY(ISetCompressCodecsInfo)
#define DECL_ISetCompressCodecsInfo STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo);
#define IMPL_ISetCompressCodecsInfo2(x) \
STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) { \
COM_TRY_BEGIN _codecsInfo = compressCodecsInfo; return LoadExternalCodecs(_codecsInfo, _externalCodecs); COM_TRY_END }
#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler)
#define EXTERNAL_CODECS_VARS2 _codecsInfo, &_externalCodecs
#define DECL_EXTERNAL_CODECS_VARS CMyComPtr<ICompressCodecsInfo> _codecsInfo; CObjectVector<CCodecInfoEx> _externalCodecs;
#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2,
#define DECL_EXTERNAL_CODECS_LOC_VARS2 ICompressCodecsInfo *codecsInfo, const CObjectVector<CCodecInfoEx> *externalCodecs
#define EXTERNAL_CODECS_LOC_VARS2 codecsInfo, externalCodecs
#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2,
#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2,
#else
#define PUBLIC_ISetCompressCodecsInfo
#define QUERY_ENTRY_ISetCompressCodecsInfo
#define DECL_ISetCompressCodecsInfo
#define IMPL_ISetCompressCodecsInfo
#define EXTERNAL_CODECS_VARS2
#define DECL_EXTERNAL_CODECS_VARS
#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2
#define DECL_EXTERNAL_CODECS_LOC_VARS2
#define EXTERNAL_CODECS_LOC_VARS2
#define DECL_EXTERNAL_CODECS_LOC_VARS
#define EXTERNAL_CODECS_LOC_VARS
#endif
bool FindMethod(
DECL_EXTERNAL_CODECS_LOC_VARS
const UString &name, CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams);
bool FindMethod(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, UString &name);
HRESULT CreateCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId,
CMyComPtr<ICompressFilter> &filter,
CMyComPtr<ICompressCoder> &coder,
CMyComPtr<ICompressCoder2> &coder2,
bool encode, bool onlyCoder);
HRESULT CreateCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId,
CMyComPtr<ICompressCoder> &coder,
CMyComPtr<ICompressCoder2> &coder2,
bool encode);
HRESULT CreateCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId,
CMyComPtr<ICompressCoder> &coder, bool encode);
HRESULT CreateFilter(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId,
CMyComPtr<ICompressFilter> &filter,
bool encode);
#endif

View file

@ -0,0 +1,57 @@
// FilePathAutoRename.cpp
#include "StdAfx.h"
#include "FilePathAutoRename.h"
#include "Common/Defs.h"
#include "Common/IntToString.h"
#include "Windows/FileName.h"
#include "Windows/FileFind.h"
using namespace NWindows;
static bool MakeAutoName(const UString &name,
const UString &extension, int value, UString &path)
{
wchar_t number[32];
ConvertUInt64ToString(value, number);
path = name;
path += number;
path += extension;
return NFile::NFind::DoesFileExist(path);
}
bool AutoRenamePath(UString &fullProcessedPath)
{
UString path;
int dotPos = fullProcessedPath.ReverseFind(L'.');
int slashPos = fullProcessedPath.ReverseFind(L'/');
#ifdef _WIN32
int slash1Pos = fullProcessedPath.ReverseFind(L'\\');
slashPos = MyMax(slashPos, slash1Pos);
#endif
UString name, extension;
if (dotPos > slashPos && dotPos > 0)
{
name = fullProcessedPath.Left(dotPos);
extension = fullProcessedPath.Mid(dotPos);
}
else
name = fullProcessedPath;
name += L'_';
int indexLeft = 1, indexRight = (1 << 30);
while (indexLeft != indexRight)
{
int indexMid = (indexLeft + indexRight) / 2;
if (MakeAutoName(name, extension, indexMid, path))
indexLeft = indexMid + 1;
else
indexRight = indexMid;
}
if (MakeAutoName(name, extension, indexRight, fullProcessedPath))
return false;
return true;
}

View file

@ -0,0 +1,10 @@
// Util/FilePathAutoRename.h
#ifndef __FILEPATHAUTORENAME_H
#define __FILEPATHAUTORENAME_H
#include "Common/MyString.h"
bool AutoRenamePath(UString &fullProcessedPath);
#endif

View file

@ -0,0 +1,261 @@
// FileStreams.cpp
#include "StdAfx.h"
#ifndef _WIN32
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#endif
#include "FileStreams.h"
static inline HRESULT ConvertBoolToHRESULT(bool result)
{
#ifdef _WIN32
if (result)
return S_OK;
DWORD lastError = ::GetLastError();
if (lastError == 0)
return E_FAIL;
return lastError;
#else
return result ? S_OK: E_FAIL;
#endif
}
bool CInFileStream::Open(LPCTSTR fileName)
{
return File.Open(fileName);
}
#ifdef USE_WIN_FILE
#ifndef _UNICODE
bool CInFileStream::Open(LPCWSTR fileName)
{
return File.Open(fileName);
}
#endif
#endif
bool CInFileStream::OpenShared(LPCTSTR fileName, bool shareForWrite)
{
return File.OpenShared(fileName, shareForWrite);
}
#ifdef USE_WIN_FILE
#ifndef _UNICODE
bool CInFileStream::OpenShared(LPCWSTR fileName, bool shareForWrite)
{
return File.OpenShared(fileName, shareForWrite);
}
#endif
#endif
STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
#ifdef USE_WIN_FILE
UInt32 realProcessedSize;
bool result = File.ReadPart(data, size, realProcessedSize);
if(processedSize != NULL)
*processedSize = realProcessedSize;
return ConvertBoolToHRESULT(result);
#else
if(processedSize != NULL)
*processedSize = 0;
ssize_t res = File.Read(data, (size_t)size);
if (res == -1)
return E_FAIL;
if(processedSize != NULL)
*processedSize = (UInt32)res;
return S_OK;
#endif
}
#ifndef _WIN32_WCE
STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
#ifdef _WIN32
UInt32 realProcessedSize;
BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE),
data, size, (DWORD *)&realProcessedSize, NULL);
if(processedSize != NULL)
*processedSize = realProcessedSize;
if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
return S_OK;
return ConvertBoolToHRESULT(res != FALSE);
#else
if(processedSize != NULL)
*processedSize = 0;
ssize_t res;
do
{
res = read(0, data, (size_t)size);
}
while (res < 0 && (errno == EINTR));
if (res == -1)
return E_FAIL;
if(processedSize != NULL)
*processedSize = (UInt32)res;
return S_OK;
#endif
}
#endif
STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
UInt64 *newPosition)
{
if(seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
#ifdef USE_WIN_FILE
UInt64 realNewPosition;
bool result = File.Seek(offset, seekOrigin, realNewPosition);
if(newPosition != NULL)
*newPosition = realNewPosition;
return ConvertBoolToHRESULT(result);
#else
off_t res = File.Seek(offset, seekOrigin);
if (res == -1)
return E_FAIL;
if(newPosition != NULL)
*newPosition = (UInt64)res;
return S_OK;
#endif
}
STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
{
return ConvertBoolToHRESULT(File.GetLength(*size));
}
//////////////////////////
// COutFileStream
HRESULT COutFileStream::Close()
{
return ConvertBoolToHRESULT(File.Close());
}
STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
#ifdef USE_WIN_FILE
UInt32 realProcessedSize;
bool result = File.WritePart(data, size, realProcessedSize);
ProcessedSize += realProcessedSize;
if(processedSize != NULL)
*processedSize = realProcessedSize;
return ConvertBoolToHRESULT(result);
#else
if(processedSize != NULL)
*processedSize = 0;
ssize_t res = File.Write(data, (size_t)size);
if (res == -1)
return E_FAIL;
if(processedSize != NULL)
*processedSize = (UInt32)res;
ProcessedSize += res;
return S_OK;
#endif
}
STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
if(seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
#ifdef USE_WIN_FILE
UInt64 realNewPosition;
bool result = File.Seek(offset, seekOrigin, realNewPosition);
if(newPosition != NULL)
*newPosition = realNewPosition;
return ConvertBoolToHRESULT(result);
#else
off_t res = File.Seek(offset, seekOrigin);
if (res == -1)
return E_FAIL;
if(newPosition != NULL)
*newPosition = (UInt64)res;
return S_OK;
#endif
}
STDMETHODIMP COutFileStream::SetSize(Int64 newSize)
{
#ifdef USE_WIN_FILE
UInt64 currentPos;
if(!File.Seek(0, FILE_CURRENT, currentPos))
return E_FAIL;
bool result = File.SetLength(newSize);
UInt64 currentPos2;
result = result && File.Seek(currentPos, currentPos2);
return result ? S_OK : E_FAIL;
#else
return E_FAIL;
#endif
}
#ifndef _WIN32_WCE
STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if(processedSize != NULL)
*processedSize = 0;
#ifdef _WIN32
UInt32 realProcessedSize;
BOOL res = TRUE;
if (size > 0)
{
// Seems that Windows doesn't like big amounts writing to stdout.
// So we limit portions by 32KB.
UInt32 sizeTemp = (1 << 15);
if (sizeTemp > size)
sizeTemp = size;
res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
size -= realProcessedSize;
data = (const void *)((const Byte *)data + realProcessedSize);
if(processedSize != NULL)
*processedSize += realProcessedSize;
}
return ConvertBoolToHRESULT(res != FALSE);
#else
ssize_t res;
do
{
res = write(1, data, (size_t)size);
}
while (res < 0 && (errno == EINTR));
if (res == -1)
return E_FAIL;
if(processedSize != NULL)
*processedSize = (UInt32)res;
return S_OK;
return S_OK;
#endif
}
#endif

View file

@ -0,0 +1,143 @@
// FileStreams.h
#ifndef __FILESTREAMS_H
#define __FILESTREAMS_H
#ifdef _WIN32
#define USE_WIN_FILE
#endif
#ifdef USE_WIN_FILE
#include "../../Windows/FileIO.h"
#else
#include "../../Common/C_FileIO.h"
#endif
#include "../IStream.h"
#include "../../Common/MyCom.h"
class CInFileStream:
public IInStream,
public IStreamGetSize,
public CMyUnknownImp
{
public:
#ifdef USE_WIN_FILE
NWindows::NFile::NIO::CInFile File;
#else
NC::NFile::NIO::CInFile File;
#endif
CInFileStream() {}
virtual ~CInFileStream() {}
bool Open(LPCTSTR fileName);
#ifdef USE_WIN_FILE
#ifndef _UNICODE
bool Open(LPCWSTR fileName);
#endif
#endif
bool OpenShared(LPCTSTR fileName, bool shareForWrite);
#ifdef USE_WIN_FILE
#ifndef _UNICODE
bool OpenShared(LPCWSTR fileName, bool shareForWrite);
#endif
#endif
MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
STDMETHOD(GetSize)(UInt64 *size);
};
#ifndef _WIN32_WCE
class CStdInFileStream:
public ISequentialInStream,
public CMyUnknownImp
{
public:
// HANDLE File;
// CStdInFileStream() File(INVALID_HANDLE_VALUE): {}
// void Open() { File = GetStdHandle(STD_INPUT_HANDLE); };
MY_UNKNOWN_IMP
virtual ~CStdInFileStream() {}
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
#endif
class COutFileStream:
public IOutStream,
public CMyUnknownImp
{
#ifdef USE_WIN_FILE
NWindows::NFile::NIO::COutFile File;
#else
NC::NFile::NIO::COutFile File;
#endif
public:
virtual ~COutFileStream() {}
bool Create(LPCTSTR fileName, bool createAlways)
{
ProcessedSize = 0;
return File.Create(fileName, createAlways);
}
bool Open(LPCTSTR fileName, DWORD creationDisposition)
{
ProcessedSize = 0;
return File.Open(fileName, creationDisposition);
}
#ifdef USE_WIN_FILE
#ifndef _UNICODE
bool Create(LPCWSTR fileName, bool createAlways)
{
ProcessedSize = 0;
return File.Create(fileName, createAlways);
}
bool Open(LPCWSTR fileName, DWORD creationDisposition)
{
ProcessedSize = 0;
return File.Open(fileName, creationDisposition);
}
#endif
#endif
HRESULT Close();
UInt64 ProcessedSize;
#ifdef USE_WIN_FILE
bool SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
{
return File.SetTime(creationTime, lastAccessTime, lastWriteTime);
}
bool SetLastWriteTime(const FILETIME *lastWriteTime)
{
return File.SetLastWriteTime(lastWriteTime);
}
#endif
MY_UNKNOWN_IMP1(IOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
STDMETHOD(SetSize)(Int64 newSize);
};
#ifndef _WIN32_WCE
class CStdOutFileStream:
public ISequentialOutStream,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP
virtual ~CStdOutFileStream() {}
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
#endif
#endif

View file

@ -0,0 +1,264 @@
// FilterCoder.cpp
#include "StdAfx.h"
#include "FilterCoder.h"
extern "C"
{
#include "../../../C/Alloc.h"
}
#include "../../Common/Defs.h"
#include "StreamUtils.h"
static const UInt32 kBufferSize = 1 << 17;
CFilterCoder::CFilterCoder()
{
_buffer = (Byte *)::MidAlloc(kBufferSize);
}
CFilterCoder::~CFilterCoder()
{
::MidFree(_buffer);
}
HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size)
{
if (_outSizeIsDefined)
{
UInt64 remSize = _outSize - _nowPos64;
if (size > remSize)
size = (UInt32)remSize;
}
UInt32 processedSize = 0;
RINOK(WriteStream(outStream, _buffer, size, &processedSize));
if (size != processedSize)
return E_FAIL;
_nowPos64 += processedSize;
return S_OK;
}
STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
ICompressProgressInfo *progress)
{
RINOK(Init());
UInt32 bufferPos = 0;
_outSizeIsDefined = (outSize != 0);
if (_outSizeIsDefined)
_outSize = *outSize;
while(NeedMore())
{
UInt32 processedSize;
// Change it: It can be optimized using ReadPart
RINOK(ReadStream(inStream, _buffer + bufferPos, kBufferSize - bufferPos, &processedSize));
UInt32 endPos = bufferPos + processedSize;
bufferPos = Filter->Filter(_buffer, endPos);
if (bufferPos > endPos)
{
for (; endPos< bufferPos; endPos++)
_buffer[endPos] = 0;
bufferPos = Filter->Filter(_buffer, endPos);
}
if (bufferPos == 0)
{
if (endPos > 0)
return WriteWithLimit(outStream, endPos);
return S_OK;
}
RINOK(WriteWithLimit(outStream, bufferPos));
if (progress != NULL)
{
RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64));
}
UInt32 i = 0;
while(bufferPos < endPos)
_buffer[i++] = _buffer[bufferPos++];
bufferPos = i;
}
return S_OK;
}
// #ifdef _ST_MODE
STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream)
{
_bufferPos = 0;
_outStream = outStream;
return Init();
}
STDMETHODIMP CFilterCoder::ReleaseOutStream()
{
_outStream.Release();
return S_OK;
};
STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 processedSizeTotal = 0;
while(size > 0)
{
UInt32 sizeMax = kBufferSize - _bufferPos;
UInt32 sizeTemp = size;
if (sizeTemp > sizeMax)
sizeTemp = sizeMax;
memmove(_buffer + _bufferPos, data, sizeTemp);
size -= sizeTemp;
processedSizeTotal += sizeTemp;
data = (const Byte *)data + sizeTemp;
UInt32 endPos = _bufferPos + sizeTemp;
_bufferPos = Filter->Filter(_buffer, endPos);
if (_bufferPos == 0)
{
_bufferPos = endPos;
break;
}
if (_bufferPos > endPos)
{
if (size != 0)
return E_FAIL;
break;
}
RINOK(WriteWithLimit(_outStream, _bufferPos));
UInt32 i = 0;
while(_bufferPos < endPos)
_buffer[i++] = _buffer[_bufferPos++];
_bufferPos = i;
}
if (processedSize != NULL)
*processedSize = processedSizeTotal;
return S_OK;
}
STDMETHODIMP CFilterCoder::Flush()
{
if (_bufferPos != 0)
{
UInt32 endPos = Filter->Filter(_buffer, _bufferPos);
if (endPos > _bufferPos)
{
for (; _bufferPos < endPos; _bufferPos++)
_buffer[_bufferPos] = 0;
if (Filter->Filter(_buffer, endPos) != endPos)
return E_FAIL;
}
UInt32 processedSize;
RINOK(WriteStream(_outStream, _buffer, _bufferPos, &processedSize));
if (_bufferPos != processedSize)
return E_FAIL;
_bufferPos = 0;
}
CMyComPtr<IOutStreamFlush> flush;
_outStream.QueryInterface(IID_IOutStreamFlush, &flush);
if (flush)
return flush->Flush();
return S_OK;
}
STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
{
_convertedPosBegin = _convertedPosEnd = _bufferPos = 0;
_inStream = inStream;
return Init();
}
STDMETHODIMP CFilterCoder::ReleaseInStream()
{
_inStream.Release();
return S_OK;
};
STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 processedSizeTotal = 0;
while(size > 0)
{
if (_convertedPosBegin != _convertedPosEnd)
{
UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin);
memmove(data, _buffer + _convertedPosBegin, sizeTemp);
_convertedPosBegin += sizeTemp;
data = (void *)((Byte *)data + sizeTemp);
size -= sizeTemp;
processedSizeTotal += sizeTemp;
break;
}
int i;
for (i = 0; _convertedPosEnd + i < _bufferPos; i++)
_buffer[i] = _buffer[i + _convertedPosEnd];
_bufferPos = i;
_convertedPosBegin = _convertedPosEnd = 0;
UInt32 processedSizeTemp;
UInt32 size0 = kBufferSize - _bufferPos;
// Optimize it:
RINOK(ReadStream(_inStream, _buffer + _bufferPos, size0, &processedSizeTemp));
_bufferPos = _bufferPos + processedSizeTemp;
_convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
if (_convertedPosEnd == 0)
{
if (_bufferPos == 0)
break;
else
{
_convertedPosEnd = _bufferPos; // check it
continue;
}
}
if (_convertedPosEnd > _bufferPos)
{
for (; _bufferPos < _convertedPosEnd; _bufferPos++)
_buffer[_bufferPos] = 0;
_convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
}
}
if (processedSize != NULL)
*processedSize = processedSizeTotal;
return S_OK;
}
// #endif // _ST_MODE
#ifndef _NO_CRYPTO
STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)
{
return _setPassword->CryptoSetPassword(data, size);
}
#endif
#ifndef EXTRACT_ONLY
STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs,
const PROPVARIANT *properties, UInt32 numProperties)
{
return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties);
}
STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)
{
return _writeCoderProperties->WriteCoderProperties(outStream);
}
/*
STDMETHODIMP CFilterCoder::ResetSalt()
{
return _CryptoResetSalt->ResetSalt();
}
*/
STDMETHODIMP CFilterCoder::ResetInitVector()
{
return _CryptoResetInitVector->ResetInitVector();
}
#endif
STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
{
return _setDecoderProperties->SetDecoderProperties2(data, size);
}

View file

@ -0,0 +1,143 @@
// FilterCoder.h
#ifndef __FILTERCODER_H
#define __FILTERCODER_H
#include "../../Common/MyCom.h"
#include "../ICoder.h"
#include "../IPassword.h"
#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \
{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
*outObject = (void *)(i *)this; AddRef(); return S_OK; }
class CFilterCoder:
public ICompressCoder,
// #ifdef _ST_MODE
public ICompressSetInStream,
public ISequentialInStream,
public ICompressSetOutStream,
public ISequentialOutStream,
public IOutStreamFlush,
// #endif
#ifndef _NO_CRYPTO
public ICryptoSetPassword,
#endif
#ifndef EXTRACT_ONLY
public ICompressSetCoderProperties,
public ICompressWriteCoderProperties,
// public ICryptoResetSalt,
public ICryptoResetInitVector,
#endif
public ICompressSetDecoderProperties2,
public CMyUnknownImp
{
protected:
Byte *_buffer;
// #ifdef _ST_MODE
CMyComPtr<ISequentialInStream> _inStream;
CMyComPtr<ISequentialOutStream> _outStream;
UInt32 _bufferPos;
UInt32 _convertedPosBegin;
UInt32 _convertedPosEnd;
// #endif
bool _outSizeIsDefined;
UInt64 _outSize;
UInt64 _nowPos64;
HRESULT Init()
{
_nowPos64 = 0;
_outSizeIsDefined = false;
return Filter->Init();
}
CMyComPtr<ICryptoSetPassword> _setPassword;
#ifndef EXTRACT_ONLY
CMyComPtr<ICompressSetCoderProperties> _SetCoderProperties;
CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties;
// CMyComPtr<ICryptoResetSalt> _CryptoResetSalt;
CMyComPtr<ICryptoResetInitVector> _CryptoResetInitVector;
#endif
CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties;
public:
CMyComPtr<ICompressFilter> Filter;
CFilterCoder();
~CFilterCoder();
HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size);
bool NeedMore() const
{ return (!_outSizeIsDefined || (_nowPos64 < _outSize)); }
public:
MY_QUERYINTERFACE_BEGIN
MY_QUERYINTERFACE_ENTRY(ICompressCoder)
// #ifdef _ST_MODE
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream)
MY_QUERYINTERFACE_ENTRY(ISequentialOutStream)
MY_QUERYINTERFACE_ENTRY(IOutStreamFlush)
// #endif
#ifndef _NO_CRYPTO
MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword)
#endif
#ifndef EXTRACT_ONLY
MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties)
MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties)
// MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt)
MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector)
#endif
MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties)
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
// #ifdef _ST_MODE
STDMETHOD(ReleaseInStream)();
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \
STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
STDMETHOD(ReleaseOutStream)();
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Flush)();
// #endif
#ifndef _NO_CRYPTO
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
#endif
#ifndef EXTRACT_ONLY
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
const PROPVARIANT *properties, UInt32 numProperties);
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
// STDMETHOD(ResetSalt)();
STDMETHOD(ResetInitVector)();
#endif
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
};
// #ifdef _ST_MODE
class CInStreamReleaser
{
public:
CFilterCoder *FilterCoder;
CInStreamReleaser(): FilterCoder(0) {}
~CInStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); }
};
class COutStreamReleaser
{
public:
CFilterCoder *FilterCoder;
COutStreamReleaser(): FilterCoder(0) {}
~COutStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); }
};
// #endif
#endif

View file

@ -0,0 +1,83 @@
// InBuffer.cpp
#include "StdAfx.h"
#include "InBuffer.h"
extern "C"
{
#include "../../../C/Alloc.h"
}
CInBuffer::CInBuffer():
_buffer(0),
_bufferLimit(0),
_bufferBase(0),
_stream(0),
_bufferSize(0)
{}
bool CInBuffer::Create(UInt32 bufferSize)
{
const UInt32 kMinBlockSize = 1;
if (bufferSize < kMinBlockSize)
bufferSize = kMinBlockSize;
if (_bufferBase != 0 && _bufferSize == bufferSize)
return true;
Free();
_bufferSize = bufferSize;
_bufferBase = (Byte *)::MidAlloc(bufferSize);
return (_bufferBase != 0);
}
void CInBuffer::Free()
{
::MidFree(_bufferBase);
_bufferBase = 0;
}
void CInBuffer::SetStream(ISequentialInStream *stream)
{
_stream = stream;
}
void CInBuffer::Init()
{
_processedSize = 0;
_buffer = _bufferBase;
_bufferLimit = _buffer;
_wasFinished = false;
#ifdef _NO_EXCEPTIONS
ErrorCode = S_OK;
#endif
}
bool CInBuffer::ReadBlock()
{
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
return false;
#endif
if (_wasFinished)
return false;
_processedSize += (_buffer - _bufferBase);
UInt32 numProcessedBytes;
HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
#ifdef _NO_EXCEPTIONS
ErrorCode = result;
#else
if (result != S_OK)
throw CInBufferException(result);
#endif
_buffer = _bufferBase;
_bufferLimit = _buffer + numProcessedBytes;
_wasFinished = (numProcessedBytes == 0);
return (!_wasFinished);
}
Byte CInBuffer::ReadBlock2()
{
if(!ReadBlock())
return 0xFF;
return *_buffer++;
}

View file

@ -0,0 +1,75 @@
// InBuffer.h
#ifndef __INBUFFER_H
#define __INBUFFER_H
#include "../IStream.h"
#include "../../Common/MyCom.h"
#include "../../Common/MyException.h"
#ifndef _NO_EXCEPTIONS
struct CInBufferException: public CSystemException
{
CInBufferException(HRESULT errorCode): CSystemException(errorCode) {}
};
#endif
class CInBuffer
{
Byte *_buffer;
Byte *_bufferLimit;
Byte *_bufferBase;
CMyComPtr<ISequentialInStream> _stream;
UInt64 _processedSize;
UInt32 _bufferSize;
bool _wasFinished;
bool ReadBlock();
Byte ReadBlock2();
public:
#ifdef _NO_EXCEPTIONS
HRESULT ErrorCode;
#endif
CInBuffer();
~CInBuffer() { Free(); }
bool Create(UInt32 bufferSize);
void Free();
void SetStream(ISequentialInStream *stream);
void Init();
void ReleaseStream() { _stream.Release(); }
bool ReadByte(Byte &b)
{
if(_buffer >= _bufferLimit)
if(!ReadBlock())
return false;
b = *_buffer++;
return true;
}
Byte ReadByte()
{
if(_buffer >= _bufferLimit)
return ReadBlock2();
return *_buffer++;
}
void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
{
for(processedSize = 0; processedSize < size; processedSize++)
if (!ReadByte(((Byte *)data)[processedSize]))
return;
}
bool ReadBytes(void *data, UInt32 size)
{
UInt32 processedSize;
ReadBytes(data, size, processedSize);
return (processedSize == size);
}
UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
bool WasFinished() const { return _wasFinished; }
};
#endif

View file

@ -0,0 +1,122 @@
// InOutTempBuffer.cpp
#include "StdAfx.h"
#include "InOutTempBuffer.h"
#include "../../Common/Defs.h"
// #include "Windows/Defs.h"
#include "StreamUtils.h"
using namespace NWindows;
using namespace NFile;
using namespace NDirectory;
static UInt32 kTmpBufferMemorySize = (1 << 20);
static LPCTSTR kTempFilePrefixString = TEXT("iot");
CInOutTempBuffer::CInOutTempBuffer():
_buffer(NULL)
{
}
void CInOutTempBuffer::Create()
{
_buffer = new Byte[kTmpBufferMemorySize];
}
CInOutTempBuffer::~CInOutTempBuffer()
{
delete []_buffer;
}
void CInOutTempBuffer::InitWriting()
{
_bufferPosition = 0;
_tmpFileCreated = false;
_fileSize = 0;
}
bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
{
if (size == 0)
return true;
if(!_tmpFileCreated)
{
CSysString tempDirPath;
if(!MyGetTempPath(tempDirPath))
return false;
if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tmpFileName) == 0)
return false;
// _outFile.SetOpenCreationDispositionCreateAlways();
if(!_outFile.Create(_tmpFileName, true))
return false;
_tmpFileCreated = true;
}
UInt32 processedSize;
if(!_outFile.Write(data, size, processedSize))
return false;
_fileSize += processedSize;
return (processedSize == size);
}
bool CInOutTempBuffer::FlushWrite()
{
return _outFile.Close();
}
bool CInOutTempBuffer::Write(const void *data, UInt32 size)
{
if(_bufferPosition < kTmpBufferMemorySize)
{
UInt32 curSize = MyMin(kTmpBufferMemorySize - _bufferPosition, size);
memmove(_buffer + _bufferPosition, (const Byte *)data, curSize);
_bufferPosition += curSize;
size -= curSize;
data = ((const Byte *)data) + curSize;
_fileSize += curSize;
}
return WriteToFile(data, size);
}
bool CInOutTempBuffer::InitReading()
{
_currentPositionInBuffer = 0;
if(_tmpFileCreated)
return _inFile.Open(_tmpFileName);
return true;
}
HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
{
if (_currentPositionInBuffer < _bufferPosition)
{
UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer;
RINOK(WriteStream(stream, _buffer + _currentPositionInBuffer, sizeToWrite, NULL));
_currentPositionInBuffer += sizeToWrite;
}
if (!_tmpFileCreated)
return true;
for (;;)
{
UInt32 localProcessedSize;
if (!_inFile.ReadPart(_buffer, kTmpBufferMemorySize, localProcessedSize))
return E_FAIL;
if (localProcessedSize == 0)
return S_OK;
RINOK(WriteStream(stream, _buffer, localProcessedSize, NULL));
}
}
STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (!_buffer->Write(data, size))
{
if (processedSize != NULL)
*processedSize = 0;
return E_FAIL;
}
if (processedSize != NULL)
*processedSize = size;
return S_OK;
}

View file

@ -0,0 +1,55 @@
// Util/InOutTempBuffer.h
#ifndef __IN_OUT_TEMP_BUFFER_H
#define __IN_OUT_TEMP_BUFFER_H
#include "../../Windows/FileIO.h"
#include "../../Windows/FileDir.h"
#include "../../Common/MyCom.h"
#include "../IStream.h"
class CInOutTempBuffer
{
NWindows::NFile::NDirectory::CTempFile _tempFile;
NWindows::NFile::NIO::COutFile _outFile;
NWindows::NFile::NIO::CInFile _inFile;
Byte *_buffer;
UInt32 _bufferPosition;
UInt32 _currentPositionInBuffer;
CSysString _tmpFileName;
bool _tmpFileCreated;
UInt64 _fileSize;
bool WriteToFile(const void *data, UInt32 size);
public:
CInOutTempBuffer();
~CInOutTempBuffer();
void Create();
void InitWriting();
bool Write(const void *data, UInt32 size);
UInt64 GetDataSize() const { return _fileSize; }
bool FlushWrite();
bool InitReading();
HRESULT WriteToStream(ISequentialOutStream *stream);
};
class CSequentialOutTempBufferImp:
public ISequentialOutStream,
public CMyUnknownImp
{
CInOutTempBuffer *_buffer;
public:
// CSequentialOutStreamImp(): _size(0) {}
// UInt32 _size;
void Init(CInOutTempBuffer *buffer) { _buffer = buffer; }
// UInt32 GetSize() const { return _size; }
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
#endif

View file

@ -0,0 +1,24 @@
// LimitedStreams.cpp
#include "StdAfx.h"
#include "LimitedStreams.h"
#include "../../Common/Defs.h"
STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize = 0;
UInt32 sizeToRead = (UInt32)MyMin((_size - _pos), (UInt64)size);
HRESULT result = S_OK;
if (sizeToRead > 0)
{
result = _stream->Read(data, sizeToRead, &realProcessedSize);
_pos += realProcessedSize;
if (realProcessedSize == 0)
_wasFinished = true;
}
if(processedSize != NULL)
*processedSize = realProcessedSize;
return result;
}

View file

@ -0,0 +1,33 @@
// LimitedStreams.h
#ifndef __LIMITEDSTREAMS_H
#define __LIMITEDSTREAMS_H
#include "../../Common/MyCom.h"
#include "../IStream.h"
class CLimitedSequentialInStream:
public ISequentialInStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialInStream> _stream;
UInt64 _size;
UInt64 _pos;
bool _wasFinished;
public:
void SetStream(ISequentialInStream *stream) { _stream = stream; }
void Init(UInt64 streamSize)
{
_size = streamSize;
_pos = 0;
_wasFinished = false;
}
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
UInt64 GetSize() const { return _pos; }
bool WasFinished() const { return _wasFinished; }
};
#endif

View file

@ -0,0 +1,23 @@
// LockedStream.cpp
#include "StdAfx.h"
#include "LockedStream.h"
HRESULT CLockedInStream::Read(UInt64 startPos, void *data, UInt32 size,
UInt32 *processedSize)
{
NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL));
return _stream->Read(data, size, processedSize);
}
STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize = 0;
HRESULT result = _lockedInStream->Read(_pos, data, size, &realProcessedSize);
_pos += realProcessedSize;
if (processedSize != NULL)
*processedSize = realProcessedSize;
return result;
}

View file

@ -0,0 +1,38 @@
// LockedStream.h
#ifndef __LOCKEDSTREAM_H
#define __LOCKEDSTREAM_H
#include "../../Windows/Synchronization.h"
#include "../../Common/MyCom.h"
#include "../IStream.h"
class CLockedInStream
{
CMyComPtr<IInStream> _stream;
NWindows::NSynchronization::CCriticalSection _criticalSection;
public:
void Init(IInStream *stream)
{ _stream = stream; }
HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize);
};
class CLockedSequentialInStreamImp:
public ISequentialInStream,
public CMyUnknownImp
{
CLockedInStream *_lockedInStream;
UInt64 _pos;
public:
void Init(CLockedInStream *lockedInStream, UInt64 startPos)
{
_lockedInStream = lockedInStream;
_pos = startPos;
}
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
#endif

View file

@ -0,0 +1,27 @@
// MethodId.cpp
#include "StdAfx.h"
#include "MethodId.h"
#include "../../Common/MyString.h"
static inline wchar_t GetHex(Byte value)
{
return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
}
UString ConvertMethodIdToString(UInt64 id)
{
wchar_t s[32];
int len = 32;
s[--len] = 0;
do
{
s[--len] = GetHex((Byte)id & 0xF);
id >>= 4;
s[--len] = GetHex((Byte)id & 0xF);
id >>= 4;
}
while (id != 0);
return s + len;
}

View file

@ -0,0 +1,10 @@
// MethodId.h
#ifndef __7Z_METHOD_ID_H
#define __7Z_METHOD_ID_H
#include "../../Common/Types.h"
typedef UInt64 CMethodId;
#endif

View file

@ -0,0 +1,96 @@
// MethodProps.cpp
#include "StdAfx.h"
#include "MethodProps.h"
#include "../../Common/MyCom.h"
static UInt64 k_LZMA = 0x030101;
// static UInt64 k_LZMA2 = 0x030102;
HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder)
{
bool tryReduce = false;
UInt32 reducedDictionarySize = 1 << 10;
if (inSizeForReduce != 0 && (method.Id == k_LZMA /* || methodFull.MethodID == k_LZMA2 */))
{
for (;;)
{
const UInt32 step = (reducedDictionarySize >> 1);
if (reducedDictionarySize >= *inSizeForReduce)
{
tryReduce = true;
break;
}
reducedDictionarySize += step;
if (reducedDictionarySize >= *inSizeForReduce)
{
tryReduce = true;
break;
}
if (reducedDictionarySize >= ((UInt32)3 << 30))
break;
reducedDictionarySize += step;
}
}
{
int numProperties = method.Properties.Size();
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
if (setCoderProperties == NULL)
{
if (numProperties != 0)
return E_INVALIDARG;
}
else
{
CRecordVector<PROPID> propIDs;
NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProperties];
HRESULT res = S_OK;
try
{
for (int i = 0; i < numProperties; i++)
{
const CProp &prop = method.Properties[i];
propIDs.Add(prop.Id);
NWindows::NCOM::CPropVariant &value = values[i];
value = prop.Value;
// if (tryReduce && prop.Id == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
if (tryReduce)
if (prop.Id == NCoderPropID::kDictionarySize)
if (value.vt == VT_UI4)
if (reducedDictionarySize < value.ulVal)
value.ulVal = reducedDictionarySize;
}
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
res = setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties);
}
catch(...)
{
delete []values;
throw;
}
delete []values;
RINOK(res);
}
}
/*
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
if (writeCoderProperties != NULL)
{
CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init();
RINOK(writeCoderProperties->WriteCoderProperties(outStream));
size_t size = outStreamSpec->GetSize();
filterProps.SetCapacity(size);
memmove(filterProps, outStreamSpec->GetBuffer(), size);
}
*/
return S_OK;
}

View file

@ -0,0 +1,41 @@
// MethodProps.h
#ifndef __7Z_METHOD_PROPS_H
#define __7Z_METHOD_PROPS_H
#include "MethodId.h"
#include "../../Windows/PropVariant.h"
#include "../../Common/MyVector.h"
#include "../ICoder.h"
struct CProp
{
PROPID Id;
NWindows::NCOM::CPropVariant Value;
};
struct CMethod
{
CMethodId Id;
CObjectVector<CProp> Properties;
};
struct CMethodsMode
{
CObjectVector<CMethod> Methods;
#ifdef COMPRESS_MT
UInt32 NumThreads;
#endif
CMethodsMode()
#ifdef COMPRESS_MT
: NumThreads(1)
#endif
{}
bool IsEmpty() const { return Methods.IsEmpty() ; }
};
HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder);
#endif

View file

@ -0,0 +1,35 @@
// OffsetStream.cpp
#include "StdAfx.h"
#include "Common/Defs.h"
#include "OffsetStream.h"
HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset)
{
_offset = offset;
_stream = stream;
return _stream->Seek(offset, STREAM_SEEK_SET, NULL);
}
STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
return _stream->Write(data, size, processedSize);
}
STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin,
UInt64 *newPosition)
{
UInt64 absoluteNewPosition;
if (seekOrigin == STREAM_SEEK_SET)
offset += _offset;
HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition);
if (newPosition != NULL)
*newPosition = absoluteNewPosition - _offset;
return result;
}
STDMETHODIMP COffsetOutStream::SetSize(Int64 newSize)
{
return _stream->SetSize(_offset + newSize);
}

View file

@ -0,0 +1,25 @@
// OffsetStream.h
#ifndef __OFFSETSTREAM_H
#define __OFFSETSTREAM_H
#include "Common/MyCom.h"
#include "../IStream.h"
class COffsetOutStream:
public IOutStream,
public CMyUnknownImp
{
UInt64 _offset;
CMyComPtr<IOutStream> _stream;
public:
HRESULT Init(IOutStream *stream, UInt64 offset);
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
STDMETHOD(SetSize)(Int64 newSize);
};
#endif

View file

@ -0,0 +1,119 @@
// OutByte.cpp
#include "StdAfx.h"
#include "OutBuffer.h"
extern "C"
{
#include "../../../C/Alloc.h"
}
bool COutBuffer::Create(UInt32 bufferSize)
{
const UInt32 kMinBlockSize = 1;
if (bufferSize < kMinBlockSize)
bufferSize = kMinBlockSize;
if (_buffer != 0 && _bufferSize == bufferSize)
return true;
Free();
_bufferSize = bufferSize;
_buffer = (Byte *)::MidAlloc(bufferSize);
return (_buffer != 0);
}
void COutBuffer::Free()
{
::MidFree(_buffer);
_buffer = 0;
}
void COutBuffer::SetStream(ISequentialOutStream *stream)
{
_stream = stream;
}
void COutBuffer::Init()
{
_streamPos = 0;
_limitPos = _bufferSize;
_pos = 0;
_processedSize = 0;
_overDict = false;
#ifdef _NO_EXCEPTIONS
ErrorCode = S_OK;
#endif
}
UInt64 COutBuffer::GetProcessedSize() const
{
UInt64 res = _processedSize + _pos - _streamPos;
if (_streamPos > _pos)
res += _bufferSize;
return res;
}
HRESULT COutBuffer::FlushPart()
{
// _streamPos < _bufferSize
UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
HRESULT result = S_OK;
#ifdef _NO_EXCEPTIONS
result = ErrorCode;
#endif
if (_buffer2 != 0)
{
memmove(_buffer2, _buffer + _streamPos, size);
_buffer2 += size;
}
if (_stream != 0
#ifdef _NO_EXCEPTIONS
&& (ErrorCode == S_OK)
#endif
)
{
UInt32 processedSize = 0;
result = _stream->Write(_buffer + _streamPos, size, &processedSize);
size = processedSize;
}
_streamPos += size;
if (_streamPos == _bufferSize)
_streamPos = 0;
if (_pos == _bufferSize)
{
_overDict = true;
_pos = 0;
}
_limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
_processedSize += size;
return result;
}
HRESULT COutBuffer::Flush()
{
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
return ErrorCode;
#endif
while(_streamPos != _pos)
{
HRESULT result = FlushPart();
if (result != S_OK)
return result;
}
return S_OK;
}
void COutBuffer::FlushWithCheck()
{
HRESULT result = Flush();
#ifdef _NO_EXCEPTIONS
ErrorCode = result;
#else
if (result != S_OK)
throw COutBufferException(result);
#endif
}

View file

@ -0,0 +1,64 @@
// OutBuffer.h
#ifndef __OUTBUFFER_H
#define __OUTBUFFER_H
#include "../IStream.h"
#include "../../Common/MyCom.h"
#include "../../Common/MyException.h"
#ifndef _NO_EXCEPTIONS
struct COutBufferException: public CSystemException
{
COutBufferException(HRESULT errorCode): CSystemException(errorCode) {}
};
#endif
class COutBuffer
{
protected:
Byte *_buffer;
UInt32 _pos;
UInt32 _limitPos;
UInt32 _streamPos;
UInt32 _bufferSize;
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _processedSize;
Byte *_buffer2;
bool _overDict;
HRESULT FlushPart();
public:
#ifdef _NO_EXCEPTIONS
HRESULT ErrorCode;
#endif
COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
~COutBuffer() { Free(); }
bool Create(UInt32 bufferSize);
void Free();
void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
void SetStream(ISequentialOutStream *stream);
void Init();
HRESULT Flush();
void FlushWithCheck();
void ReleaseStream() { _stream.Release(); }
void WriteByte(Byte b)
{
_buffer[_pos++] = b;
if(_pos == _limitPos)
FlushWithCheck();
}
void WriteBytes(const void *data, size_t size)
{
for (size_t i = 0; i < size; i++)
WriteByte(((const Byte *)data)[i]);
}
UInt64 GetProcessedSize() const;
};
#endif

View file

@ -0,0 +1,42 @@
// ProgressUtils.h
#include "StdAfx.h"
#include "ProgressUtils.h"
CLocalProgress::CLocalProgress()
{
ProgressOffset = InSize = OutSize = 0;
SendRatio = SendProgress = true;
}
void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain)
{
_ratioProgress.Release();
_progress = progress;
_progress.QueryInterface(IID_ICompressProgressInfo, &_ratioProgress);
_inSizeIsMain = inSizeIsMain;
}
STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
{
UInt64 inSizeNew = InSize, outSizeNew = OutSize;
if (inSize)
inSizeNew += (*inSize);
if (outSize)
outSizeNew += (*outSize);
if (SendRatio && _ratioProgress)
{
RINOK(_ratioProgress->SetRatioInfo(&inSizeNew, &outSizeNew));
}
inSizeNew += ProgressOffset;
outSizeNew += ProgressOffset;
if (SendProgress)
return _progress->SetCompleted(_inSizeIsMain ? &inSizeNew : &outSizeNew);
return S_OK;
}
HRESULT CLocalProgress::SetCur()
{
return SetRatioInfo(NULL, NULL);
}

View file

@ -0,0 +1,34 @@
// ProgressUtils.h
#ifndef __PROGRESSUTILS_H
#define __PROGRESSUTILS_H
#include "../../Common/MyCom.h"
#include "../ICoder.h"
#include "../IProgress.h"
class CLocalProgress:
public ICompressProgressInfo,
public CMyUnknownImp
{
CMyComPtr<IProgress> _progress;
CMyComPtr<ICompressProgressInfo> _ratioProgress;
bool _inSizeIsMain;
public:
UInt64 ProgressOffset;
UInt64 InSize;
UInt64 OutSize;
bool SendRatio;
bool SendProgress;
CLocalProgress();
void Init(IProgress *progress, bool inSizeIsMain);
HRESULT SetCur();
MY_UNKNOWN_IMP
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
#endif

View file

@ -0,0 +1,36 @@
// RegisterArc.h
#ifndef __REGISTERARC_H
#define __REGISTERARC_H
#include "../Archive/IArchive.h"
typedef IInArchive * (*CreateInArchiveP)();
typedef IOutArchive * (*CreateOutArchiveP)();
struct CArcInfo
{
const wchar_t *Name;
const wchar_t *Ext;
const wchar_t *AddExt;
Byte ClassId;
Byte Signature[16];
int SignatureSize;
bool KeepName;
CreateInArchiveP CreateInArchive;
CreateOutArchiveP CreateOutArchive;
};
void RegisterArc(const CArcInfo *arcInfo);
#define REGISTER_ARC_NAME(x) CRegister ## x
#define REGISTER_ARC_DEC_SIG(x) struct REGISTER_ARC_NAME(x) { \
REGISTER_ARC_NAME(x)() { g_ArcInfo.Signature[0]--; RegisterArc(&g_ArcInfo); }}; \
static REGISTER_ARC_NAME(x) g_RegisterArc;
#define REGISTER_ARC(x) struct REGISTER_ARC_NAME(x) { \
REGISTER_ARC_NAME(x)() { RegisterArc(&g_ArcInfo); }}; \
static REGISTER_ARC_NAME(x) g_RegisterArc;
#endif

View file

@ -0,0 +1,33 @@
// RegisterCodec.h
#ifndef __REGISTERCODEC_H
#define __REGISTERCODEC_H
#include "../Common/MethodId.h"
typedef void * (*CreateCodecP)();
struct CCodecInfo
{
CreateCodecP CreateDecoder;
CreateCodecP CreateEncoder;
CMethodId Id;
const wchar_t *Name;
UInt32 NumInStreams;
bool IsFilter;
};
void RegisterCodec(const CCodecInfo *codecInfo);
#define REGISTER_CODEC_NAME(x) CRegisterCodec ## x
#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \
REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo); }}; \
static REGISTER_CODEC_NAME(x) g_RegisterCodec;
#define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x
#define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \
REGISTER_CODECS_NAME(x)() { for (int i = 0; i < sizeof(g_CodecsInfo) / sizeof(g_CodecsInfo[0]); i++) \
RegisterCodec(&g_CodecsInfo[i]); }}; \
static REGISTER_CODECS_NAME(x) g_RegisterCodecs;
#endif

View file

@ -0,0 +1,9 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../Common/MyWindows.h"
#include "../../Common/NewHandler.h"
#endif

View file

@ -0,0 +1,150 @@
// StreamBinder.cpp
#include "StdAfx.h"
#include "StreamBinder.h"
#include "../../Common/Defs.h"
#include "../../Common/MyCom.h"
using namespace NWindows;
using namespace NSynchronization;
class CSequentialInStreamForBinder:
public ISequentialInStream,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
private:
CStreamBinder *m_StreamBinder;
public:
~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); }
void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
};
STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
{ return m_StreamBinder->Read(data, size, processedSize); }
class CSequentialOutStreamForBinder:
public ISequentialOutStream,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
private:
CStreamBinder *m_StreamBinder;
public:
~CSequentialOutStreamForBinder() { m_StreamBinder->CloseWrite(); }
void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
};
STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
{ return m_StreamBinder->Write(data, size, processedSize); }
//////////////////////////
// CStreamBinder
// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished.
HRes CStreamBinder::CreateEvents()
{
RINOK(_allBytesAreWritenEvent.Create(true));
RINOK(_thereAreBytesToReadEvent.Create());
return _readStreamIsClosedEvent.Create();
}
void CStreamBinder::ReInit()
{
_thereAreBytesToReadEvent.Reset();
_readStreamIsClosedEvent.Reset();
ProcessedSize = 0;
}
void CStreamBinder::CreateStreams(ISequentialInStream **inStream,
ISequentialOutStream **outStream)
{
CSequentialInStreamForBinder *inStreamSpec = new
CSequentialInStreamForBinder;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
inStreamSpec->SetBinder(this);
*inStream = inStreamLoc.Detach();
CSequentialOutStreamForBinder *outStreamSpec = new
CSequentialOutStreamForBinder;
CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec);
outStreamSpec->SetBinder(this);
*outStream = outStreamLoc.Detach();
_buffer = NULL;
_bufferSize= 0;
ProcessedSize = 0;
}
HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 sizeToRead = size;
if (size > 0)
{
RINOK(_thereAreBytesToReadEvent.Lock());
sizeToRead = MyMin(_bufferSize, size);
if (_bufferSize > 0)
{
MoveMemory(data, _buffer, sizeToRead);
_buffer = ((const Byte *)_buffer) + sizeToRead;
_bufferSize -= sizeToRead;
if (_bufferSize == 0)
{
_thereAreBytesToReadEvent.Reset();
_allBytesAreWritenEvent.Set();
}
}
}
if (processedSize != NULL)
*processedSize = sizeToRead;
ProcessedSize += sizeToRead;
return S_OK;
}
void CStreamBinder::CloseRead()
{
_readStreamIsClosedEvent.Set();
}
HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (size > 0)
{
_buffer = data;
_bufferSize = size;
_allBytesAreWritenEvent.Reset();
_thereAreBytesToReadEvent.Set();
HANDLE events[2];
events[0] = _allBytesAreWritenEvent;
events[1] = _readStreamIsClosedEvent;
DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
if (waitResult != WAIT_OBJECT_0 + 0)
{
// ReadingWasClosed = true;
return S_FALSE;
}
// if(!_allBytesAreWritenEvent.Lock())
// return E_FAIL;
}
if (processedSize != NULL)
*processedSize = size;
return S_OK;
}
void CStreamBinder::CloseWrite()
{
// _bufferSize must be = 0
_thereAreBytesToReadEvent.Set();
}

View file

@ -0,0 +1,32 @@
// StreamBinder.h
#ifndef __STREAMBINDER_H
#define __STREAMBINDER_H
#include "../IStream.h"
#include "../../Windows/Synchronization.h"
class CStreamBinder
{
NWindows::NSynchronization::CManualResetEvent _allBytesAreWritenEvent;
NWindows::NSynchronization::CManualResetEvent _thereAreBytesToReadEvent;
NWindows::NSynchronization::CManualResetEvent _readStreamIsClosedEvent;
UInt32 _bufferSize;
const void *_buffer;
public:
// bool ReadingWasClosed;
UInt64 ProcessedSize;
CStreamBinder() {}
HRes CreateEvents();
void CreateStreams(ISequentialInStream **inStream,
ISequentialOutStream **outStream);
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
void CloseRead();
HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);
void CloseWrite();
void ReInit();
};
#endif

View file

@ -0,0 +1,68 @@
// StreamObjects.cpp
#include "StdAfx.h"
#include "StreamObjects.h"
#include "../../Common/Defs.h"
STDMETHODIMP CSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 numBytesToRead = (UInt32)(MyMin(_pos + size, _size) - _pos);
memmove(data, _dataPointer + _pos, numBytesToRead);
_pos += numBytesToRead;
if(processedSize != NULL)
*processedSize = numBytesToRead;
return S_OK;
}
void CWriteBuffer::Write(const void *data, size_t size)
{
size_t newCapacity = _size + size;
_buffer.EnsureCapacity(newCapacity);
memmove(_buffer + _size, data, size);
_size += size;
}
STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
_writeBuffer.Write(data, size);
if(processedSize != NULL)
*processedSize = size;
return S_OK;
}
STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 newSize = size;
if (_pos + size > _size)
newSize = (UInt32)(_size - _pos);
memmove(_buffer + _pos, data, newSize);
if(processedSize != NULL)
*processedSize = newSize;
_pos += newSize;
if (newSize != size)
return E_FAIL;
return S_OK;
}
STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
HRESULT result = _stream->Read(data, size, &realProcessedSize);
_size += realProcessedSize;
if (processedSize != 0)
*processedSize = realProcessedSize;
return result;
}
STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
HRESULT result = _stream->Write(data, size, &realProcessedSize);
_size += realProcessedSize;
if (processedSize != 0)
*processedSize = realProcessedSize;
return result;
}

View file

@ -0,0 +1,117 @@
// StreamObjects.h
#ifndef __STREAMOBJECTS_H
#define __STREAMOBJECTS_H
#include "../../Common/DynamicBuffer.h"
#include "../../Common/MyCom.h"
#include "../IStream.h"
class CSequentialInStreamImp:
public ISequentialInStream,
public CMyUnknownImp
{
const Byte *_dataPointer;
size_t _size;
size_t _pos;
public:
void Init(const Byte *dataPointer, size_t size)
{
_dataPointer = dataPointer;
_size = size;
_pos = 0;
}
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
class CWriteBuffer
{
CByteDynamicBuffer _buffer;
size_t _size;
public:
CWriteBuffer(): _size(0) {}
void Init() { _size = 0; }
void Write(const void *data, size_t size);
size_t GetSize() const { return _size; }
const CByteDynamicBuffer& GetBuffer() const { return _buffer; }
};
class CSequentialOutStreamImp:
public ISequentialOutStream,
public CMyUnknownImp
{
CWriteBuffer _writeBuffer;
public:
void Init() { _writeBuffer.Init(); }
size_t GetSize() const { return _writeBuffer.GetSize(); }
const CByteDynamicBuffer& GetBuffer() const { return _writeBuffer.GetBuffer(); }
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
class CSequentialOutStreamImp2:
public ISequentialOutStream,
public CMyUnknownImp
{
Byte *_buffer;
size_t _size;
size_t _pos;
public:
void Init(Byte *buffer, size_t size)
{
_buffer = buffer;
_pos = 0;
_size = size;
}
size_t GetPos() const { return _pos; }
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
class CSequentialInStreamSizeCount:
public ISequentialInStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialInStream> _stream;
UInt64 _size;
public:
void Init(ISequentialInStream *stream)
{
_stream = stream;
_size = 0;
}
UInt64 GetSize() const { return _size; }
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
class CSequentialOutStreamSizeCount:
public ISequentialOutStream,
public CMyUnknownImp
{
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
public:
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void Init() { _size = 0; }
UInt64 GetSize() const { return _size; }
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
#endif

View file

@ -0,0 +1,44 @@
// StreamUtils.cpp
#include "StdAfx.h"
#include "../../Common/MyCom.h"
#include "StreamUtils.h"
HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize != 0)
*processedSize = 0;
while(size != 0)
{
UInt32 processedSizeLoc;
HRESULT res = stream->Read(data, size, &processedSizeLoc);
if (processedSize != 0)
*processedSize += processedSizeLoc;
data = (Byte *)((Byte *)data + processedSizeLoc);
size -= processedSizeLoc;
RINOK(res);
if (processedSizeLoc == 0)
return S_OK;
}
return S_OK;
}
HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize != 0)
*processedSize = 0;
while(size != 0)
{
UInt32 processedSizeLoc;
HRESULT res = stream->Write(data, size, &processedSizeLoc);
if (processedSize != 0)
*processedSize += processedSizeLoc;
data = (const void *)((const Byte *)data + processedSizeLoc);
size -= processedSizeLoc;
RINOK(res);
if (processedSizeLoc == 0)
return E_FAIL;
}
return S_OK;
}

View file

@ -0,0 +1,11 @@
// StreamUtils.h
#ifndef __STREAMUTILS_H
#define __STREAMUTILS_H
#include "../IStream.h"
HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize);
HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize);
#endif

View file

@ -0,0 +1,45 @@
// VirtThread.cpp
#include "StdAfx.h"
#include "VirtThread.h"
static THREAD_FUNC_DECL CoderThread(void *p)
{
for (;;)
{
CVirtThread *t = (CVirtThread *)p;
t->StartEvent.Lock();
if (t->ExitEvent)
return 0;
t->Execute();
t->FinishedEvent.Set();
}
}
HRes CVirtThread::Create()
{
RINOK(StartEvent.CreateIfNotCreated());
RINOK(FinishedEvent.CreateIfNotCreated());
StartEvent.Reset();
FinishedEvent.Reset();
ExitEvent = false;
if (Thread.IsCreated())
return S_OK;
return Thread.Create(CoderThread, this);
}
void CVirtThread::Start()
{
ExitEvent = false;
StartEvent.Set();
}
CVirtThread::~CVirtThread()
{
ExitEvent = true;
if (StartEvent.IsCreated())
StartEvent.Set();
Thread.Wait();
}

View file

@ -0,0 +1,23 @@
// VirtThread.h
#ifndef __VIRTTHREAD_H
#define __VIRTTHREAD_H
#include "../../Windows/Synchronization.h"
#include "../../Windows/Thread.h"
struct CVirtThread
{
NWindows::NSynchronization::CAutoResetEvent StartEvent;
NWindows::NSynchronization::CAutoResetEvent FinishedEvent;
NWindows::CThread Thread;
bool ExitEvent;
~CVirtThread();
HRes Create();
void Start();
void WaitFinish() { FinishedEvent.Lock(); }
virtual void Execute() = 0;
};
#endif