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