view 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
line wrap: on
line source
1 // MultiStream.cpp
3 #include "StdAfx.h"
5 #include "MultiStream.h"
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 }
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 }
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;
90 public:
91 MY_UNKNOWN_IMP
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;
103 VolumeCallback = volumeCallback;
104 _volIndex = 0;
105 _volSize = 0;
106 }
108 HRESULT Flush();
109 STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
110 };
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 */
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 }
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 }
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 */