1 // MultiStream.cpp
2
3 #include "StdAfx.h"
4
5 #include "MultiStream.h"
6
Z7_COM7F_IMF(CMultiStream::Read (void * data,UInt32 size,UInt32 * processedSize))7 Z7_COM7F_IMF(CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize))
8 {
9 if (processedSize)
10 *processedSize = 0;
11 if (size == 0)
12 return S_OK;
13 if (_pos >= _totalLength)
14 return S_OK;
15
16 {
17 unsigned left = 0, mid = _streamIndex, right = Streams.Size();
18 for (;;)
19 {
20 CSubStreamInfo &m = Streams[mid];
21 if (_pos < m.GlobalOffset)
22 right = mid;
23 else if (_pos >= m.GlobalOffset + m.Size)
24 left = mid + 1;
25 else
26 break;
27 mid = (left + right) / 2;
28 }
29 _streamIndex = mid;
30 }
31
32 CSubStreamInfo &s = Streams[_streamIndex];
33 UInt64 localPos = _pos - s.GlobalOffset;
34 if (localPos != s.LocalPos)
35 {
36 RINOK(s.Stream->Seek((Int64)localPos, STREAM_SEEK_SET, &s.LocalPos))
37 }
38 {
39 const UInt64 rem = s.Size - localPos;
40 if (size > rem)
41 size = (UInt32)rem;
42 }
43 const HRESULT result = s.Stream->Read(data, size, &size);
44 _pos += size;
45 s.LocalPos += size;
46 if (processedSize)
47 *processedSize = size;
48 return result;
49 }
50
Z7_COM7F_IMF(CMultiStream::Seek (Int64 offset,UInt32 seekOrigin,UInt64 * newPosition))51 Z7_COM7F_IMF(CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
52 {
53 switch (seekOrigin)
54 {
55 case STREAM_SEEK_SET: break;
56 case STREAM_SEEK_CUR: offset += _pos; break;
57 case STREAM_SEEK_END: offset += _totalLength; break;
58 default: return STG_E_INVALIDFUNCTION;
59 }
60 if (offset < 0)
61 return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
62 _pos = (UInt64)offset;
63 if (newPosition)
64 *newPosition = (UInt64)offset;
65 return S_OK;
66 }
67
68
69 /*
70 class COutVolumeStream:
71 public ISequentialOutStream,
72 public CMyUnknownImp
73 {
74 Z7_COM_UNKNOWN_IMP_0
75 Z7_IFACE_COM7_IMP(ISequentialOutStream)
76
77 unsigned _volIndex;
78 UInt64 _volSize;
79 UInt64 _curPos;
80 CMyComPtr<ISequentialOutStream> _volumeStream;
81 COutArchive _archive;
82 CCRC _crc;
83
84 public:
85 CFileItem _file;
86 CUpdateOptions _options;
87 CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
88 void Init(IArchiveUpdateCallback2 *volumeCallback,
89 const UString &name)
90 {
91 _file.Name = name;
92 _file.IsStartPosDefined = true;
93 _file.StartPos = 0;
94
95 VolumeCallback = volumeCallback;
96 _volIndex = 0;
97 _volSize = 0;
98 }
99
100 HRESULT Flush();
101 };
102
103 HRESULT COutVolumeStream::Flush()
104 {
105 if (_volumeStream)
106 {
107 _file.UnPackSize = _curPos;
108 _file.FileCRC = _crc.GetDigest();
109 RINOK(WriteVolumeHeader(_archive, _file, _options))
110 _archive.Close();
111 _volumeStream.Release();
112 _file.StartPos += _file.UnPackSize;
113 }
114 return S_OK;
115 }
116 */
117
118 /*
119
120 #include "../../../Common/Defs.h"
121
122 Z7_COM7F_IMF(COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
123 {
124 if (processedSize)
125 *processedSize = 0;
126 while (size > 0)
127 {
128 if (_streamIndex >= Streams.Size())
129 {
130 CSubStreamInfo subStream;
131 RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size))
132 RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream))
133 subStream.Pos = 0;
134 Streams.Add(subStream);
135 continue;
136 }
137 CSubStreamInfo &subStream = Streams[_streamIndex];
138 if (_offsetPos >= subStream.Size)
139 {
140 _offsetPos -= subStream.Size;
141 _streamIndex++;
142 continue;
143 }
144 if (_offsetPos != subStream.Pos)
145 {
146 CMyComPtr<IOutStream> outStream;
147 RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream))
148 RINOK(outStream->Seek((Int64)_offsetPos, STREAM_SEEK_SET, NULL))
149 subStream.Pos = _offsetPos;
150 }
151
152 const UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos);
153 UInt32 realProcessed;
154 RINOK(subStream.Stream->Write(data, curSize, &realProcessed))
155 data = (const void *)((const Byte *)data + realProcessed);
156 size -= realProcessed;
157 subStream.Pos += realProcessed;
158 _offsetPos += realProcessed;
159 _absPos += realProcessed;
160 if (_absPos > _length)
161 _length = _absPos;
162 if (processedSize)
163 *processedSize += realProcessed;
164 if (subStream.Pos == subStream.Size)
165 {
166 _streamIndex++;
167 _offsetPos = 0;
168 }
169 if (realProcessed != curSize && realProcessed == 0)
170 return E_FAIL;
171 }
172 return S_OK;
173 }
174
175 Z7_COM7F_IMF(COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
176 {
177 switch (seekOrigin)
178 {
179 case STREAM_SEEK_SET: break;
180 case STREAM_SEEK_CUR: offset += _absPos; break;
181 case STREAM_SEEK_END: offset += _length; break;
182 default: return STG_E_INVALIDFUNCTION;
183 }
184 if (offset < 0)
185 return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
186 _absPos = (UInt64)offset;
187 _offsetPos = _absPos;
188 _streamIndex = 0;
189 if (newPosition)
190 *newPosition = (UInt64)offset;
191 return S_OK;
192 }
193 */
194