diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2010-11-02 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:04 +0300 |
commit | c65230d8585317f7cd58ae2982067385269fdee9 (patch) | |
tree | 436513094ff5034da4c88def9609f0ea376065c6 /CPP/7zip/Archive/Common | |
parent | 2eb60a059819da595efb8e1de49f04c241f5b981 (diff) |
9.189.18
Diffstat (limited to 'CPP/7zip/Archive/Common')
-rwxr-xr-x | CPP/7zip/Archive/Common/ItemNameUtils.cpp | 2 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/MultiStream.cpp | 99 | ||||
-rwxr-xr-x | CPP/7zip/Archive/Common/MultiStream.h | 32 |
3 files changed, 66 insertions, 67 deletions
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp index 71996a63..a5e0dc0b 100755 --- a/CPP/7zip/Archive/Common/ItemNameUtils.cpp +++ b/CPP/7zip/Archive/Common/ItemNameUtils.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include "../../../../C/Types.h" + #include "ItemNameUtils.h" namespace NArchive { diff --git a/CPP/7zip/Archive/Common/MultiStream.cpp b/CPP/7zip/Archive/Common/MultiStream.cpp index cf7dc050..04d11caf 100755 --- a/CPP/7zip/Archive/Common/MultiStream.cpp +++ b/CPP/7zip/Archive/Common/MultiStream.cpp @@ -6,72 +6,61 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) { - if(processedSize != NULL) + if (processedSize) *processedSize = 0; - while(_streamIndex < Streams.Size() && size > 0) + if (size == 0) + return S_OK; + if (_pos >= _totalLength) + return (_pos == _totalLength) ? S_OK : E_FAIL; + { - CSubStreamInfo &s = Streams[_streamIndex]; - if (_pos == s.Size) + int left = 0, mid = _streamIndex, right = Streams.Size(); + for (;;) { - _streamIndex++; - _pos = 0; - continue; + CSubStreamInfo &m = Streams[mid]; + if (_pos < m.GlobalOffset) + right = mid; + else if (_pos >= m.GlobalOffset + m.Size) + left = mid + 1; + else + { + _streamIndex = mid; + break; + } + mid = (left + right) / 2; } - RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0)); - UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos)); - UInt32 realProcessed; - HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed); - data = (void *)((Byte *)data + realProcessed); - size -= realProcessed; - if(processedSize != NULL) - *processedSize += realProcessed; - _pos += realProcessed; - _seekPos += realProcessed; - RINOK(result); - break; + _streamIndex = mid; } - return S_OK; + + CSubStreamInfo &s = Streams[_streamIndex]; + UInt64 localPos = _pos - s.GlobalOffset; + if (localPos != s.LocalPos) + { + RINOK(s.Stream->Seek(localPos, STREAM_SEEK_SET, &s.LocalPos)); + } + UInt64 rem = s.Size - localPos; + if (size > rem) + size = (UInt32)rem; + HRESULT result = s.Stream->Read(data, size, &size); + _pos += size; + s.LocalPos += size; + if (processedSize) + *processedSize = size; + return result; } -STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, - UInt64 *newPosition) +STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) { - UInt64 newPos; switch(seekOrigin) { - case STREAM_SEEK_SET: - newPos = offset; - break; - case STREAM_SEEK_CUR: - newPos = _seekPos + offset; - break; - case STREAM_SEEK_END: - newPos = _totalLength + offset; - break; - default: - return STG_E_INVALIDFUNCTION; - } - _seekPos = 0; - for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++) - { - UInt64 size = Streams[_streamIndex].Size; - if (newPos < _seekPos + size) - { - _pos = newPos - _seekPos; - _seekPos += _pos; - if (newPosition != 0) - *newPosition = newPos; - return S_OK; - } - _seekPos += size; + case STREAM_SEEK_SET: _pos = offset; break; + case STREAM_SEEK_CUR: _pos = _pos + offset; break; + case STREAM_SEEK_END: _pos = _totalLength + offset; break; + default: return STG_E_INVALIDFUNCTION; } - if (newPos == _seekPos) - { - if (newPosition != 0) - *newPosition = newPos; - return S_OK; - } - return E_FAIL; + if (newPosition != 0) + *newPosition = _pos; + return S_OK; } diff --git a/CPP/7zip/Archive/Common/MultiStream.h b/CPP/7zip/Archive/Common/MultiStream.h index 137c9400..3fceb7cc 100755 --- a/CPP/7zip/Archive/Common/MultiStream.h +++ b/CPP/7zip/Archive/Common/MultiStream.h @@ -1,36 +1,44 @@ // MultiStream.h -#ifndef __MULTISTREAM_H -#define __MULTISTREAM_H +#ifndef __MULTI_STREAM_H +#define __MULTI_STREAM_H #include "../../../Common/MyCom.h" #include "../../../Common/MyVector.h" -#include "../../Archive/IArchive.h" + +#include "../../IStream.h" class CMultiStream: public IInStream, public CMyUnknownImp { - int _streamIndex; UInt64 _pos; - UInt64 _seekPos; UInt64 _totalLength; + int _streamIndex; public: struct CSubStreamInfo { CMyComPtr<IInStream> Stream; - UInt64 Pos; UInt64 Size; + UInt64 GlobalOffset; + UInt64 LocalPos; }; CObjectVector<CSubStreamInfo> Streams; - void Init() + + HRESULT Init() { - _streamIndex = 0; - _pos = 0; - _seekPos = 0; - _totalLength = 0; + UInt64 total = 0; for (int i = 0; i < Streams.Size(); i++) - _totalLength += Streams[i].Size; + { + CSubStreamInfo &s = Streams[i]; + s.GlobalOffset = total; + total += Streams[i].Size; + RINOK(s.Stream->Seek(0, STREAM_SEEK_CUR, &s.LocalPos)); + } + _totalLength = total; + _pos = 0; + _streamIndex = 0; + return S_OK; } MY_UNKNOWN_IMP1(IInStream) |