| OLD | NEW |
| (Empty) |
| 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 *proce
ssedSize) | |
| 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 *newP
osition) | |
| 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 */ | |
| OLD | NEW |