4.60 beta

This commit is contained in:
Igor Pavlov
2008-08-19 00:00:00 +00:00
committed by Kornel Lesiński
parent 173c07e166
commit c10e6b16f6
107 changed files with 490 additions and 503 deletions

View File

@@ -236,25 +236,40 @@ STDMETHODIMP CUdfInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
const CFile &file = _archive->Files[ref.FileIndex];
const CItem &item = _archive->Items[file.ItemIndex];
const CMyExtent &extent = item.Extents[_extentIndex];
UInt32 rem = extent.GetLen() - _offsetInExtent;
if (rem == 0)
HRESULT res = S_OK;
if (item.IsInline)
{
_extentIndex++;
_offsetInExtent = 0;
continue;
size_t rem = item.InlineData.GetCapacity() - _offsetInExtent;
if (rem == 0)
return S_OK;
if (rem > _rem)
rem = (size_t)_rem;
memcpy(data, (const Byte *)item.InlineData + _offsetInExtent, rem);
}
if (size > rem)
size = rem;
int partitionIndex = vol.PartitionMaps[extent.PartitionRef].PartitionIndex;
UInt32 logBlockNumber = extent.Pos;
const CPartition &partition = _archive->Partitions[partitionIndex];
UInt64 offset = ((UInt64)partition.Pos << _archive->SecLogSize) +
else
{
if (_extentIndex >= item.Extents.Size())
return S_OK;
const CMyExtent &extent = item.Extents[_extentIndex];
UInt32 rem = extent.GetLen() - _offsetInExtent;
if (rem == 0)
{
_extentIndex++;
_offsetInExtent = 0;
continue;
}
if (size > rem)
size = rem;
int partitionIndex = vol.PartitionMaps[extent.PartitionRef].PartitionIndex;
UInt32 logBlockNumber = extent.Pos;
const CPartition &partition = _archive->Partitions[partitionIndex];
UInt64 offset = ((UInt64)partition.Pos << _archive->SecLogSize) +
(UInt64)logBlockNumber * vol.BlockSize + _offsetInExtent;
RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL));
HRESULT res = _stream->Read(data, size, &size);
RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL));
res = _stream->Read(data, size, &size);
}
_offsetInExtent += size;
_rem -= size;
if (processedSize)

View File

@@ -26,6 +26,7 @@ const int kNumFilesMax = 1 << 28;
const int kNumRefsMax = 1 << 28;
const UInt32 kNumExtentsMax = (UInt32)1 << 30;
const UInt64 kFileNameLengthTotalMax = (UInt64)1 << 33;
const UInt64 kInlineExtentsSizeMax = (UInt64)1 << 33;
void MY_FAST_CALL Crc16GenerateTable(void);
@@ -275,6 +276,11 @@ HRESULT CInArchive::ReadFromFile(int volIndex, const CItem &item, CByteBuffer &b
{
if (item.Size >= (UInt32)1 << 30)
return S_FALSE;
if (item.IsInline)
{
buf = item.InlineData;
return S_OK;
}
buf.SetCapacity((size_t)item.Size);
size_t pos = 0;
for (int i = 0; i < item.Extents.Size(); i++)
@@ -448,37 +454,46 @@ HRESULT CInArchive::ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &la
pos += extendedAttrLen;
int desctType = item.IcbTag.GetDescriptorType();
// if (desctType == ICB_DESC_TYPE_INLINE || desctType == ICB_DESC_TYPE_EXTENDED)
if (desctType != ICB_DESC_TYPE_SHORT && desctType != ICB_DESC_TYPE_LONG)
return S_FALSE;
if (allocDescriptorsLen > size - pos)
return S_FALSE;
for (UInt32 i = 0; i < allocDescriptorsLen;)
if (desctType == ICB_DESC_TYPE_INLINE)
{
CMyExtent e;
if (desctType == ICB_DESC_TYPE_SHORT)
item.IsInline = true;
item.InlineData.SetCapacity(allocDescriptorsLen);
memcpy(item.InlineData, p + pos, allocDescriptorsLen);
}
else
{
item.IsInline = false;
if (desctType != ICB_DESC_TYPE_SHORT && desctType != ICB_DESC_TYPE_LONG)
return S_FALSE;
for (UInt32 i = 0; i < allocDescriptorsLen;)
{
if (i + 8 > allocDescriptorsLen)
return S_FALSE;
CShortAllocDesc sad;
sad.Parse(p + pos + i);
e.Pos = sad.Pos;
e.Len = sad.Len;
e.PartitionRef = lad.Location.PartitionRef;
i += 8;
CMyExtent e;
if (desctType == ICB_DESC_TYPE_SHORT)
{
if (i + 8 > allocDescriptorsLen)
return S_FALSE;
CShortAllocDesc sad;
sad.Parse(p + pos + i);
e.Pos = sad.Pos;
e.Len = sad.Len;
e.PartitionRef = lad.Location.PartitionRef;
i += 8;
}
else
{
if (i + 16 > allocDescriptorsLen)
return S_FALSE;
CLongAllocDesc ladNew;
ladNew.Parse(p + pos + i);
e.Pos = ladNew.Location.Pos;
e.PartitionRef = ladNew.Location.PartitionRef;
e.Len = ladNew.Len;
i += 16;
}
item.Extents.Add(e);
}
else
{
if (i + 16 > allocDescriptorsLen)
return S_FALSE;
CLongAllocDesc ladNew;
ladNew.Parse(p + pos + i);
e.Pos = ladNew.Location.Pos;
e.PartitionRef = ladNew.Location.PartitionRef;
e.Len = ladNew.Len;
i += 16;
}
item.Extents.Add(e);
}
if (item.IcbTag.IsDir())
@@ -489,6 +504,7 @@ HRESULT CInArchive::ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &la
RINOK(ReadFromFile(volIndex, item, buf));
item.Size = 0;
item.Extents.ClearAndFree();
item.InlineData.Free();
const Byte *p = buf;
size = buf.GetCapacity();
@@ -524,6 +540,10 @@ HRESULT CInArchive::ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &la
if ((UInt32)item.Extents.Size() > kNumExtentsMax - _numExtents)
return S_FALSE;
_numExtents += item.Extents.Size();
if (item.InlineData.GetCapacity() > kInlineExtentsSizeMax - _inlineExtentsSize)
return S_FALSE;
_inlineExtentsSize += item.InlineData.GetCapacity();
}
return S_OK;
@@ -769,6 +789,7 @@ void CInArchive::Clear()
_fileNameLengthTotal = 0;
_numRefs = 0;
_numExtents = 0;
_inlineExtentsSize = 0;
_processedProgressBytes = 0;
}

View File

@@ -167,6 +167,8 @@ struct CPartitionMap
int PartitionIndex;
};
// ECMA 4/14.6
enum EIcbFileType
{
ICB_FILE_TYPE_DIR = 4,
@@ -243,6 +245,8 @@ struct CItem
// CRegId ImplId;
// UInt64 UniqueId;
bool IsInline;
CByteBuffer InlineData;
CRecordVector<CMyExtent> Extents;
CRecordVector<int> SubFiles;
@@ -258,6 +262,8 @@ struct CItem
UInt64 GetChunksSumSize() const
{
if (IsInline)
return InlineData.GetCapacity();
UInt64 size = 0;
for (int i = 0; i < Extents.Size(); i++)
size += Extents[i].GetLen();
@@ -343,6 +349,7 @@ class CInArchive
UInt64 _fileNameLengthTotal;
int _numRefs;
UInt32 _numExtents;
UInt64 _inlineExtentsSize;
bool CheckExtent(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len) const;
public:
HRESULT Open(IInStream *inStream, CProgressVirt *progress);