mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-11 20:07:19 -06:00
Update to 7-Zip Version 21.02
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// CWrappers.h
|
||||
// CWrappers.c
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -158,27 +158,27 @@ void CSeekInStreamWrap::Init(IInStream *stream) throw()
|
||||
void CByteInBufWrap::Free() throw()
|
||||
{
|
||||
::MidFree(Buf);
|
||||
Buf = 0;
|
||||
Buf = NULL;
|
||||
}
|
||||
|
||||
bool CByteInBufWrap::Alloc(UInt32 size) throw()
|
||||
{
|
||||
if (Buf == 0 || size != Size)
|
||||
if (!Buf || size != Size)
|
||||
{
|
||||
Free();
|
||||
Lim = Cur = Buf = (Byte *)::MidAlloc((size_t)size);
|
||||
Size = size;
|
||||
}
|
||||
return (Buf != 0);
|
||||
return (Buf != NULL);
|
||||
}
|
||||
|
||||
Byte CByteInBufWrap::ReadByteFromNewBlock() throw()
|
||||
{
|
||||
if (Res == S_OK)
|
||||
if (!Extra && Res == S_OK)
|
||||
{
|
||||
UInt32 avail;
|
||||
Processed += (Cur - Buf);
|
||||
Res = Stream->Read(Buf, Size, &avail);
|
||||
Processed += (size_t)(Cur - Buf);
|
||||
Cur = Buf;
|
||||
Lim = Buf + avail;
|
||||
if (avail != 0)
|
||||
@@ -196,41 +196,88 @@ static Byte Wrap_ReadByte(const IByteIn *pp) throw()
|
||||
return p->ReadByteFromNewBlock();
|
||||
}
|
||||
|
||||
CByteInBufWrap::CByteInBufWrap(): Buf(0)
|
||||
CByteInBufWrap::CByteInBufWrap(): Buf(NULL)
|
||||
{
|
||||
vt.Read = Wrap_ReadByte;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ---------- CByteOutBufWrap ---------- */
|
||||
|
||||
/*
|
||||
void CLookToSequentialWrap::Free() throw()
|
||||
{
|
||||
::MidFree(BufBase);
|
||||
BufBase = NULL;
|
||||
}
|
||||
|
||||
bool CLookToSequentialWrap::Alloc(UInt32 size) throw()
|
||||
{
|
||||
if (!BufBase || size != Size)
|
||||
{
|
||||
Free();
|
||||
BufBase = (Byte *)::MidAlloc((size_t)size);
|
||||
Size = size;
|
||||
}
|
||||
return (BufBase != NULL);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
void CLookToSequentialWrap_Look(ILookInSeqStream *pp)
|
||||
{
|
||||
CLookToSequentialWrap *p = (CLookToSequentialWrap *)pp->Obj;
|
||||
|
||||
if (p->Extra || p->Res != S_OK)
|
||||
return;
|
||||
{
|
||||
UInt32 avail;
|
||||
p->Res = p->Stream->Read(p->BufBase, p->Size, &avail);
|
||||
p->Processed += avail;
|
||||
pp->Buf = p->BufBase;
|
||||
pp->Limit = pp->Buf + avail;
|
||||
if (avail == 0)
|
||||
p->Extra = true;
|
||||
}
|
||||
}
|
||||
|
||||
EXTERN_C_END
|
||||
*/
|
||||
|
||||
|
||||
/* ---------- CByteOutBufWrap ---------- */
|
||||
|
||||
void CByteOutBufWrap::Free() throw()
|
||||
{
|
||||
::MidFree(Buf);
|
||||
Buf = 0;
|
||||
Buf = NULL;
|
||||
}
|
||||
|
||||
bool CByteOutBufWrap::Alloc(size_t size) throw()
|
||||
{
|
||||
if (Buf == 0 || size != Size)
|
||||
if (!Buf || size != Size)
|
||||
{
|
||||
Free();
|
||||
Buf = (Byte *)::MidAlloc(size);
|
||||
Size = size;
|
||||
}
|
||||
return (Buf != 0);
|
||||
return (Buf != NULL);
|
||||
}
|
||||
|
||||
HRESULT CByteOutBufWrap::Flush() throw()
|
||||
{
|
||||
if (Res == S_OK)
|
||||
{
|
||||
size_t size = (Cur - Buf);
|
||||
const size_t size = (size_t)(Cur - Buf);
|
||||
Res = WriteStream(Stream, Buf, size);
|
||||
if (Res == S_OK)
|
||||
Processed += size;
|
||||
Cur = Buf;
|
||||
// else throw 11;
|
||||
}
|
||||
Cur = Buf; // reset pointer for later Wrap_WriteByte()
|
||||
return Res;
|
||||
}
|
||||
|
||||
@@ -244,7 +291,57 @@ static void Wrap_WriteByte(const IByteOut *pp, Byte b) throw()
|
||||
p->Flush();
|
||||
}
|
||||
|
||||
CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0)
|
||||
CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(NULL), Size(0)
|
||||
{
|
||||
vt.Write = Wrap_WriteByte;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- CLookOutWrap ---------- */
|
||||
|
||||
/*
|
||||
void CLookOutWrap::Free() throw()
|
||||
{
|
||||
::MidFree(Buf);
|
||||
Buf = NULL;
|
||||
}
|
||||
|
||||
bool CLookOutWrap::Alloc(size_t size) throw()
|
||||
{
|
||||
if (!Buf || size != Size)
|
||||
{
|
||||
Free();
|
||||
Buf = (Byte *)::MidAlloc(size);
|
||||
Size = size;
|
||||
}
|
||||
return (Buf != NULL);
|
||||
}
|
||||
|
||||
static size_t LookOutWrap_GetOutBuf(const ILookOutStream *pp, void **buf) throw()
|
||||
{
|
||||
CLookOutWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt);
|
||||
*buf = p->Buf;
|
||||
return p->Size;
|
||||
}
|
||||
|
||||
static size_t LookOutWrap_Write(const ILookOutStream *pp, size_t size) throw()
|
||||
{
|
||||
CLookOutWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt);
|
||||
if (p->Res == S_OK && size != 0)
|
||||
{
|
||||
p->Res = WriteStream(p->Stream, p->Buf, size);
|
||||
if (p->Res == S_OK)
|
||||
{
|
||||
p->Processed += size;
|
||||
return size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CLookOutWrap::CLookOutWrap() throw(): Buf(NULL), Size(0)
|
||||
{
|
||||
vt.GetOutBuf = LookOutWrap_GetOutBuf;
|
||||
vt.Write = LookOutWrap_Write;
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -74,7 +74,7 @@ struct CByteInBufWrap
|
||||
Extra = false;
|
||||
Res = S_OK;
|
||||
}
|
||||
UInt64 GetProcessed() const { return Processed + (Cur - Buf); }
|
||||
UInt64 GetProcessed() const { return Processed + (size_t)(Cur - Buf); }
|
||||
Byte ReadByteFromNewBlock() throw();
|
||||
Byte ReadByte()
|
||||
{
|
||||
@@ -85,6 +85,45 @@ struct CByteInBufWrap
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
struct CLookToSequentialWrap
|
||||
{
|
||||
Byte *BufBase;
|
||||
UInt32 Size;
|
||||
ISequentialInStream *Stream;
|
||||
UInt64 Processed;
|
||||
bool Extra;
|
||||
HRESULT Res;
|
||||
|
||||
CLookToSequentialWrap(): BufBase(NULL) {}
|
||||
~CLookToSequentialWrap() { Free(); }
|
||||
void Free() throw();
|
||||
bool Alloc(UInt32 size) throw();
|
||||
void Init()
|
||||
{
|
||||
// Lim = Cur = Buf;
|
||||
Processed = 0;
|
||||
Extra = false;
|
||||
Res = S_OK;
|
||||
}
|
||||
// UInt64 GetProcessed() const { return Processed + (Cur - Buf); }
|
||||
|
||||
Byte ReadByteFromNewBlock() throw();
|
||||
Byte ReadByte()
|
||||
{
|
||||
if (Cur != Lim)
|
||||
return *Cur++;
|
||||
return ReadByteFromNewBlock();
|
||||
}
|
||||
};
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
// void CLookToSequentialWrap_Look(ILookInSeqStream *pp);
|
||||
EXTERN_C_END
|
||||
*/
|
||||
|
||||
|
||||
|
||||
struct CByteOutBufWrap
|
||||
{
|
||||
IByteOut vt;
|
||||
@@ -107,7 +146,7 @@ struct CByteOutBufWrap
|
||||
Processed = 0;
|
||||
Res = S_OK;
|
||||
}
|
||||
UInt64 GetProcessed() const { return Processed + (Cur - Buf); }
|
||||
UInt64 GetProcessed() const { return Processed + (size_t)(Cur - Buf); }
|
||||
HRESULT Flush() throw();
|
||||
void WriteByte(Byte b)
|
||||
{
|
||||
@@ -117,4 +156,27 @@ struct CByteOutBufWrap
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
struct CLookOutWrap
|
||||
{
|
||||
ILookOutStream vt;
|
||||
Byte *Buf;
|
||||
size_t Size;
|
||||
ISequentialOutStream *Stream;
|
||||
UInt64 Processed;
|
||||
HRESULT Res;
|
||||
|
||||
CLookOutWrap() throw();
|
||||
~CLookOutWrap() { Free(); }
|
||||
void Free() throw();
|
||||
bool Alloc(size_t size) throw();
|
||||
void Init()
|
||||
{
|
||||
Processed = 0;
|
||||
Res = S_OK;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,19 +11,23 @@
|
||||
#include "RegisterCodec.h"
|
||||
|
||||
static const unsigned kNumCodecsMax = 64;
|
||||
extern
|
||||
unsigned g_NumCodecs;
|
||||
unsigned g_NumCodecs = 0;
|
||||
extern
|
||||
const CCodecInfo *g_Codecs[];
|
||||
const CCodecInfo *g_Codecs[kNumCodecsMax];
|
||||
|
||||
// We use g_ExternalCodecs in other stages.
|
||||
/*
|
||||
#ifdef EXTERNAL_CODECS
|
||||
/*
|
||||
extern CExternalCodecs g_ExternalCodecs;
|
||||
#define CHECK_GLOBAL_CODECS \
|
||||
if (!__externalCodecs || !__externalCodecs->IsSet()) __externalCodecs = &g_ExternalCodecs;
|
||||
#endif
|
||||
*/
|
||||
|
||||
#define CHECK_GLOBAL_CODECS
|
||||
#endif
|
||||
|
||||
|
||||
void RegisterCodec(const CCodecInfo *codecInfo) throw()
|
||||
{
|
||||
@@ -32,7 +36,11 @@ void RegisterCodec(const CCodecInfo *codecInfo) throw()
|
||||
}
|
||||
|
||||
static const unsigned kNumHashersMax = 16;
|
||||
extern
|
||||
unsigned g_NumHashers;
|
||||
unsigned g_NumHashers = 0;
|
||||
extern
|
||||
const CHasherInfo *g_Hashers[];
|
||||
const CHasherInfo *g_Hashers[kNumHashersMax];
|
||||
|
||||
void RegisterHasher(const CHasherInfo *hashInfo) throw()
|
||||
@@ -164,7 +172,7 @@ int FindMethod_Index(
|
||||
{
|
||||
methodId = codec.Id;
|
||||
numStreams = codec.NumStreams;
|
||||
return i;
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +189,7 @@ int FindMethod_Index(
|
||||
{
|
||||
methodId = codec.Id;
|
||||
numStreams = codec.NumStreams;
|
||||
return g_NumCodecs + i;
|
||||
return (int)(g_NumCodecs + i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +208,7 @@ static int FindMethod_Index(
|
||||
{
|
||||
const CCodecInfo &codec = *g_Codecs[i];
|
||||
if (codec.Id == methodId && (encode ? codec.CreateEncoder : codec.CreateDecoder))
|
||||
return i;
|
||||
return (int)i;
|
||||
}
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
@@ -212,7 +220,7 @@ static int FindMethod_Index(
|
||||
{
|
||||
const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
|
||||
if (codec.Id == methodId && (encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned))
|
||||
return g_NumCodecs + i;
|
||||
return (int)(g_NumCodecs + i);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -441,7 +449,7 @@ HRESULT CreateCoder_Id(
|
||||
int index = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS methodId, encode);
|
||||
if (index < 0)
|
||||
return S_OK;
|
||||
return CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS index, encode, filter, cod);
|
||||
return CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS (unsigned)index, encode, filter, cod);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ bool AutoRenamePath(FString &path)
|
||||
FString extension;
|
||||
if (dotPos > slashPos + 1)
|
||||
{
|
||||
name.DeleteFrom(dotPos);
|
||||
extension = path.Ptr(dotPos);
|
||||
name.DeleteFrom((unsigned)dotPos);
|
||||
extension = path.Ptr((unsigned)dotPos);
|
||||
}
|
||||
name += '_';
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "../../Windows/FileFind.h"
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_DEVICE_FILE
|
||||
@@ -15,22 +16,26 @@
|
||||
|
||||
#include "FileStreams.h"
|
||||
|
||||
static inline HRESULT ConvertBoolToHRESULT(bool result)
|
||||
static inline HRESULT GetLastError_HRESULT()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (result)
|
||||
return S_OK;
|
||||
DWORD lastError = ::GetLastError();
|
||||
if (lastError == 0)
|
||||
return E_FAIL;
|
||||
return HRESULT_FROM_WIN32(lastError);
|
||||
#else
|
||||
return result ? S_OK: E_FAIL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline HRESULT ConvertBoolToHRESULT(bool result)
|
||||
{
|
||||
if (result)
|
||||
return S_OK;
|
||||
return GetLastError_HRESULT();
|
||||
}
|
||||
|
||||
|
||||
#ifdef SUPPORT_DEVICE_FILE
|
||||
static const UInt32 kClusterSize = 1 << 18;
|
||||
#endif
|
||||
|
||||
CInFileStream::CInFileStream():
|
||||
#ifdef SUPPORT_DEVICE_FILE
|
||||
VirtPos(0),
|
||||
@@ -111,7 +116,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
if (alignedPos != PhyPos)
|
||||
{
|
||||
UInt64 realNewPosition;
|
||||
bool result = File.Seek(alignedPos, FILE_BEGIN, realNewPosition);
|
||||
bool result = File.Seek((Int64)alignedPos, FILE_BEGIN, realNewPosition);
|
||||
if (!result)
|
||||
return ConvertBoolToHRESULT(result);
|
||||
PhyPos = realNewPosition;
|
||||
@@ -140,7 +145,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
if (VirtPos != PhyPos)
|
||||
{
|
||||
UInt64 realNewPosition;
|
||||
bool result = File.Seek(VirtPos, FILE_BEGIN, realNewPosition);
|
||||
bool result = File.Seek((Int64)VirtPos, FILE_BEGIN, realNewPosition);
|
||||
if (!result)
|
||||
return ConvertBoolToHRESULT(result);
|
||||
PhyPos = VirtPos = realNewPosition;
|
||||
@@ -149,7 +154,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
#endif
|
||||
|
||||
UInt32 realProcessedSize;
|
||||
bool result = File.ReadPart(data, size, realProcessedSize);
|
||||
const bool result = File.ReadPart(data, size, realProcessedSize);
|
||||
if (processedSize)
|
||||
*processedSize = realProcessedSize;
|
||||
|
||||
@@ -161,33 +166,27 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
if (result)
|
||||
return S_OK;
|
||||
|
||||
#else // USE_WIN_FILE
|
||||
|
||||
if (processedSize)
|
||||
*processedSize = 0;
|
||||
const ssize_t res = File.read_part(data, (size_t)size);
|
||||
if (res != -1)
|
||||
{
|
||||
DWORD error = ::GetLastError();
|
||||
if (processedSize)
|
||||
*processedSize = (UInt32)res;
|
||||
return S_OK;
|
||||
}
|
||||
#endif // USE_WIN_FILE
|
||||
|
||||
{
|
||||
const DWORD error = ::GetLastError();
|
||||
if (Callback)
|
||||
return Callback->InFileStream_On_Error(CallbackRef, error);
|
||||
if (error == 0)
|
||||
return E_FAIL;
|
||||
|
||||
return HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (processedSize)
|
||||
*processedSize = 0;
|
||||
ssize_t res = File.Read(data, (size_t)size);
|
||||
if (res == -1)
|
||||
{
|
||||
if (Callback)
|
||||
return Callback->InFileStream_On_Error(CallbackRef, E_FAIL);
|
||||
return E_FAIL;
|
||||
}
|
||||
if (processedSize)
|
||||
*processedSize = (UInt32)res;
|
||||
return S_OK;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef UNDER_CE
|
||||
@@ -228,7 +227,7 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi
|
||||
}
|
||||
while (res < 0 && (errno == EINTR));
|
||||
if (res == -1)
|
||||
return E_FAIL;
|
||||
return GetLastError_HRESULT();
|
||||
if (processedSize)
|
||||
*processedSize = (UInt32)res;
|
||||
return S_OK;
|
||||
@@ -257,9 +256,9 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos
|
||||
}
|
||||
if (offset < 0)
|
||||
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
|
||||
VirtPos = offset;
|
||||
VirtPos = (UInt64)offset;
|
||||
if (newPosition)
|
||||
*newPosition = offset;
|
||||
*newPosition = (UInt64)offset;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
@@ -277,9 +276,9 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos
|
||||
|
||||
#else
|
||||
|
||||
off_t res = File.Seek((off_t)offset, seekOrigin);
|
||||
off_t res = File.seek((off_t)offset, (int)seekOrigin);
|
||||
if (res == -1)
|
||||
return E_FAIL;
|
||||
return GetLastError_HRESULT();
|
||||
if (newPosition)
|
||||
*newPosition = (UInt64)res;
|
||||
return S_OK;
|
||||
@@ -306,7 +305,7 @@ STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aT
|
||||
if (attrib) *attrib = info.dwFileAttributes;
|
||||
return S_OK;
|
||||
}
|
||||
return GetLastError();
|
||||
return GetLastError_HRESULT();
|
||||
}
|
||||
|
||||
STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props)
|
||||
@@ -325,7 +324,71 @@ STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props)
|
||||
props->MTime = info.ftLastWriteTime;
|
||||
return S_OK;
|
||||
}
|
||||
return GetLastError();
|
||||
return GetLastError_HRESULT();
|
||||
}
|
||||
|
||||
#elif !defined(_WIN32)
|
||||
|
||||
STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)
|
||||
{
|
||||
struct stat st;
|
||||
if (File.my_fstat(&st) != 0)
|
||||
return GetLastError_HRESULT();
|
||||
|
||||
if (size) *size = (UInt64)st.st_size;
|
||||
#ifdef __APPLE__
|
||||
if (cTime) NWindows::NFile::NFind::timespec_To_FILETIME(st.st_ctimespec, *cTime);
|
||||
if (aTime) NWindows::NFile::NFind::timespec_To_FILETIME(st.st_atimespec, *aTime);
|
||||
if (mTime) NWindows::NFile::NFind::timespec_To_FILETIME(st.st_mtimespec, *mTime);
|
||||
#else
|
||||
if (cTime) NWindows::NFile::NFind::timespec_To_FILETIME(st.st_ctim, *cTime);
|
||||
if (aTime) NWindows::NFile::NFind::timespec_To_FILETIME(st.st_atim, *aTime);
|
||||
if (mTime) NWindows::NFile::NFind::timespec_To_FILETIME(st.st_mtim, *mTime);
|
||||
#endif
|
||||
if (attrib) *attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// #include <stdio.h>
|
||||
|
||||
STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props)
|
||||
{
|
||||
struct stat st;
|
||||
if (File.my_fstat(&st) != 0)
|
||||
return GetLastError_HRESULT();
|
||||
|
||||
props->Size = (UInt64)st.st_size;
|
||||
/*
|
||||
dev_t stat::st_dev:
|
||||
GCC:Linux long unsigned int : __dev_t
|
||||
Mac: int
|
||||
*/
|
||||
props->VolID = (UInt64)(Int64)st.st_dev;
|
||||
props->FileID_Low = st.st_ino;
|
||||
props->FileID_High = 0;
|
||||
props->NumLinks = (UInt32)st.st_nlink; // we reduce to UInt32 from (nlink_t) that is (unsigned long)
|
||||
props->Attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode);
|
||||
|
||||
#ifdef __APPLE__
|
||||
NWindows::NFile::NFind::timespec_To_FILETIME(st.st_ctimespec, props->CTime);
|
||||
NWindows::NFile::NFind::timespec_To_FILETIME(st.st_atimespec, props->ATime);
|
||||
NWindows::NFile::NFind::timespec_To_FILETIME(st.st_mtimespec, props->MTime);
|
||||
#else
|
||||
NWindows::NFile::NFind::timespec_To_FILETIME(st.st_ctim, props->CTime);
|
||||
NWindows::NFile::NFind::timespec_To_FILETIME(st.st_atim, props->ATime);
|
||||
NWindows::NFile::NFind::timespec_To_FILETIME(st.st_mtim, props->MTime);
|
||||
#endif
|
||||
|
||||
/*
|
||||
printf("\nGetProps2() NumLinks=%d = st_dev=%d st_ino = %d\n"
|
||||
, (unsigned)(props->NumLinks)
|
||||
, (unsigned)(st.st_dev)
|
||||
, (unsigned)(st.st_ino)
|
||||
);
|
||||
*/
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -343,7 +406,7 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces
|
||||
#ifdef USE_WIN_FILE
|
||||
|
||||
UInt32 realProcessedSize;
|
||||
bool result = File.Write(data, size, realProcessedSize);
|
||||
const bool result = File.Write(data, size, realProcessedSize);
|
||||
ProcessedSize += realProcessedSize;
|
||||
if (processedSize)
|
||||
*processedSize = realProcessedSize;
|
||||
@@ -353,12 +416,13 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces
|
||||
|
||||
if (processedSize)
|
||||
*processedSize = 0;
|
||||
ssize_t res = File.Write(data, (size_t)size);
|
||||
if (res == -1)
|
||||
return E_FAIL;
|
||||
size_t realProcessedSize;
|
||||
const ssize_t res = File.write_full(data, (size_t)size, realProcessedSize);
|
||||
ProcessedSize += realProcessedSize;
|
||||
if (processedSize)
|
||||
*processedSize = (UInt32)res;
|
||||
ProcessedSize += res;
|
||||
*processedSize = (UInt32)realProcessedSize;
|
||||
if (res == -1)
|
||||
return GetLastError_HRESULT();
|
||||
return S_OK;
|
||||
|
||||
#endif
|
||||
@@ -379,9 +443,9 @@ STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo
|
||||
|
||||
#else
|
||||
|
||||
off_t res = File.Seek((off_t)offset, seekOrigin);
|
||||
off_t res = File.seek((off_t)offset, (int)seekOrigin);
|
||||
if (res == -1)
|
||||
return E_FAIL;
|
||||
return GetLastError_HRESULT();
|
||||
if (newPosition)
|
||||
*newPosition = (UInt64)res;
|
||||
return S_OK;
|
||||
@@ -403,8 +467,11 @@ STDMETHODIMP COutFileStream::SetSize(UInt64 newSize)
|
||||
|
||||
#else
|
||||
|
||||
return E_FAIL;
|
||||
|
||||
// SetLength() uses ftruncate() that doesn't change file offset
|
||||
if (!File.SetLength(newSize))
|
||||
return GetLastError_HRESULT();
|
||||
return S_OK;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -462,7 +529,7 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
|
||||
while (res < 0 && (errno == EINTR));
|
||||
|
||||
if (res == -1)
|
||||
return E_FAIL;
|
||||
return GetLastError_HRESULT();
|
||||
|
||||
_size += (size_t)res;
|
||||
if (processedSize)
|
||||
|
||||
@@ -7,42 +7,30 @@
|
||||
#define USE_WIN_FILE
|
||||
#endif
|
||||
|
||||
#include "../../Common/MyCom.h"
|
||||
#include "../../Common/MyString.h"
|
||||
|
||||
#ifdef USE_WIN_FILE
|
||||
#include "../../Windows/FileIO.h"
|
||||
#else
|
||||
#include "../../Common/C_FileIO.h"
|
||||
#endif
|
||||
|
||||
#include "../../Common/MyCom.h"
|
||||
|
||||
#include "../IStream.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef UINT_PTR My_UINT_PTR;
|
||||
#else
|
||||
typedef UINT My_UINT_PTR;
|
||||
#endif
|
||||
|
||||
struct IInFileStream_Callback
|
||||
{
|
||||
virtual HRESULT InFileStream_On_Error(My_UINT_PTR val, DWORD error) = 0;
|
||||
virtual void InFileStream_On_Destroy(My_UINT_PTR val) = 0;
|
||||
virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error) = 0;
|
||||
virtual void InFileStream_On_Destroy(UINT_PTR val) = 0;
|
||||
};
|
||||
|
||||
class CInFileStream:
|
||||
public IInStream,
|
||||
public IStreamGetSize,
|
||||
#ifdef USE_WIN_FILE
|
||||
public IStreamGetProps,
|
||||
public IStreamGetProps2,
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
#ifdef USE_WIN_FILE
|
||||
NWindows::NFile::NIO::CInFile File;
|
||||
|
||||
#ifdef USE_WIN_FILE
|
||||
|
||||
#ifdef SUPPORT_DEVICE_FILE
|
||||
UInt64 VirtPos;
|
||||
@@ -52,14 +40,12 @@ public:
|
||||
UInt32 BufSize;
|
||||
#endif
|
||||
|
||||
#else
|
||||
NC::NFile::NIO::CInFile File;
|
||||
#endif
|
||||
|
||||
bool SupportHardLinks;
|
||||
|
||||
IInFileStream_Callback *Callback;
|
||||
My_UINT_PTR CallbackRef;
|
||||
UINT_PTR CallbackRef;
|
||||
|
||||
virtual ~CInFileStream();
|
||||
|
||||
@@ -77,10 +63,8 @@ public:
|
||||
|
||||
MY_QUERYINTERFACE_BEGIN2(IInStream)
|
||||
MY_QUERYINTERFACE_ENTRY(IStreamGetSize)
|
||||
#ifdef USE_WIN_FILE
|
||||
MY_QUERYINTERFACE_ENTRY(IStreamGetProps)
|
||||
MY_QUERYINTERFACE_ENTRY(IStreamGetProps2)
|
||||
#endif
|
||||
MY_QUERYINTERFACE_END
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
@@ -88,10 +72,8 @@ public:
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
||||
|
||||
STDMETHOD(GetSize)(UInt64 *size);
|
||||
#ifdef USE_WIN_FILE
|
||||
STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib);
|
||||
STDMETHOD(GetProps2)(CStreamFileProps *props);
|
||||
#endif
|
||||
};
|
||||
|
||||
class CStdInFileStream:
|
||||
@@ -110,11 +92,8 @@ class COutFileStream:
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
#ifdef USE_WIN_FILE
|
||||
NWindows::NFile::NIO::COutFile File;
|
||||
#else
|
||||
NC::NFile::NIO::COutFile File;
|
||||
#endif
|
||||
|
||||
virtual ~COutFileStream() {}
|
||||
bool Create(CFSTR fileName, bool createAlways)
|
||||
{
|
||||
@@ -131,14 +110,11 @@ public:
|
||||
|
||||
UInt64 ProcessedSize;
|
||||
|
||||
#ifdef USE_WIN_FILE
|
||||
bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
|
||||
{
|
||||
return File.SetTime(cTime, aTime, mTime);
|
||||
}
|
||||
bool SetMTime(const FILETIME *mTime) { return File.SetMTime(mTime); }
|
||||
#endif
|
||||
|
||||
|
||||
MY_UNKNOWN_IMP1(IOutStream)
|
||||
|
||||
@@ -146,6 +122,15 @@ public:
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
||||
STDMETHOD(SetSize)(UInt64 newSize);
|
||||
|
||||
bool SeekToBegin_bool()
|
||||
{
|
||||
#ifdef USE_WIN_FILE
|
||||
return File.SeekToBegin();
|
||||
#else
|
||||
return File.seekToBegin() == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT GetSize(UInt64 *size);
|
||||
};
|
||||
|
||||
|
||||
@@ -86,47 +86,47 @@ STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStr
|
||||
{
|
||||
RINOK(Init_and_Alloc());
|
||||
|
||||
UInt64 prev = 0;
|
||||
UInt64 nowPos64 = 0;
|
||||
bool inputFinished = false;
|
||||
UInt32 pos = 0;
|
||||
|
||||
while (!outSize || nowPos64 < *outSize)
|
||||
{
|
||||
UInt32 endPos = pos;
|
||||
|
||||
if (!inputFinished)
|
||||
{
|
||||
size_t processedSize = _bufSize - pos;
|
||||
RINOK(ReadStream(inStream, _buf + pos, &processedSize));
|
||||
endPos = pos + (UInt32)processedSize;
|
||||
inputFinished = (endPos != _bufSize);
|
||||
pos += (UInt32)processedSize;
|
||||
inputFinished = (pos != _bufSize);
|
||||
}
|
||||
|
||||
pos = Filter->Filter(_buf, endPos);
|
||||
if (pos == 0)
|
||||
return S_OK;
|
||||
|
||||
UInt32 filtered = Filter->Filter(_buf, pos);
|
||||
|
||||
if (pos > endPos)
|
||||
if (filtered > pos)
|
||||
{
|
||||
// AES
|
||||
if (!inputFinished || pos > _bufSize)
|
||||
if (!inputFinished || filtered > _bufSize)
|
||||
return E_FAIL;
|
||||
if (!_encodeMode)
|
||||
return S_FALSE;
|
||||
|
||||
Byte *buf = _buf;
|
||||
do
|
||||
_buf[endPos] = 0;
|
||||
while (++endPos != pos);
|
||||
buf[pos] = 0;
|
||||
while (++pos != filtered);
|
||||
|
||||
if (pos != Filter->Filter(_buf, pos))
|
||||
if (filtered != Filter->Filter(buf, filtered))
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (endPos == 0)
|
||||
return S_OK;
|
||||
|
||||
UInt32 size = (pos != 0 ? pos : endPos);
|
||||
UInt32 size = (filtered != 0 ? filtered : pos);
|
||||
if (outSize)
|
||||
{
|
||||
UInt64 remSize = *outSize - nowPos64;
|
||||
const UInt64 remSize = *outSize - nowPos64;
|
||||
if (size > remSize)
|
||||
size = (UInt32)remSize;
|
||||
}
|
||||
@@ -134,16 +134,17 @@ STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStr
|
||||
RINOK(WriteStream(outStream, _buf, size));
|
||||
nowPos64 += size;
|
||||
|
||||
if (pos == 0)
|
||||
if (filtered == 0)
|
||||
return S_OK;
|
||||
pos -= filtered;
|
||||
for (UInt32 i = 0; i < pos; i++)
|
||||
_buf[i] = _buf[filtered++];
|
||||
|
||||
if (progress)
|
||||
if (progress && (nowPos64 - prev) >= (1 << 22))
|
||||
{
|
||||
prev = nowPos64;
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
|
||||
|
||||
UInt32 i = 0;
|
||||
while (pos < endPos)
|
||||
_buf[i++] = _buf[pos++];
|
||||
pos = i;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
||||
@@ -56,7 +56,7 @@ bool CInBufferBase::ReadBlock()
|
||||
#endif
|
||||
if (_wasFinished)
|
||||
return false;
|
||||
_processedSize += (_buf - _bufBase);
|
||||
_processedSize += (size_t)(_buf - _bufBase);
|
||||
_buf = _bufBase;
|
||||
_bufLim = _bufBase;
|
||||
UInt32 processed;
|
||||
@@ -100,7 +100,7 @@ size_t CInBufferBase::ReadBytes(Byte *buf, size_t size)
|
||||
size_t num = 0;
|
||||
for (;;)
|
||||
{
|
||||
const size_t rem = _bufLim - _buf;
|
||||
const size_t rem = (size_t)(_bufLim - _buf);
|
||||
if (size <= rem)
|
||||
{
|
||||
if (size != 0)
|
||||
@@ -148,7 +148,7 @@ size_t CInBufferBase::Skip(size_t size)
|
||||
size_t processed = 0;
|
||||
for (;;)
|
||||
{
|
||||
size_t rem = (_bufLim - _buf);
|
||||
const size_t rem = (size_t)(_bufLim - _buf);
|
||||
if (rem >= size)
|
||||
{
|
||||
_buf += size;
|
||||
|
||||
@@ -38,8 +38,16 @@ public:
|
||||
|
||||
CInBufferBase() throw();
|
||||
|
||||
UInt64 GetStreamSize() const { return _processedSize + (_buf - _bufBase); }
|
||||
UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (_buf - _bufBase); }
|
||||
// the size of portion of data in real stream that was already read from this object
|
||||
// it doesn't include unused data in buffer
|
||||
// it doesn't include virtual Extra bytes after the end of real stream data
|
||||
UInt64 GetStreamSize() const { return _processedSize + (size_t)(_buf - _bufBase); }
|
||||
|
||||
// the size of virtual data that was read from this object
|
||||
// it doesn't include unused data in buffers
|
||||
// it includes any virtual Extra bytes after the end of real data
|
||||
UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (size_t)(_buf - _bufBase); }
|
||||
|
||||
bool WasFinished() const { return _wasFinished; }
|
||||
|
||||
void SetStream(ISequentialInStream *stream) { _stream = stream; }
|
||||
@@ -68,6 +76,15 @@ public:
|
||||
b = *_buf++;
|
||||
return true;
|
||||
}
|
||||
|
||||
MY_FORCE_INLINE
|
||||
bool ReadByte_FromBuf(Byte &b)
|
||||
{
|
||||
if (_buf >= _bufLim)
|
||||
return false;
|
||||
b = *_buf++;
|
||||
return true;
|
||||
}
|
||||
|
||||
MY_FORCE_INLINE
|
||||
Byte ReadByte()
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../C/7zCrc.h"
|
||||
|
||||
#include "../../Common/Defs.h"
|
||||
|
||||
#include "InOutTempBuffer.h"
|
||||
#include "StreamUtils.h"
|
||||
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
|
||||
#include "../../../C/7zCrc.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDir;
|
||||
@@ -16,50 +16,58 @@ using namespace NDir;
|
||||
static const size_t kTempBufSize = (1 << 20);
|
||||
|
||||
#define kTempFilePrefixString FTEXT("7zt")
|
||||
|
||||
CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { }
|
||||
|
||||
void CInOutTempBuffer::Create()
|
||||
{
|
||||
if (!_buf)
|
||||
_buf = new Byte[kTempBufSize];
|
||||
}
|
||||
|
||||
CInOutTempBuffer::~CInOutTempBuffer()
|
||||
{
|
||||
delete []_buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
CInOutTempBuffer::CInOutTempBuffer()
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
: _buf(NULL)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
void CInOutTempBuffer::Create()
|
||||
{
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
if (!_buf)
|
||||
_buf = new Byte[kTempBufSize];
|
||||
#endif
|
||||
}
|
||||
|
||||
void CInOutTempBuffer::InitWriting()
|
||||
{
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
_bufPos = 0;
|
||||
_tempFileCreated = false;
|
||||
_size = 0;
|
||||
_crc = CRC_INIT_VAL;
|
||||
_tempFileCreated = false;
|
||||
#endif
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
|
||||
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
|
||||
static inline HRESULT Get_HRESULT_LastError()
|
||||
{
|
||||
if (size == 0)
|
||||
return true;
|
||||
if (!_tempFileCreated)
|
||||
{
|
||||
if (!_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile))
|
||||
return false;
|
||||
_tempFileCreated = true;
|
||||
}
|
||||
UInt32 processed;
|
||||
if (!_outFile.Write(data, size, processed))
|
||||
return false;
|
||||
_crc = CrcUpdate(_crc, data, processed);
|
||||
_size += processed;
|
||||
return (processed == size);
|
||||
#ifdef _WIN32
|
||||
DWORD lastError = ::GetLastError();
|
||||
if (lastError != 0)
|
||||
return HRESULT_FROM_WIN32(lastError);
|
||||
#endif
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
bool CInOutTempBuffer::Write(const void *data, UInt32 size)
|
||||
#endif
|
||||
|
||||
|
||||
HRESULT CInOutTempBuffer::Write_HRESULT(const void *data, UInt32 size)
|
||||
{
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
|
||||
if (size == 0)
|
||||
return true;
|
||||
return S_OK;
|
||||
size_t cur = kTempBufSize - _bufPos;
|
||||
if (cur != 0)
|
||||
{
|
||||
@@ -72,11 +80,42 @@ bool CInOutTempBuffer::Write(const void *data, UInt32 size)
|
||||
size -= (UInt32)cur;
|
||||
data = ((const Byte *)data) + cur;
|
||||
}
|
||||
return WriteToFile(data, size);
|
||||
|
||||
if (size == 0)
|
||||
return S_OK;
|
||||
|
||||
if (!_tempFileCreated)
|
||||
{
|
||||
if (!_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile))
|
||||
return Get_HRESULT_LastError();
|
||||
_tempFileCreated = true;
|
||||
}
|
||||
UInt32 processed;
|
||||
if (!_outFile.Write(data, size, processed))
|
||||
return Get_HRESULT_LastError();
|
||||
_crc = CrcUpdate(_crc, data, processed);
|
||||
_size += processed;
|
||||
return (processed == size) ? S_OK : E_FAIL;
|
||||
|
||||
#else
|
||||
|
||||
const size_t newSize = _size + size;
|
||||
if (newSize < _size)
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_dynBuffer.EnsureCapacity(newSize))
|
||||
return E_OUTOFMEMORY;
|
||||
memcpy(((Byte *)_dynBuffer) + _size, data, size);
|
||||
_size = newSize;
|
||||
return S_OK;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
|
||||
{
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
|
||||
if (!_outFile.Close())
|
||||
return E_FAIL;
|
||||
|
||||
@@ -107,8 +146,13 @@ HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
|
||||
size += processed;
|
||||
}
|
||||
}
|
||||
|
||||
return (_crc == crc && size == _size) ? S_OK : E_FAIL;
|
||||
|
||||
#else
|
||||
|
||||
return WriteStream(stream, (const Byte *)_dynBuffer, _size);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -3,30 +3,48 @@
|
||||
#ifndef __IN_OUT_TEMP_BUFFER_H
|
||||
#define __IN_OUT_TEMP_BUFFER_H
|
||||
|
||||
#include "../../Common/MyCom.h"
|
||||
#ifdef _WIN32
|
||||
// #define USE_InOutTempBuffer_FILE
|
||||
#endif
|
||||
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
#include "../../Windows/FileDir.h"
|
||||
#else
|
||||
#include "StreamObjects.h"
|
||||
#endif
|
||||
|
||||
#include "../IStream.h"
|
||||
|
||||
class CInOutTempBuffer
|
||||
{
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
|
||||
NWindows::NFile::NDir::CTempFile _tempFile;
|
||||
NWindows::NFile::NIO::COutFile _outFile;
|
||||
bool _tempFileCreated;
|
||||
Byte *_buf;
|
||||
size_t _bufPos;
|
||||
UInt64 _size;
|
||||
UInt32 _crc;
|
||||
bool _tempFileCreated;
|
||||
|
||||
bool WriteToFile(const void *data, UInt32 size);
|
||||
#else
|
||||
|
||||
CByteDynBuffer _dynBuffer;
|
||||
size_t _size;
|
||||
|
||||
#endif
|
||||
|
||||
CLASS_NO_COPY(CInOutTempBuffer);
|
||||
public:
|
||||
CInOutTempBuffer();
|
||||
~CInOutTempBuffer();
|
||||
void Create();
|
||||
|
||||
void InitWriting();
|
||||
bool Write(const void *data, UInt32 size);
|
||||
#ifdef USE_InOutTempBuffer_FILE
|
||||
~CInOutTempBuffer();
|
||||
#endif
|
||||
|
||||
void InitWriting();
|
||||
HRESULT Write_HRESULT(const void *data, UInt32 size);
|
||||
HRESULT WriteToStream(ISequentialOutStream *stream);
|
||||
UInt64 GetDataSize() const { return _size; }
|
||||
};
|
||||
|
||||
@@ -67,7 +67,7 @@ STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *new
|
||||
}
|
||||
if (offset < 0)
|
||||
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
|
||||
_virtPos = offset;
|
||||
_virtPos = (UInt64)offset;
|
||||
if (newPosition)
|
||||
*newPosition = _virtPos;
|
||||
return S_OK;
|
||||
@@ -115,7 +115,7 @@ STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSi
|
||||
|
||||
_curRem = blockSize - offsetInBlock;
|
||||
|
||||
for (int i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++)
|
||||
for (unsigned i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++)
|
||||
_curRem += (UInt32)1 << BlockSizeLog;
|
||||
}
|
||||
|
||||
@@ -143,9 +143,9 @@ STDMETHODIMP CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *new
|
||||
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
|
||||
if (_virtPos != (UInt64)offset)
|
||||
_curRem = 0;
|
||||
_virtPos = offset;
|
||||
_virtPos = (UInt64)offset;
|
||||
if (newPosition)
|
||||
*newPosition = offset;
|
||||
*newPosition = (UInt64)offset;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ STDMETHODIMP CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo
|
||||
}
|
||||
if (offset < 0)
|
||||
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
|
||||
_virtPos = offset;
|
||||
_virtPos = (UInt64)offset;
|
||||
if (newPosition)
|
||||
*newPosition = _virtPos;
|
||||
return S_OK;
|
||||
@@ -268,10 +268,10 @@ STDMETHODIMP CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos
|
||||
}
|
||||
if (offset < 0)
|
||||
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
|
||||
_virtPos = offset;
|
||||
_virtPos = (UInt64)offset;
|
||||
if (newPosition)
|
||||
*newPosition = _virtPos;
|
||||
return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL);
|
||||
return Stream->Seek((Int64)(Offset + _virtPos), STREAM_SEEK_SET, NULL);
|
||||
}
|
||||
|
||||
STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
@@ -325,7 +325,7 @@ STDMETHODIMP CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt6
|
||||
}
|
||||
if (offset < 0)
|
||||
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
|
||||
_virtPos = offset;
|
||||
_virtPos = (UInt64)offset;
|
||||
if (newPosition)
|
||||
*newPosition = _virtPos;
|
||||
return S_OK;
|
||||
@@ -354,10 +354,10 @@ STDMETHODIMP CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo
|
||||
}
|
||||
if (offset < 0)
|
||||
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
|
||||
_virtPos = offset;
|
||||
_virtPos = (UInt64)offset;
|
||||
if (newPosition)
|
||||
*newPosition = _virtPos;
|
||||
return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL);
|
||||
return Stream->Seek((Int64)(Offset + _virtPos), STREAM_SEEK_SET, NULL);
|
||||
}
|
||||
|
||||
STDMETHODIMP CTailOutStream::SetSize(UInt64 newSize)
|
||||
|
||||
@@ -44,7 +44,7 @@ class CLimitedInStream:
|
||||
UInt64 _size;
|
||||
UInt64 _startOffset;
|
||||
|
||||
HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
|
||||
HRESULT SeekToPhys() { return _stream->Seek((Int64)_physPos, STREAM_SEEK_SET, NULL); }
|
||||
public:
|
||||
void SetStream(IInStream *stream) { _stream = stream; }
|
||||
HRESULT InitAndSeek(UInt64 startOffset, UInt64 size)
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
CRecordVector<UInt32> Vector;
|
||||
UInt64 StartOffset;
|
||||
|
||||
HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
|
||||
HRESULT SeekToPhys() { return Stream->Seek((Int64)_physPos, STREAM_SEEK_SET, NULL); }
|
||||
|
||||
HRESULT InitAndSeek()
|
||||
{
|
||||
@@ -115,7 +115,7 @@ class CExtentsStream:
|
||||
UInt64 _virtPos;
|
||||
bool _needStartSeek;
|
||||
|
||||
HRESULT SeekToPhys() { return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); }
|
||||
HRESULT SeekToPhys() { return Stream->Seek((Int64)_phyPos, STREAM_SEEK_SET, NULL); }
|
||||
|
||||
public:
|
||||
CMyComPtr<IInStream> Stream;
|
||||
@@ -177,7 +177,7 @@ public:
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
||||
|
||||
HRESULT SeekToStart() { return Stream->Seek(Offset, STREAM_SEEK_SET, NULL); }
|
||||
HRESULT SeekToStart() { return Stream->Seek((Int64)Offset, STREAM_SEEK_SET, NULL); }
|
||||
};
|
||||
|
||||
class CLimitedCachedInStream:
|
||||
@@ -195,7 +195,7 @@ class CLimitedCachedInStream:
|
||||
size_t _cachePhyPos;
|
||||
|
||||
|
||||
HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
|
||||
HRESULT SeekToPhys() { return _stream->Seek((Int64)_physPos, STREAM_SEEK_SET, NULL); }
|
||||
public:
|
||||
CByteBuffer Buffer;
|
||||
|
||||
|
||||
@@ -7,21 +7,26 @@
|
||||
#include "MemBlocks.h"
|
||||
#include "StreamUtils.h"
|
||||
|
||||
bool CMemBlockManager::AllocateSpace(size_t numBlocks)
|
||||
bool CMemBlockManager::AllocateSpace_bool(size_t numBlocks)
|
||||
{
|
||||
FreeSpace();
|
||||
if (_blockSize < sizeof(void *) || numBlocks < 1)
|
||||
if (numBlocks == 0)
|
||||
{
|
||||
return true;
|
||||
// return false;
|
||||
}
|
||||
if (_blockSize < sizeof(void *))
|
||||
return false;
|
||||
size_t totalSize = numBlocks * _blockSize;
|
||||
const size_t totalSize = numBlocks * _blockSize;
|
||||
if (totalSize / _blockSize != numBlocks)
|
||||
return false;
|
||||
_data = ::MidAlloc(totalSize);
|
||||
if (_data == 0)
|
||||
if (!_data)
|
||||
return false;
|
||||
Byte *p = (Byte *)_data;
|
||||
for (size_t i = 0; i + 1 < numBlocks; i++, p += _blockSize)
|
||||
*(Byte **)p = (p + _blockSize);
|
||||
*(Byte **)p = 0;
|
||||
*(Byte **)(void *)p = (p + _blockSize);
|
||||
*(Byte **)(void *)p = NULL;
|
||||
_headFree = _data;
|
||||
return true;
|
||||
}
|
||||
@@ -35,41 +40,64 @@ void CMemBlockManager::FreeSpace()
|
||||
|
||||
void *CMemBlockManager::AllocateBlock()
|
||||
{
|
||||
if (_headFree == 0)
|
||||
return 0;
|
||||
void *p = _headFree;
|
||||
_headFree = *(void **)_headFree;
|
||||
if (p)
|
||||
_headFree = *(void **)p;
|
||||
return p;
|
||||
}
|
||||
|
||||
void CMemBlockManager::FreeBlock(void *p)
|
||||
{
|
||||
if (p == 0)
|
||||
if (!p)
|
||||
return;
|
||||
*(void **)p = _headFree;
|
||||
_headFree = p;
|
||||
}
|
||||
|
||||
|
||||
// #include <stdio.h>
|
||||
|
||||
HRes CMemBlockManagerMt::AllocateSpace(size_t numBlocks, size_t numNoLockBlocks)
|
||||
{
|
||||
if (numNoLockBlocks > numBlocks)
|
||||
return E_INVALIDARG;
|
||||
if (!CMemBlockManager::AllocateSpace(numBlocks))
|
||||
const size_t numLockBlocks = numBlocks - numNoLockBlocks;
|
||||
UInt32 maxCount = (UInt32)numLockBlocks;
|
||||
if (maxCount != numLockBlocks)
|
||||
return E_OUTOFMEMORY;
|
||||
if (!CMemBlockManager::AllocateSpace_bool(numBlocks))
|
||||
return E_OUTOFMEMORY;
|
||||
size_t numLockBlocks = numBlocks - numNoLockBlocks;
|
||||
Semaphore.Close();
|
||||
return Semaphore.Create((LONG)numLockBlocks, (LONG)numLockBlocks);
|
||||
// we need (maxCount = 1), if we want to create non-use empty Semaphore
|
||||
if (maxCount == 0)
|
||||
maxCount = 1;
|
||||
|
||||
// printf("\n Synchro.Create() \n");
|
||||
WRes wres;
|
||||
#ifndef _WIN32
|
||||
wres = Synchro.Create();
|
||||
if (wres != 0)
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
wres = Semaphore.Create(&Synchro, (UInt32)numLockBlocks, maxCount);
|
||||
#else
|
||||
wres = Semaphore.Create((UInt32)numLockBlocks, maxCount);
|
||||
#endif
|
||||
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
}
|
||||
|
||||
|
||||
HRes CMemBlockManagerMt::AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks)
|
||||
{
|
||||
// desiredNumberOfBlocks = 0; // for debug
|
||||
if (numNoLockBlocks > desiredNumberOfBlocks)
|
||||
return E_INVALIDARG;
|
||||
for (;;)
|
||||
{
|
||||
if (AllocateSpace(desiredNumberOfBlocks, numNoLockBlocks) == 0)
|
||||
return 0;
|
||||
// if (desiredNumberOfBlocks == 0) return E_OUTOFMEMORY;
|
||||
HRes hres = AllocateSpace(desiredNumberOfBlocks, numNoLockBlocks);
|
||||
if (hres != E_OUTOFMEMORY)
|
||||
return hres;
|
||||
if (desiredNumberOfBlocks == numNoLockBlocks)
|
||||
return E_OUTOFMEMORY;
|
||||
desiredNumberOfBlocks = numNoLockBlocks + ((desiredNumberOfBlocks - numNoLockBlocks) >> 1);
|
||||
@@ -91,7 +119,7 @@ void *CMemBlockManagerMt::AllocateBlock()
|
||||
|
||||
void CMemBlockManagerMt::FreeBlock(void *p, bool lockMode)
|
||||
{
|
||||
if (p == 0)
|
||||
if (!p)
|
||||
return;
|
||||
{
|
||||
NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
|
||||
@@ -101,6 +129,8 @@ void CMemBlockManagerMt::FreeBlock(void *p, bool lockMode)
|
||||
Semaphore.Release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CMemBlocks::Free(CMemBlockManagerMt *manager)
|
||||
{
|
||||
while (Blocks.Size() > 0)
|
||||
@@ -122,9 +152,9 @@ HRESULT CMemBlocks::WriteToStream(size_t blockSize, ISequentialOutStream *outStr
|
||||
UInt64 totalSize = TotalSize;
|
||||
for (unsigned blockIndex = 0; totalSize > 0; blockIndex++)
|
||||
{
|
||||
UInt32 curSize = (UInt32)blockSize;
|
||||
if (totalSize < curSize)
|
||||
curSize = (UInt32)totalSize;
|
||||
size_t curSize = blockSize;
|
||||
if (curSize > totalSize)
|
||||
curSize = (size_t)totalSize;
|
||||
if (blockIndex >= Blocks.Size())
|
||||
return E_FAIL;
|
||||
RINOK(WriteStream(outStream, Blocks[blockIndex], curSize));
|
||||
@@ -134,10 +164,10 @@ HRESULT CMemBlocks::WriteToStream(size_t blockSize, ISequentialOutStream *outStr
|
||||
}
|
||||
|
||||
|
||||
void CMemLockBlocks::FreeBlock(int index, CMemBlockManagerMt *memManager)
|
||||
void CMemLockBlocks::FreeBlock(unsigned index, CMemBlockManagerMt *memManager)
|
||||
{
|
||||
memManager->FreeBlock(Blocks[index], LockMode);
|
||||
Blocks[index] = 0;
|
||||
Blocks[index] = NULL;
|
||||
}
|
||||
|
||||
void CMemLockBlocks::Free(CMemBlockManagerMt *memManager)
|
||||
@@ -150,6 +180,7 @@ void CMemLockBlocks::Free(CMemBlockManagerMt *memManager)
|
||||
TotalSize = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
HRes CMemLockBlocks::SwitchToNoLockMode(CMemBlockManagerMt *memManager)
|
||||
{
|
||||
if (LockMode)
|
||||
@@ -162,13 +193,14 @@ HRes CMemLockBlocks::SwitchToNoLockMode(CMemBlockManagerMt *memManager)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
void CMemLockBlocks::Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager)
|
||||
{
|
||||
blocks.Free(memManager);
|
||||
blocks.LockMode = LockMode;
|
||||
UInt64 totalSize = 0;
|
||||
size_t blockSize = memManager->GetBlockSize();
|
||||
const size_t blockSize = memManager->GetBlockSize();
|
||||
FOR_VECTOR (i, Blocks)
|
||||
{
|
||||
if (totalSize < TotalSize)
|
||||
|
||||
@@ -15,10 +15,10 @@ class CMemBlockManager
|
||||
size_t _blockSize;
|
||||
void *_headFree;
|
||||
public:
|
||||
CMemBlockManager(size_t blockSize = (1 << 20)): _data(0), _blockSize(blockSize), _headFree(0) {}
|
||||
CMemBlockManager(size_t blockSize = (1 << 20)): _data(NULL), _blockSize(blockSize), _headFree(NULL) {}
|
||||
~CMemBlockManager() { FreeSpace(); }
|
||||
|
||||
bool AllocateSpace(size_t numBlocks);
|
||||
bool AllocateSpace_bool(size_t numBlocks);
|
||||
void FreeSpace();
|
||||
size_t GetBlockSize() const { return _blockSize; }
|
||||
void *AllocateBlock();
|
||||
@@ -30,17 +30,18 @@ class CMemBlockManagerMt: public CMemBlockManager
|
||||
{
|
||||
NWindows::NSynchronization::CCriticalSection _criticalSection;
|
||||
public:
|
||||
NWindows::NSynchronization::CSemaphore Semaphore;
|
||||
SYNC_OBJ_DECL(Synchro);
|
||||
NWindows::NSynchronization::CSemaphore_WFMO Semaphore;
|
||||
|
||||
CMemBlockManagerMt(size_t blockSize = (1 << 20)): CMemBlockManager(blockSize) {}
|
||||
~CMemBlockManagerMt() { FreeSpace(); }
|
||||
|
||||
HRes AllocateSpace(size_t numBlocks, size_t numNoLockBlocks = 0);
|
||||
HRes AllocateSpace(size_t numBlocks, size_t numNoLockBlocks);
|
||||
HRes AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks = 0);
|
||||
void FreeSpace();
|
||||
void *AllocateBlock();
|
||||
void FreeBlock(void *p, bool lockMode = true);
|
||||
HRes ReleaseLockedBlocks(int number) { return Semaphore.Release(number); }
|
||||
// WRes ReleaseLockedBlocks_WRes(unsigned number) { return Semaphore.Release(number); }
|
||||
};
|
||||
|
||||
|
||||
@@ -63,8 +64,8 @@ struct CMemLockBlocks: public CMemBlocks
|
||||
|
||||
CMemLockBlocks(): LockMode(true) {};
|
||||
void Free(CMemBlockManagerMt *memManager);
|
||||
void FreeBlock(int index, CMemBlockManagerMt *memManager);
|
||||
HRes SwitchToNoLockMode(CMemBlockManagerMt *memManager);
|
||||
void FreeBlock(unsigned index, CMemBlockManagerMt *memManager);
|
||||
// HRes SwitchToNoLockMode(CMemBlockManagerMt *memManager);
|
||||
void Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager);
|
||||
};
|
||||
|
||||
|
||||
@@ -184,10 +184,12 @@ class CCoderProps
|
||||
unsigned _numProps;
|
||||
unsigned _numPropsMax;
|
||||
public:
|
||||
CCoderProps(unsigned numPropsMax)
|
||||
CCoderProps(unsigned numPropsMax):
|
||||
_propIDs(NULL),
|
||||
_props(NULL),
|
||||
_numProps(0),
|
||||
_numPropsMax(numPropsMax)
|
||||
{
|
||||
_numPropsMax = numPropsMax;
|
||||
_numProps = 0;
|
||||
_propIDs = new PROPID[numPropsMax];
|
||||
_props = new NCOM::CPropVariant[numPropsMax];
|
||||
}
|
||||
@@ -214,7 +216,15 @@ void CCoderProps::AddProp(const CProp &prop)
|
||||
|
||||
HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const
|
||||
{
|
||||
CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0));
|
||||
return SetCoderProps_DSReduce_Aff(scp, dataSizeReduce, NULL);
|
||||
}
|
||||
|
||||
HRESULT CProps::SetCoderProps_DSReduce_Aff(
|
||||
ICompressSetCoderProperties *scp,
|
||||
const UInt64 *dataSizeReduce,
|
||||
const UInt64 *affinity) const
|
||||
{
|
||||
CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0) + (affinity ? 1 : 0) );
|
||||
FOR_VECTOR (i, Props)
|
||||
coderProps.AddProp(Props[i]);
|
||||
if (dataSizeReduce)
|
||||
@@ -224,27 +234,34 @@ HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *da
|
||||
prop.Value = *dataSizeReduce;
|
||||
coderProps.AddProp(prop);
|
||||
}
|
||||
if (affinity)
|
||||
{
|
||||
CProp prop;
|
||||
prop.Id = NCoderPropID::kAffinity;
|
||||
prop.Value = *affinity;
|
||||
coderProps.AddProp(prop);
|
||||
}
|
||||
return coderProps.SetProps(scp);
|
||||
}
|
||||
|
||||
|
||||
int CMethodProps::FindProp(PROPID id) const
|
||||
{
|
||||
for (int i = Props.Size() - 1; i >= 0; i--)
|
||||
if (Props[i].Id == id)
|
||||
for (int i = (int)Props.Size() - 1; i >= 0; i--)
|
||||
if (Props[(unsigned)i].Id == id)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CMethodProps::GetLevel() const
|
||||
unsigned CMethodProps::GetLevel() const
|
||||
{
|
||||
int i = FindProp(NCoderPropID::kLevel);
|
||||
if (i < 0)
|
||||
return 5;
|
||||
if (Props[i].Value.vt != VT_UI4)
|
||||
if (Props[(unsigned)i].Value.vt != VT_UI4)
|
||||
return 9;
|
||||
UInt32 level = Props[i].Value.ulVal;
|
||||
return level > 9 ? 9 : (int)level;
|
||||
UInt32 level = Props[(unsigned)i].Value.ulVal;
|
||||
return level > 9 ? 9 : (unsigned)level;
|
||||
}
|
||||
|
||||
struct CNameToPropID
|
||||
@@ -300,7 +317,7 @@ static int FindPropIdExact(const UString &name)
|
||||
{
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(g_NameToPropID); i++)
|
||||
if (StringsAreEqualNoCase_Ascii(name, g_NameToPropID[i].Name))
|
||||
return i;
|
||||
return (int)i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -360,8 +377,8 @@ static void SplitParam(const UString ¶m, UString &name, UString &value)
|
||||
int eqPos = param.Find(L'=');
|
||||
if (eqPos >= 0)
|
||||
{
|
||||
name.SetFrom(param, eqPos);
|
||||
value = param.Ptr(eqPos + 1);
|
||||
name.SetFrom(param, (unsigned)eqPos);
|
||||
value = param.Ptr((unsigned)(eqPos + 1));
|
||||
return;
|
||||
}
|
||||
unsigned i;
|
||||
@@ -396,7 +413,7 @@ HRESULT CMethodProps::SetParam(const UString &name, const UString &value)
|
||||
return E_INVALIDARG;
|
||||
const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index];
|
||||
CProp prop;
|
||||
prop.Id = index;
|
||||
prop.Id = (unsigned)index;
|
||||
|
||||
if (IsLogSizeProp(prop.Id))
|
||||
{
|
||||
@@ -477,7 +494,7 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const
|
||||
return E_INVALIDARG;
|
||||
const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index];
|
||||
CProp prop;
|
||||
prop.Id = index;
|
||||
prop.Id = (unsigned)index;
|
||||
|
||||
if (IsLogSizeProp(prop.Id))
|
||||
{
|
||||
@@ -499,14 +516,14 @@ HRESULT COneMethodInfo::ParseMethodFromString(const UString &s)
|
||||
{
|
||||
UString temp = s;
|
||||
if (splitPos >= 0)
|
||||
temp.DeleteFrom(splitPos);
|
||||
temp.DeleteFrom((unsigned)splitPos);
|
||||
if (!temp.IsAscii())
|
||||
return E_INVALIDARG;
|
||||
MethodName.SetFromWStr_if_Ascii(temp);
|
||||
}
|
||||
if (splitPos < 0)
|
||||
return S_OK;
|
||||
PropsString = s.Ptr(splitPos + 1);
|
||||
PropsString = s.Ptr((unsigned)(splitPos + 1));
|
||||
return ParseParamsFromString(PropsString);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,20 +53,21 @@ struct CProps
|
||||
prop.Value = s;
|
||||
}
|
||||
|
||||
HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const;
|
||||
HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce = NULL) const;
|
||||
HRESULT SetCoderProps_DSReduce_Aff(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce, const UInt64 *affinity) const;
|
||||
};
|
||||
|
||||
class CMethodProps: public CProps
|
||||
{
|
||||
HRESULT SetParam(const UString &name, const UString &value);
|
||||
public:
|
||||
int GetLevel() const;
|
||||
unsigned GetLevel() const;
|
||||
int Get_NumThreads() const
|
||||
{
|
||||
int i = FindProp(NCoderPropID::kNumThreads);
|
||||
if (i >= 0)
|
||||
if (Props[i].Value.vt == VT_UI4)
|
||||
return (int)Props[i].Value.ulVal;
|
||||
if (Props[(unsigned)i].Value.vt == VT_UI4)
|
||||
return (int)Props[(unsigned)i].Value.ulVal;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -75,9 +76,9 @@ public:
|
||||
res = 0;
|
||||
int i = FindProp(NCoderPropID::kDictionarySize);
|
||||
if (i >= 0)
|
||||
if (Props[i].Value.vt == VT_UI4)
|
||||
if (Props[(unsigned)i].Value.vt == VT_UI4)
|
||||
{
|
||||
res = Props[i].Value.ulVal;
|
||||
res = Props[(unsigned)i].Value.ulVal;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -89,8 +90,8 @@ public:
|
||||
{
|
||||
int i = FindProp(NCoderPropID::kAlgorithm);
|
||||
if (i >= 0)
|
||||
if (Props[i].Value.vt == VT_UI4)
|
||||
return Props[i].Value.ulVal;
|
||||
if (Props[(unsigned)i].Value.vt == VT_UI4)
|
||||
return Props[(unsigned)i].Value.ulVal;
|
||||
return GetLevel() >= 5 ? 1 : 0;
|
||||
}
|
||||
|
||||
@@ -98,10 +99,14 @@ public:
|
||||
{
|
||||
int i = FindProp(NCoderPropID::kDictionarySize);
|
||||
if (i >= 0)
|
||||
if (Props[i].Value.vt == VT_UI4)
|
||||
return Props[i].Value.ulVal;
|
||||
int level = GetLevel();
|
||||
return level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26));
|
||||
if (Props[(unsigned)i].Value.vt == VT_UI4)
|
||||
return Props[(unsigned)i].Value.ulVal;
|
||||
unsigned level = GetLevel();
|
||||
return
|
||||
( level <= 3 ? (1 << (level * 2 + 16)) :
|
||||
( level <= 6 ? (1 << (level + 19)) :
|
||||
( level <= 7 ? (1 << 25) : (1 << 26)
|
||||
)));
|
||||
}
|
||||
|
||||
bool Get_Lzma_Eos() const
|
||||
@@ -109,7 +114,7 @@ public:
|
||||
int i = FindProp(NCoderPropID::kEndMarker);
|
||||
if (i >= 0)
|
||||
{
|
||||
const NWindows::NCOM::CPropVariant &val = Props[i].Value;
|
||||
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
||||
if (val.vt == VT_BOOL)
|
||||
return VARIANT_BOOLToBool(val.boolVal);
|
||||
}
|
||||
@@ -150,7 +155,7 @@ public:
|
||||
int i = FindProp(id);
|
||||
if (i >= 0)
|
||||
{
|
||||
const NWindows::NCOM::CPropVariant &val = Props[i].Value;
|
||||
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
||||
if (val.vt == VT_UI4) { return val.ulVal; }
|
||||
if (val.vt == VT_UI8) { return val.uhVal.QuadPart; }
|
||||
}
|
||||
@@ -191,8 +196,8 @@ public:
|
||||
fixedNumber = true;
|
||||
if (numThreads < 1) return 1;
|
||||
const unsigned kNumBZip2ThreadsMax = 64;
|
||||
if (numThreads > kNumBZip2ThreadsMax) return kNumBZip2ThreadsMax;
|
||||
return numThreads;
|
||||
if ((unsigned)numThreads > kNumBZip2ThreadsMax) return kNumBZip2ThreadsMax;
|
||||
return (unsigned)numThreads;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -201,16 +206,16 @@ public:
|
||||
{
|
||||
int i = FindProp(NCoderPropID::kDictionarySize);
|
||||
if (i >= 0)
|
||||
if (Props[i].Value.vt == VT_UI4)
|
||||
if (Props[(unsigned)i].Value.vt == VT_UI4)
|
||||
{
|
||||
UInt32 blockSize = Props[i].Value.ulVal;
|
||||
UInt32 blockSize = Props[(unsigned)i].Value.ulVal;
|
||||
const UInt32 kDicSizeMin = 100000;
|
||||
const UInt32 kDicSizeMax = 900000;
|
||||
if (blockSize < kDicSizeMin) blockSize = kDicSizeMin;
|
||||
if (blockSize > kDicSizeMax) blockSize = kDicSizeMax;
|
||||
return blockSize;
|
||||
}
|
||||
int level = GetLevel();
|
||||
unsigned level = GetLevel();
|
||||
return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1));
|
||||
}
|
||||
|
||||
@@ -218,10 +223,10 @@ public:
|
||||
{
|
||||
int i = FindProp(NCoderPropID::kUsedMemorySize);
|
||||
if (i >= 0)
|
||||
if (Props[i].Value.vt == VT_UI4)
|
||||
return Props[i].Value.ulVal;
|
||||
int level = GetLevel();
|
||||
return level >= 9 ? (192 << 20) : ((UInt32)1 << (level + 19));
|
||||
if (Props[(unsigned)i].Value.vt == VT_UI4)
|
||||
return Props[(unsigned)i].Value.ulVal;
|
||||
unsigned level = GetLevel();
|
||||
return ((UInt32)1 << (level + 19));
|
||||
}
|
||||
|
||||
void AddProp_Level(UInt32 level)
|
||||
|
||||
@@ -10,7 +10,7 @@ HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset)
|
||||
{
|
||||
_offset = offset;
|
||||
_stream = stream;
|
||||
return _stream->Seek(offset, STREAM_SEEK_SET, NULL);
|
||||
return _stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL);
|
||||
}
|
||||
|
||||
STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
// #include <stdio.h>
|
||||
|
||||
#include "OutMemStream.h"
|
||||
|
||||
void COutMemStream::Free()
|
||||
@@ -34,11 +36,12 @@ HRESULT COutMemStream::WriteToRealStream()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if (_realStreamMode)
|
||||
return OutSeqStream->Write(data, size, processedSize);
|
||||
if (processedSize != 0)
|
||||
if (processedSize)
|
||||
*processedSize = 0;
|
||||
while (size != 0)
|
||||
{
|
||||
@@ -49,7 +52,7 @@ STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *process
|
||||
if (size < curSize)
|
||||
curSize = size;
|
||||
memcpy(p, data, curSize);
|
||||
if (processedSize != 0)
|
||||
if (processedSize)
|
||||
*processedSize += (UInt32)curSize;
|
||||
data = (const void *)((const Byte *)data + curSize);
|
||||
size -= (UInt32)curSize;
|
||||
@@ -65,8 +68,14 @@ STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *process
|
||||
}
|
||||
continue;
|
||||
}
|
||||
HANDLE events[3] = { StopWritingEvent, WriteToRealStreamEvent, /* NoLockEvent, */ _memManager->Semaphore };
|
||||
DWORD waitResult = ::WaitForMultipleObjects((Blocks.LockMode ? 3 : 2), events, FALSE, INFINITE);
|
||||
|
||||
const NWindows::NSynchronization::CHandle_WFMO events[3] =
|
||||
{ StopWritingEvent, WriteToRealStreamEvent, /* NoLockEvent, */ _memManager->Semaphore };
|
||||
const DWORD waitResult = NWindows::NSynchronization::WaitForMultiObj_Any_Infinite(
|
||||
((Blocks.LockMode /* && _memManager->Semaphore.IsCreated() */) ? 3 : 2), events);
|
||||
|
||||
// printf("\n 1- outMemStream %d\n", waitResult - WAIT_OBJECT_0);
|
||||
|
||||
switch (waitResult)
|
||||
{
|
||||
case (WAIT_OBJECT_0 + 0):
|
||||
@@ -77,27 +86,34 @@ STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *process
|
||||
RINOK(WriteToRealStream());
|
||||
UInt32 processedSize2;
|
||||
HRESULT res = OutSeqStream->Write(data, size, &processedSize2);
|
||||
if (processedSize != 0)
|
||||
if (processedSize)
|
||||
*processedSize += processedSize2;
|
||||
return res;
|
||||
}
|
||||
/*
|
||||
case (WAIT_OBJECT_0 + 2):
|
||||
{
|
||||
// it has bug: no write.
|
||||
/*
|
||||
if (!Blocks.SwitchToNoLockMode(_memManager))
|
||||
return E_FAIL;
|
||||
*/
|
||||
break;
|
||||
}
|
||||
*/
|
||||
case (WAIT_OBJECT_0 + 2):
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if (waitResult == WAIT_FAILED)
|
||||
{
|
||||
DWORD res = ::GetLastError();
|
||||
if (res != 0)
|
||||
return HRESULT_FROM_WIN32(res);
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
Blocks.Blocks.Add(_memManager->AllocateBlock());
|
||||
if (Blocks.Blocks.Back() == 0)
|
||||
void *p = _memManager->AllocateBlock();
|
||||
if (!p)
|
||||
return E_FAIL;
|
||||
Blocks.Blocks.Add(p);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ class COutMemStream:
|
||||
bool _realStreamMode;
|
||||
|
||||
bool _unlockEventWasSent;
|
||||
NWindows::NSynchronization::CAutoResetEvent StopWritingEvent;
|
||||
NWindows::NSynchronization::CAutoResetEvent WriteToRealStreamEvent;
|
||||
NWindows::NSynchronization::CAutoResetEvent_WFMO StopWritingEvent;
|
||||
NWindows::NSynchronization::CAutoResetEvent_WFMO WriteToRealStreamEvent;
|
||||
// NWindows::NSynchronization::CAutoResetEvent NoLockEvent;
|
||||
|
||||
HRESULT StopWriteResult;
|
||||
@@ -31,10 +31,13 @@ class COutMemStream:
|
||||
|
||||
public:
|
||||
|
||||
HRes CreateEvents()
|
||||
|
||||
HRes CreateEvents(SYNC_PARAM_DECL(synchro))
|
||||
{
|
||||
RINOK(StopWritingEvent.CreateIfNotCreated());
|
||||
return WriteToRealStreamEvent.CreateIfNotCreated();
|
||||
WRes wres = StopWritingEvent.CreateIfNotCreated_Reset(SYNC_WFMO(synchro));
|
||||
if (wres == 0)
|
||||
wres = WriteToRealStreamEvent.CreateIfNotCreated_Reset(SYNC_WFMO(synchro));
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
}
|
||||
|
||||
void SetOutStream(IOutStream *outStream)
|
||||
@@ -55,7 +58,16 @@ public:
|
||||
OutSeqStream.Release();
|
||||
}
|
||||
|
||||
COutMemStream(CMemBlockManagerMt *memManager): _memManager(memManager) { }
|
||||
COutMemStream(CMemBlockManagerMt *memManager):
|
||||
_memManager(memManager)
|
||||
{
|
||||
/*
|
||||
#ifndef _WIN32
|
||||
StopWritingEvent._sync =
|
||||
WriteToRealStreamEvent._sync = &memManager->Synchro;
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
~COutMemStream() { Free(); }
|
||||
void Free();
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
#include "ProgressMt.h"
|
||||
|
||||
void CMtCompressProgressMixer::Init(int numItems, ICompressProgressInfo *progress)
|
||||
void CMtCompressProgressMixer::Init(unsigned numItems, ICompressProgressInfo *progress)
|
||||
{
|
||||
NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
|
||||
InSizes.Clear();
|
||||
OutSizes.Clear();
|
||||
for (int i = 0; i < numItems; i++)
|
||||
for (unsigned i = 0; i < numItems; i++)
|
||||
{
|
||||
InSizes.Add(0);
|
||||
OutSizes.Add(0);
|
||||
@@ -19,23 +19,23 @@ void CMtCompressProgressMixer::Init(int numItems, ICompressProgressInfo *progres
|
||||
_progress = progress;
|
||||
}
|
||||
|
||||
void CMtCompressProgressMixer::Reinit(int index)
|
||||
void CMtCompressProgressMixer::Reinit(unsigned index)
|
||||
{
|
||||
NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
|
||||
InSizes[index] = 0;
|
||||
OutSizes[index] = 0;
|
||||
}
|
||||
|
||||
HRESULT CMtCompressProgressMixer::SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize)
|
||||
HRESULT CMtCompressProgressMixer::SetRatioInfo(unsigned index, const UInt64 *inSize, const UInt64 *outSize)
|
||||
{
|
||||
NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
|
||||
if (inSize != 0)
|
||||
if (inSize)
|
||||
{
|
||||
UInt64 diff = *inSize - InSizes[index];
|
||||
InSizes[index] = *inSize;
|
||||
TotalInSize += diff;
|
||||
}
|
||||
if (outSize != 0)
|
||||
if (outSize)
|
||||
{
|
||||
UInt64 diff = *outSize - OutSizes[index];
|
||||
OutSizes[index] = *outSize;
|
||||
|
||||
@@ -19,9 +19,9 @@ class CMtCompressProgressMixer
|
||||
UInt64 TotalOutSize;
|
||||
public:
|
||||
NWindows::NSynchronization::CCriticalSection CriticalSection;
|
||||
void Init(int numItems, ICompressProgressInfo *progress);
|
||||
void Reinit(int index);
|
||||
HRESULT SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize);
|
||||
void Init(unsigned numItems, ICompressProgressInfo *progress);
|
||||
void Reinit(unsigned index);
|
||||
HRESULT SetRatioInfo(unsigned index, const UInt64 *inSize, const UInt64 *outSize);
|
||||
};
|
||||
|
||||
class CMtCompressProgress:
|
||||
@@ -29,9 +29,9 @@ class CMtCompressProgress:
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMtCompressProgressMixer *_progress;
|
||||
int _index;
|
||||
unsigned _index;
|
||||
public:
|
||||
void Init(CMtCompressProgressMixer *progress, int index)
|
||||
void Init(CMtCompressProgressMixer *progress, unsigned index)
|
||||
{
|
||||
_progress = progress;
|
||||
_index = index;
|
||||
|
||||
@@ -26,11 +26,11 @@ void RegisterCodec(const CCodecInfo *codecInfo) throw();
|
||||
#define REGISTER_CODEC_CREATE(name, cls) REGISTER_CODEC_CREATE_2(name, cls, ICompressCoder)
|
||||
|
||||
#define REGISTER_CODEC_NAME(x) CRegisterCodec ## x
|
||||
#define REGISTER_CODEC_VAR static const CCodecInfo g_CodecInfo =
|
||||
#define REGISTER_CODEC_VAR(x) static const CCodecInfo g_CodecInfo_ ## x =
|
||||
|
||||
#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \
|
||||
REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo); }}; \
|
||||
static REGISTER_CODEC_NAME(x) g_RegisterCodec;
|
||||
REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo_ ## x); }}; \
|
||||
static REGISTER_CODEC_NAME(x) g_RegisterCodec_ ## x;
|
||||
|
||||
|
||||
#define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x
|
||||
@@ -43,7 +43,7 @@ void RegisterCodec(const CCodecInfo *codecInfo) throw();
|
||||
|
||||
|
||||
#define REGISTER_CODEC_2(x, crDec, crEnc, id, name) \
|
||||
REGISTER_CODEC_VAR \
|
||||
REGISTER_CODEC_VAR(x) \
|
||||
{ crDec, crEnc, id, name, 1, false }; \
|
||||
REGISTER_CODEC(x)
|
||||
|
||||
@@ -67,19 +67,19 @@ void RegisterCodec(const CCodecInfo *codecInfo) throw();
|
||||
{ crDec, crEnc, id, name, 1, true }
|
||||
|
||||
#define REGISTER_FILTER(x, crDec, crEnc, id, name) \
|
||||
REGISTER_CODEC_VAR \
|
||||
REGISTER_CODEC_VAR(x) \
|
||||
REGISTER_FILTER_ITEM(crDec, crEnc, id, name); \
|
||||
REGISTER_CODEC(x)
|
||||
|
||||
#ifdef EXTRACT_ONLY
|
||||
#define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \
|
||||
REGISTER_FILTER_CREATE(CreateDec, clsDec) \
|
||||
REGISTER_FILTER(x, CreateDec, NULL, id, name)
|
||||
REGISTER_FILTER_CREATE(x ## _CreateDec, clsDec) \
|
||||
REGISTER_FILTER(x, x ## _CreateDec, NULL, id, name)
|
||||
#else
|
||||
#define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \
|
||||
REGISTER_FILTER_CREATE(CreateDec, clsDec) \
|
||||
REGISTER_FILTER_CREATE(CreateEnc, clsEnc) \
|
||||
REGISTER_FILTER(x, CreateDec, CreateEnc, id, name)
|
||||
REGISTER_FILTER_CREATE(x ## _CreateDec, clsDec) \
|
||||
REGISTER_FILTER_CREATE(x ## _CreateEnc, clsEnc) \
|
||||
REGISTER_FILTER(x, x ## _CreateDec, x ## _CreateEnc, id, name)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ class CBinderInStream:
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ISequentialInStream)
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
~CBinderInStream() { _binder->CloseRead(); }
|
||||
~CBinderInStream() { _binder->CloseRead_CallOnce(); }
|
||||
CBinderInStream(CStreamBinder *binder): _binder(binder) {}
|
||||
};
|
||||
|
||||
@@ -37,19 +37,24 @@ STDMETHODIMP CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
|
||||
{ return _binder->Write(data, size, processedSize); }
|
||||
|
||||
|
||||
|
||||
WRes CStreamBinder::CreateEvents()
|
||||
static HRESULT Event__Create_or_Reset(NWindows::NSynchronization::CAutoResetEvent &event)
|
||||
{
|
||||
RINOK(_canWrite_Event.Create());
|
||||
RINOK(_canRead_Event.Create());
|
||||
return _readingWasClosed_Event.Create();
|
||||
WRes wres;
|
||||
if (event.IsCreated())
|
||||
wres = event.Reset();
|
||||
else
|
||||
wres = event.Create();
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
}
|
||||
|
||||
void CStreamBinder::ReInit()
|
||||
HRESULT CStreamBinder::Create_ReInit()
|
||||
{
|
||||
_canWrite_Event.Reset();
|
||||
_canRead_Event.Reset();
|
||||
_readingWasClosed_Event.Reset();
|
||||
RINOK(Event__Create_or_Reset(_canRead_Event));
|
||||
// RINOK(Event__Create_or_Reset(_canWrite_Event));
|
||||
|
||||
_canWrite_Semaphore.Close();
|
||||
// we need at least 3 items of maxCount: 1 for normal unlock in Read(), 2 items for unlock in CloseRead_CallOnce()
|
||||
_canWrite_Semaphore.Create(0, 3);
|
||||
|
||||
// _readingWasClosed = false;
|
||||
_readingWasClosed2 = false;
|
||||
@@ -59,27 +64,14 @@ void CStreamBinder::ReInit()
|
||||
_buf = NULL;
|
||||
ProcessedSize = 0;
|
||||
// WritingWasCut = false;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream)
|
||||
void CStreamBinder::CreateStreams2(CMyComPtr<ISequentialInStream> &inStream, CMyComPtr<ISequentialOutStream> &outStream)
|
||||
{
|
||||
// _readingWasClosed = false;
|
||||
_readingWasClosed2 = false;
|
||||
|
||||
_waitWrite = true;
|
||||
_bufSize = 0;
|
||||
_buf = NULL;
|
||||
ProcessedSize = 0;
|
||||
// WritingWasCut = false;
|
||||
|
||||
CBinderInStream *inStreamSpec = new CBinderInStream(this);
|
||||
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
|
||||
*inStream = inStreamLoc.Detach();
|
||||
|
||||
CBinderOutStream *outStreamSpec = new CBinderOutStream(this);
|
||||
CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec);
|
||||
*outStream = outStreamLoc.Detach();
|
||||
inStream = new CBinderInStream(this);
|
||||
outStream = new CBinderOutStream(this);
|
||||
}
|
||||
|
||||
// (_canRead_Event && _bufSize == 0) means that stream is finished.
|
||||
@@ -92,7 +84,9 @@ HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if (_waitWrite)
|
||||
{
|
||||
RINOK(_canRead_Event.Lock());
|
||||
WRes wres = _canRead_Event.Lock();
|
||||
if (wres != 0)
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
_waitWrite = false;
|
||||
}
|
||||
if (size > _bufSize)
|
||||
@@ -105,17 +99,25 @@ HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
if (processedSize)
|
||||
*processedSize = size;
|
||||
_bufSize -= size;
|
||||
|
||||
/*
|
||||
if (_bufSize == 0), then we have read whole buffer
|
||||
we have two ways here:
|
||||
- if we check (_bufSize == 0) here, we unlock Write only after full data Reading - it reduces the number of syncs
|
||||
- if we don't check (_bufSize == 0) here, we unlock Write after partial data Reading
|
||||
*/
|
||||
if (_bufSize == 0)
|
||||
{
|
||||
_waitWrite = true;
|
||||
_canRead_Event.Reset();
|
||||
_canWrite_Event.Set();
|
||||
// _canWrite_Event.Set();
|
||||
_canWrite_Semaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if (processedSize)
|
||||
@@ -135,20 +137,20 @@ HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSiz
|
||||
_readingWasClosed2 = true;
|
||||
*/
|
||||
|
||||
HANDLE events[2] = { _canWrite_Event, _readingWasClosed_Event };
|
||||
DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
|
||||
if (waitResult >= WAIT_OBJECT_0 + 2)
|
||||
return E_FAIL;
|
||||
_canWrite_Semaphore.Lock();
|
||||
|
||||
// _bufSize : is remain size that was not read
|
||||
size -= _bufSize;
|
||||
|
||||
// size : is size of data that was read
|
||||
if (size != 0)
|
||||
{
|
||||
// if some data was read, then we report that size and return
|
||||
if (processedSize)
|
||||
*processedSize = size;
|
||||
return S_OK;
|
||||
}
|
||||
// if (waitResult == WAIT_OBJECT_0 + 1)
|
||||
_readingWasClosed2 = true;
|
||||
_readingWasClosed2 = true;
|
||||
}
|
||||
|
||||
// WritingWasCut = true;
|
||||
|
||||
@@ -8,45 +8,63 @@
|
||||
#include "../IStream.h"
|
||||
|
||||
/*
|
||||
We don't use probably UNSAFE version:
|
||||
reader thread:
|
||||
We can use one from two code versions here: with Event or with Semaphore to unlock Writer thread
|
||||
The difference for cases where Reading must be closed before Writing closing
|
||||
|
||||
1) Event Version: _canWrite_Event
|
||||
We call _canWrite_Event.Set() without waiting _canRead_Event in CloseRead() function.
|
||||
The writer thread can get (_readingWasClosed) status in one from two iterations.
|
||||
It's ambiguity of processing flow. But probably it's SAFE to use, if Event functions provide memory barriers.
|
||||
reader thread:
|
||||
_canWrite_Event.Set();
|
||||
_readingWasClosed = true
|
||||
_readingWasClosed = true;
|
||||
_canWrite_Event.Set();
|
||||
writer thread:
|
||||
writer thread:
|
||||
_canWrite_Event.Wait()
|
||||
if (_readingWasClosed)
|
||||
Can second call of _canWrite_Event.Set() be executed without memory barrier, if event is already set?
|
||||
|
||||
2) Semaphore Version: _canWrite_Semaphore
|
||||
writer thread always will detect closing of reading in latest iteration after all data processing iterations
|
||||
*/
|
||||
|
||||
class CStreamBinder
|
||||
{
|
||||
NWindows::NSynchronization::CAutoResetEvent _canWrite_Event;
|
||||
NWindows::NSynchronization::CManualResetEvent _canRead_Event;
|
||||
NWindows::NSynchronization::CManualResetEvent _readingWasClosed_Event;
|
||||
NWindows::NSynchronization::CAutoResetEvent _canRead_Event;
|
||||
// NWindows::NSynchronization::CAutoResetEvent _canWrite_Event;
|
||||
NWindows::NSynchronization::CSemaphore _canWrite_Semaphore;
|
||||
|
||||
// bool _readingWasClosed;
|
||||
bool _readingWasClosed2;
|
||||
// bool _readingWasClosed; // set it in reader thread and check it in write thread
|
||||
bool _readingWasClosed2; // use it in writer thread
|
||||
// bool WritingWasCut;
|
||||
bool _waitWrite;
|
||||
bool _waitWrite; // use it in reader thread
|
||||
UInt32 _bufSize;
|
||||
const void *_buf;
|
||||
public:
|
||||
UInt64 ProcessedSize;
|
||||
UInt64 ProcessedSize; // the size that was read by reader thread
|
||||
|
||||
WRes CreateEvents();
|
||||
void CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream);
|
||||
void CreateStreams2(CMyComPtr<ISequentialInStream> &inStream, CMyComPtr<ISequentialOutStream> &outStream);
|
||||
|
||||
void ReInit();
|
||||
HRESULT Create_ReInit();
|
||||
|
||||
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
|
||||
HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
|
||||
void CloseRead()
|
||||
void CloseRead_CallOnce()
|
||||
{
|
||||
_readingWasClosed_Event.Set();
|
||||
// _readingWasClosed = true;
|
||||
// _canWrite_Event.Set();
|
||||
// call it only once: for example, in destructor
|
||||
|
||||
/*
|
||||
_readingWasClosed = true;
|
||||
_canWrite_Event.Set();
|
||||
*/
|
||||
|
||||
/*
|
||||
We must relase Semaphore only once !!!
|
||||
we must release at least 2 items of Semaphore:
|
||||
one item to unlock partial Write(), if Read() have read some items
|
||||
then additional item to stop writing (_bufSize will be 0)
|
||||
*/
|
||||
_canWrite_Semaphore.Release(2);
|
||||
}
|
||||
|
||||
void CloseWrite()
|
||||
|
||||
@@ -37,9 +37,9 @@ STDMETHODIMP CBufferInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newP
|
||||
}
|
||||
if (offset < 0)
|
||||
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
|
||||
_pos = offset;
|
||||
_pos = (UInt64)offset;
|
||||
if (newPosition)
|
||||
*newPosition = offset;
|
||||
*newPosition = (UInt64)offset;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -72,9 +72,9 @@ STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosi
|
||||
}
|
||||
if (offset < 0)
|
||||
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
|
||||
_pos = offset;
|
||||
_pos = (UInt64)offset;
|
||||
if (newPosition)
|
||||
*newPosition = offset;
|
||||
*newPosition = (UInt64)offset;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -108,14 +108,10 @@ bool CByteDynBuffer::EnsureCapacity(size_t cap) throw()
|
||||
{
|
||||
if (cap <= _capacity)
|
||||
return true;
|
||||
size_t delta;
|
||||
if (_capacity > 64)
|
||||
delta = _capacity / 4;
|
||||
else if (_capacity > 8)
|
||||
delta = 16;
|
||||
else
|
||||
delta = 4;
|
||||
cap = MyMax(_capacity + delta, cap);
|
||||
size_t delta = _capacity / 4;
|
||||
size_t cap2 = _capacity + delta;
|
||||
if (cap < cap2)
|
||||
cap = cap2;
|
||||
Byte *buf = (Byte *)realloc(_buf, cap);
|
||||
if (!buf)
|
||||
return false;
|
||||
@@ -185,9 +181,9 @@ static const UInt64 kEmptyTag = (UInt64)(Int64)-1;
|
||||
void CCachedInStream::Free() throw()
|
||||
{
|
||||
MyFree(_tags);
|
||||
_tags = 0;
|
||||
_tags = NULL;
|
||||
MidFree(_data);
|
||||
_data = 0;
|
||||
_data = NULL;
|
||||
}
|
||||
|
||||
bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw()
|
||||
@@ -196,19 +192,19 @@ bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw(
|
||||
if (sizeLog >= sizeof(size_t) * 8)
|
||||
return false;
|
||||
size_t dataSize = (size_t)1 << sizeLog;
|
||||
if (_data == 0 || dataSize != _dataSize)
|
||||
if (!_data || dataSize != _dataSize)
|
||||
{
|
||||
MidFree(_data);
|
||||
_data = (Byte *)MidAlloc(dataSize);
|
||||
if (_data == 0)
|
||||
if (!_data)
|
||||
return false;
|
||||
_dataSize = dataSize;
|
||||
}
|
||||
if (_tags == 0 || numBlocksLog != _numBlocksLog)
|
||||
if (!_tags || numBlocksLog != _numBlocksLog)
|
||||
{
|
||||
MyFree(_tags);
|
||||
_tags = (UInt64 *)MyAlloc(sizeof(UInt64) << numBlocksLog);
|
||||
if (_tags == 0)
|
||||
if (!_tags)
|
||||
return false;
|
||||
_numBlocksLog = numBlocksLog;
|
||||
}
|
||||
@@ -242,21 +238,32 @@ STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
|
||||
|
||||
while (size != 0)
|
||||
{
|
||||
UInt64 cacheTag = _pos >> _blockSizeLog;
|
||||
size_t cacheIndex = (size_t)cacheTag & (((size_t)1 << _numBlocksLog) - 1);
|
||||
const UInt64 cacheTag = _pos >> _blockSizeLog;
|
||||
const size_t cacheIndex = (size_t)cacheTag & (((size_t)1 << _numBlocksLog) - 1);
|
||||
Byte *p = _data + (cacheIndex << _blockSizeLog);
|
||||
|
||||
if (_tags[cacheIndex] != cacheTag)
|
||||
{
|
||||
_tags[cacheIndex] = kEmptyTag;
|
||||
UInt64 remInBlock = _size - (cacheTag << _blockSizeLog);
|
||||
size_t blockSize = (size_t)1 << _blockSizeLog;
|
||||
if (blockSize > remInBlock)
|
||||
blockSize = (size_t)remInBlock;
|
||||
|
||||
RINOK(ReadBlock(cacheTag, p, blockSize));
|
||||
|
||||
_tags[cacheIndex] = cacheTag;
|
||||
}
|
||||
size_t offset = (size_t)_pos & (((size_t)1 << _blockSizeLog) - 1);
|
||||
UInt32 cur = (UInt32)MyMin(((size_t)1 << _blockSizeLog) - offset, (size_t)size);
|
||||
|
||||
const size_t kBlockSize = (size_t)1 << _blockSizeLog;
|
||||
const size_t offset = (size_t)_pos & (kBlockSize - 1);
|
||||
UInt32 cur = size;
|
||||
const size_t rem = kBlockSize - offset;
|
||||
if (cur > rem)
|
||||
cur = (UInt32)rem;
|
||||
|
||||
memcpy(data, p + offset, cur);
|
||||
|
||||
if (processedSize)
|
||||
*processedSize += cur;
|
||||
data = (void *)((const Byte *)data + cur);
|
||||
@@ -266,6 +273,7 @@ STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
|
||||
{
|
||||
@@ -278,8 +286,8 @@ STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newP
|
||||
}
|
||||
if (offset < 0)
|
||||
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
|
||||
_pos = offset;
|
||||
_pos = (UInt64)offset;
|
||||
if (newPosition)
|
||||
*newPosition = offset;
|
||||
*newPosition = (UInt64)offset;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ public:
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
||||
};
|
||||
|
||||
|
||||
struct CReferenceBuf:
|
||||
public IUnknown,
|
||||
public CMyUnknownImp
|
||||
@@ -32,6 +33,7 @@ struct CReferenceBuf:
|
||||
MY_UNKNOWN_IMP
|
||||
};
|
||||
|
||||
|
||||
class CBufInStream:
|
||||
public IInStream,
|
||||
public CMyUnknownImp
|
||||
@@ -41,7 +43,7 @@ class CBufInStream:
|
||||
size_t _size;
|
||||
CMyComPtr<IUnknown> _ref;
|
||||
public:
|
||||
void Init(const Byte *data, size_t size, IUnknown *ref = 0)
|
||||
void Init(const Byte *data, size_t size, IUnknown *ref = NULL)
|
||||
{
|
||||
_data = data;
|
||||
_size = size;
|
||||
@@ -55,17 +57,20 @@ public:
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
||||
};
|
||||
|
||||
|
||||
void Create_BufInStream_WithReference(const void *data, size_t size, IUnknown *ref, ISequentialInStream **stream);
|
||||
void Create_BufInStream_WithNewBuffer(const void *data, size_t size, ISequentialInStream **stream);
|
||||
inline void Create_BufInStream_WithNewBuffer(const CByteBuffer &buf, ISequentialInStream **stream)
|
||||
{ Create_BufInStream_WithNewBuffer(buf, buf.Size(), stream); }
|
||||
|
||||
|
||||
class CByteDynBuffer
|
||||
{
|
||||
size_t _capacity;
|
||||
Byte *_buf;
|
||||
CLASS_NO_COPY(CByteDynBuffer);
|
||||
public:
|
||||
CByteDynBuffer(): _capacity(0), _buf(0) {};
|
||||
CByteDynBuffer(): _capacity(0), _buf(NULL) {};
|
||||
// there is no copy constructor. So don't copy this object.
|
||||
~CByteDynBuffer() { Free(); }
|
||||
void Free() throw();
|
||||
@@ -75,6 +80,7 @@ public:
|
||||
bool EnsureCapacity(size_t capacity) throw();
|
||||
};
|
||||
|
||||
|
||||
class CDynBufSeqOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
@@ -94,6 +100,7 @@ public:
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
|
||||
class CBufPtrSeqOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
@@ -114,6 +121,7 @@ public:
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
|
||||
class CSequentialOutStreamSizeCount:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
@@ -129,6 +137,7 @@ public:
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
|
||||
class CCachedInStream:
|
||||
public IInStream,
|
||||
public CMyUnknownImp
|
||||
@@ -143,7 +152,7 @@ class CCachedInStream:
|
||||
protected:
|
||||
virtual HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) = 0;
|
||||
public:
|
||||
CCachedInStream(): _tags(0), _data(0) {}
|
||||
CCachedInStream(): _tags(NULL), _data(NULL) {}
|
||||
virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (release calls it) !!!
|
||||
void Free() throw();
|
||||
bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw();
|
||||
|
||||
@@ -19,7 +19,7 @@ struct CUniqBlocks
|
||||
|
||||
bool IsOnlyEmpty() const
|
||||
{
|
||||
return (Bufs.Size() == 0 || Bufs.Size() == 1 && Bufs[0].Size() == 0);
|
||||
return (Bufs.Size() == 0 || (Bufs.Size() == 1 && Bufs[0].Size() == 0));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -19,20 +19,20 @@ static THREAD_FUNC_DECL CoderThread(void *p)
|
||||
|
||||
WRes CVirtThread::Create()
|
||||
{
|
||||
RINOK(StartEvent.CreateIfNotCreated());
|
||||
RINOK(FinishedEvent.CreateIfNotCreated());
|
||||
StartEvent.Reset();
|
||||
FinishedEvent.Reset();
|
||||
RINOK_WRes(StartEvent.CreateIfNotCreated_Reset());
|
||||
RINOK_WRes(FinishedEvent.CreateIfNotCreated_Reset());
|
||||
// StartEvent.Reset();
|
||||
// FinishedEvent.Reset();
|
||||
Exit = false;
|
||||
if (Thread.IsCreated())
|
||||
return S_OK;
|
||||
return Thread.Create(CoderThread, this);
|
||||
}
|
||||
|
||||
void CVirtThread::Start()
|
||||
WRes CVirtThread::Start()
|
||||
{
|
||||
Exit = false;
|
||||
StartEvent.Set();
|
||||
return StartEvent.Set();
|
||||
}
|
||||
|
||||
void CVirtThread::WaitThreadFinish()
|
||||
@@ -42,7 +42,6 @@ void CVirtThread::WaitThreadFinish()
|
||||
StartEvent.Set();
|
||||
if (Thread.IsCreated())
|
||||
{
|
||||
Thread.Wait();
|
||||
Thread.Close();
|
||||
Thread.Wait_Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ struct CVirtThread
|
||||
~CVirtThread() { WaitThreadFinish(); }
|
||||
void WaitThreadFinish(); // call it in destructor of child class !
|
||||
WRes Create();
|
||||
void Start();
|
||||
WRes Start();
|
||||
virtual void Execute() = 0;
|
||||
void WaitExecuteFinish() { FinishedEvent.Lock(); }
|
||||
WRes WaitExecuteFinish() { return FinishedEvent.Lock(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user