mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 09:14:58 -06:00
9.04 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
8874e4fbc9
commit
829409452d
@@ -8,6 +8,11 @@
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_DEVICE_FILE
|
||||
#include "../../../C/Alloc.h"
|
||||
#include "../../Common/Defs.h"
|
||||
#endif
|
||||
|
||||
#include "FileStreams.h"
|
||||
|
||||
static inline HRESULT ConvertBoolToHRESULT(bool result)
|
||||
@@ -52,24 +57,138 @@ bool CInFileStream::OpenShared(LPCWSTR fileName, bool shareForWrite)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_DEVICE_FILE
|
||||
|
||||
static const UInt32 kClusterSize = 1 << 18;
|
||||
CInFileStream::CInFileStream():
|
||||
VirtPos(0),
|
||||
PhyPos(0),
|
||||
Buffer(0),
|
||||
BufferSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
CInFileStream::~CInFileStream()
|
||||
{
|
||||
#ifdef SUPPORT_DEVICE_FILE
|
||||
MidFree(Buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
#ifdef USE_WIN_FILE
|
||||
|
||||
#ifdef SUPPORT_DEVICE_FILE
|
||||
if (processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
if (size == 0)
|
||||
return S_OK;
|
||||
if (File.IsDeviceFile)
|
||||
{
|
||||
if (File.LengthDefined)
|
||||
{
|
||||
if (VirtPos >= File.Length)
|
||||
return VirtPos == File.Length ? S_OK : E_FAIL;
|
||||
UInt64 rem = File.Length - VirtPos;
|
||||
if (size > rem)
|
||||
size = (UInt32)rem;
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
const UInt32 mask = kClusterSize - 1;
|
||||
UInt64 mask2 = ~(UInt64)mask;
|
||||
UInt64 alignedPos = VirtPos & mask2;
|
||||
if (BufferSize > 0 && BufferStartPos == alignedPos)
|
||||
{
|
||||
UInt32 pos = (UInt32)VirtPos & mask;
|
||||
if (pos >= BufferSize)
|
||||
return S_OK;
|
||||
UInt32 rem = MyMin(BufferSize - pos, size);
|
||||
memcpy(data, Buffer + pos, rem);
|
||||
VirtPos += rem;
|
||||
if (processedSize != NULL)
|
||||
*processedSize += rem;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
bool useBuffer = false;
|
||||
if ((VirtPos & mask) != 0 || ((ptrdiff_t)data & mask) != 0 )
|
||||
useBuffer = true;
|
||||
else
|
||||
{
|
||||
UInt64 end = VirtPos + size;
|
||||
if ((end & mask) != 0)
|
||||
{
|
||||
end &= mask2;
|
||||
if (end <= VirtPos)
|
||||
useBuffer = true;
|
||||
else
|
||||
size = (UInt32)(end - VirtPos);
|
||||
}
|
||||
}
|
||||
if (!useBuffer)
|
||||
break;
|
||||
if (alignedPos != PhyPos)
|
||||
{
|
||||
UInt64 realNewPosition;
|
||||
bool result = File.Seek(alignedPos, FILE_BEGIN, realNewPosition);
|
||||
if (!result)
|
||||
return ConvertBoolToHRESULT(result);
|
||||
PhyPos = realNewPosition;
|
||||
}
|
||||
|
||||
BufferStartPos = alignedPos;
|
||||
UInt32 readSize = kClusterSize;
|
||||
if (File.LengthDefined)
|
||||
readSize = (UInt32)MyMin(File.Length - PhyPos, (UInt64)kClusterSize);
|
||||
|
||||
if (Buffer == 0)
|
||||
{
|
||||
Buffer = (Byte *)MidAlloc(kClusterSize);
|
||||
if (Buffer == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
bool result = File.Read1(Buffer, readSize, BufferSize);
|
||||
if (!result)
|
||||
return ConvertBoolToHRESULT(result);
|
||||
|
||||
if (BufferSize == 0)
|
||||
return S_OK;
|
||||
PhyPos += BufferSize;
|
||||
}
|
||||
|
||||
if (VirtPos != PhyPos)
|
||||
{
|
||||
UInt64 realNewPosition;
|
||||
bool result = File.Seek(VirtPos, FILE_BEGIN, realNewPosition);
|
||||
if (!result)
|
||||
return ConvertBoolToHRESULT(result);
|
||||
PhyPos = VirtPos = realNewPosition;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
UInt32 realProcessedSize;
|
||||
bool result = File.ReadPart(data, size, realProcessedSize);
|
||||
if(processedSize != NULL)
|
||||
if (processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
#ifdef SUPPORT_DEVICE_FILE
|
||||
VirtPos += realProcessedSize;
|
||||
PhyPos += realProcessedSize;
|
||||
#endif
|
||||
return ConvertBoolToHRESULT(result);
|
||||
|
||||
#else
|
||||
|
||||
if(processedSize != NULL)
|
||||
if (processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
ssize_t res = File.Read(data, (size_t)size);
|
||||
if (res == -1)
|
||||
return E_FAIL;
|
||||
if(processedSize != NULL)
|
||||
if (processedSize != NULL)
|
||||
*processedSize = (UInt32)res;
|
||||
return S_OK;
|
||||
|
||||
@@ -80,10 +199,13 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
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)
|
||||
|
||||
DWORD realProcessedSize;
|
||||
UInt32 sizeTemp = (1 << 20);
|
||||
if (sizeTemp > size)
|
||||
sizeTemp = size;
|
||||
BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL);
|
||||
if (processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
|
||||
return S_OK;
|
||||
@@ -91,7 +213,7 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi
|
||||
|
||||
#else
|
||||
|
||||
if(processedSize != NULL)
|
||||
if (processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
ssize_t res;
|
||||
do
|
||||
@@ -101,7 +223,7 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi
|
||||
while (res < 0 && (errno == EINTR));
|
||||
if (res == -1)
|
||||
return E_FAIL;
|
||||
if(processedSize != NULL)
|
||||
if (processedSize != NULL)
|
||||
*processedSize = (UInt32)res;
|
||||
return S_OK;
|
||||
|
||||
@@ -113,14 +235,37 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi
|
||||
STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
|
||||
UInt64 *newPosition)
|
||||
{
|
||||
if(seekOrigin >= 3)
|
||||
if (seekOrigin >= 3)
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
|
||||
#ifdef USE_WIN_FILE
|
||||
|
||||
#ifdef SUPPORT_DEVICE_FILE
|
||||
if (File.IsDeviceFile)
|
||||
{
|
||||
UInt64 newVirtPos = offset;
|
||||
switch(seekOrigin)
|
||||
{
|
||||
case STREAM_SEEK_SET: break;
|
||||
case STREAM_SEEK_CUR: newVirtPos += VirtPos; break;
|
||||
case STREAM_SEEK_END: newVirtPos += File.Length; break;
|
||||
default: return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
VirtPos = newVirtPos;
|
||||
if (newPosition)
|
||||
*newPosition = newVirtPos;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
UInt64 realNewPosition;
|
||||
bool result = File.Seek(offset, seekOrigin, realNewPosition);
|
||||
if(newPosition != NULL)
|
||||
|
||||
#ifdef SUPPORT_DEVICE_FILE
|
||||
PhyPos = VirtPos = realNewPosition;
|
||||
#endif
|
||||
|
||||
if (newPosition != NULL)
|
||||
*newPosition = realNewPosition;
|
||||
return ConvertBoolToHRESULT(result);
|
||||
|
||||
@@ -129,7 +274,7 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
|
||||
off_t res = File.Seek(offset, seekOrigin);
|
||||
if (res == -1)
|
||||
return E_FAIL;
|
||||
if(newPosition != NULL)
|
||||
if (newPosition != NULL)
|
||||
*newPosition = (UInt64)res;
|
||||
return S_OK;
|
||||
|
||||
@@ -157,18 +302,18 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces
|
||||
UInt32 realProcessedSize;
|
||||
bool result = File.WritePart(data, size, realProcessedSize);
|
||||
ProcessedSize += realProcessedSize;
|
||||
if(processedSize != NULL)
|
||||
if (processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return ConvertBoolToHRESULT(result);
|
||||
|
||||
#else
|
||||
|
||||
if(processedSize != NULL)
|
||||
if (processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
ssize_t res = File.Write(data, (size_t)size);
|
||||
if (res == -1)
|
||||
return E_FAIL;
|
||||
if(processedSize != NULL)
|
||||
if (processedSize != NULL)
|
||||
*processedSize = (UInt32)res;
|
||||
ProcessedSize += res;
|
||||
return S_OK;
|
||||
@@ -178,13 +323,13 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces
|
||||
|
||||
STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
|
||||
{
|
||||
if(seekOrigin >= 3)
|
||||
if (seekOrigin >= 3)
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
#ifdef USE_WIN_FILE
|
||||
|
||||
UInt64 realNewPosition;
|
||||
bool result = File.Seek(offset, seekOrigin, realNewPosition);
|
||||
if(newPosition != NULL)
|
||||
if (newPosition != NULL)
|
||||
*newPosition = realNewPosition;
|
||||
return ConvertBoolToHRESULT(result);
|
||||
|
||||
@@ -193,7 +338,7 @@ STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo
|
||||
off_t res = File.Seek(offset, seekOrigin);
|
||||
if (res == -1)
|
||||
return E_FAIL;
|
||||
if(newPosition != NULL)
|
||||
if (newPosition != NULL)
|
||||
*newPosition = (UInt64)res;
|
||||
return S_OK;
|
||||
|
||||
@@ -204,7 +349,7 @@ STDMETHODIMP COutFileStream::SetSize(Int64 newSize)
|
||||
{
|
||||
#ifdef USE_WIN_FILE
|
||||
UInt64 currentPos;
|
||||
if(!File.Seek(0, FILE_CURRENT, currentPos))
|
||||
if (!File.Seek(0, FILE_CURRENT, currentPos))
|
||||
return E_FAIL;
|
||||
bool result = File.SetLength(newSize);
|
||||
UInt64 currentPos2;
|
||||
@@ -218,7 +363,7 @@ STDMETHODIMP COutFileStream::SetSize(Int64 newSize)
|
||||
#ifndef _WIN32_WCE
|
||||
STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if(processedSize != NULL)
|
||||
if (processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -235,7 +380,7 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
|
||||
data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
|
||||
size -= realProcessedSize;
|
||||
data = (const void *)((const Byte *)data + realProcessedSize);
|
||||
if(processedSize != NULL)
|
||||
if (processedSize != NULL)
|
||||
*processedSize += realProcessedSize;
|
||||
}
|
||||
return ConvertBoolToHRESULT(res != FALSE);
|
||||
@@ -250,7 +395,7 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
|
||||
while (res < 0 && (errno == EINTR));
|
||||
if (res == -1)
|
||||
return E_FAIL;
|
||||
if(processedSize != NULL)
|
||||
if (processedSize != NULL)
|
||||
*processedSize = (UInt32)res;
|
||||
return S_OK;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user