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