diff 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 diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Archive/Common/MultiStream.cpp	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,201 @@
     1.4 +// MultiStream.cpp
     1.5 +
     1.6 +#include "StdAfx.h"
     1.7 +
     1.8 +#include "MultiStream.h"
     1.9 +
    1.10 +STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
    1.11 +{
    1.12 +  if(processedSize != NULL)
    1.13 +    *processedSize = 0;
    1.14 +  while(_streamIndex < Streams.Size() && size > 0)
    1.15 +  {
    1.16 +    CSubStreamInfo &s = Streams[_streamIndex];
    1.17 +    if (_pos == s.Size)
    1.18 +    {
    1.19 +      _streamIndex++;
    1.20 +      _pos = 0;
    1.21 +      continue;
    1.22 +    }
    1.23 +    RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0));
    1.24 +    UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos));
    1.25 +    UInt32 realProcessed;
    1.26 +    HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed);
    1.27 +    data = (void *)((Byte *)data + realProcessed);
    1.28 +    size -= realProcessed;
    1.29 +    if(processedSize != NULL)
    1.30 +      *processedSize += realProcessed;
    1.31 +    _pos += realProcessed;
    1.32 +    _seekPos += realProcessed;
    1.33 +    RINOK(result);
    1.34 +    break;
    1.35 +  }
    1.36 +  return S_OK;
    1.37 +}
    1.38 +  
    1.39 +STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
    1.40 +    UInt64 *newPosition)
    1.41 +{
    1.42 +  UInt64 newPos;
    1.43 +  switch(seekOrigin)
    1.44 +  {
    1.45 +    case STREAM_SEEK_SET:
    1.46 +      newPos = offset;
    1.47 +      break;
    1.48 +    case STREAM_SEEK_CUR:
    1.49 +      newPos = _seekPos + offset;
    1.50 +      break;
    1.51 +    case STREAM_SEEK_END:
    1.52 +      newPos = _totalLength + offset;
    1.53 +      break;
    1.54 +    default:
    1.55 +      return STG_E_INVALIDFUNCTION;
    1.56 +  }
    1.57 +  _seekPos = 0;
    1.58 +  for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++)
    1.59 +  {
    1.60 +    UInt64 size = Streams[_streamIndex].Size;
    1.61 +    if (newPos < _seekPos + size)
    1.62 +    {
    1.63 +      _pos = newPos - _seekPos;
    1.64 +      _seekPos += _pos;
    1.65 +      if (newPosition != 0)
    1.66 +        *newPosition = newPos;
    1.67 +      return S_OK;
    1.68 +    }
    1.69 +    _seekPos += size;
    1.70 +  }
    1.71 +  if (newPos == _seekPos)
    1.72 +  {
    1.73 +    if (newPosition != 0)
    1.74 +      *newPosition = newPos;
    1.75 +    return S_OK;
    1.76 +  }
    1.77 +  return E_FAIL;
    1.78 +}
    1.79 +
    1.80 +
    1.81 +/*
    1.82 +class COutVolumeStream:
    1.83 +  public ISequentialOutStream,
    1.84 +  public CMyUnknownImp
    1.85 +{
    1.86 +  int _volIndex;
    1.87 +  UInt64 _volSize;
    1.88 +  UInt64 _curPos;
    1.89 +  CMyComPtr<ISequentialOutStream> _volumeStream;
    1.90 +  COutArchive _archive;
    1.91 +  CCRC _crc;
    1.92 +
    1.93 +public:
    1.94 +  MY_UNKNOWN_IMP
    1.95 +
    1.96 +  CFileItem _file;
    1.97 +  CUpdateOptions _options;
    1.98 +  CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
    1.99 +  void Init(IArchiveUpdateCallback2 *volumeCallback,
   1.100 +      const UString &name)
   1.101 +  {
   1.102 +    _file.Name = name;
   1.103 +    _file.IsStartPosDefined = true;
   1.104 +    _file.StartPos = 0;
   1.105 +    
   1.106 +    VolumeCallback = volumeCallback;
   1.107 +    _volIndex = 0;
   1.108 +    _volSize = 0;
   1.109 +  }
   1.110 +  
   1.111 +  HRESULT Flush();
   1.112 +  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
   1.113 +};
   1.114 +
   1.115 +HRESULT COutVolumeStream::Flush()
   1.116 +{
   1.117 +  if (_volumeStream)
   1.118 +  {
   1.119 +    _file.UnPackSize = _curPos;
   1.120 +    _file.FileCRC = _crc.GetDigest();
   1.121 +    RINOK(WriteVolumeHeader(_archive, _file, _options));
   1.122 +    _archive.Close();
   1.123 +    _volumeStream.Release();
   1.124 +    _file.StartPos += _file.UnPackSize;
   1.125 +  }
   1.126 +  return S_OK;
   1.127 +}
   1.128 +*/
   1.129 +
   1.130 +/*
   1.131 +STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
   1.132 +{
   1.133 +  if(processedSize != NULL)
   1.134 +    *processedSize = 0;
   1.135 +  while(size > 0)
   1.136 +  {
   1.137 +    if (_streamIndex >= Streams.Size())
   1.138 +    {
   1.139 +      CSubStreamInfo subStream;
   1.140 +      RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size));
   1.141 +      RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream));
   1.142 +      subStream.Pos = 0;
   1.143 +      Streams.Add(subStream);
   1.144 +      continue;
   1.145 +    }
   1.146 +    CSubStreamInfo &subStream = Streams[_streamIndex];
   1.147 +    if (_offsetPos >= subStream.Size)
   1.148 +    {
   1.149 +      _offsetPos -= subStream.Size;
   1.150 +      _streamIndex++;
   1.151 +      continue;
   1.152 +    }
   1.153 +    if (_offsetPos != subStream.Pos)
   1.154 +    {
   1.155 +      CMyComPtr<IOutStream> outStream;
   1.156 +      RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
   1.157 +      RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
   1.158 +      subStream.Pos = _offsetPos;
   1.159 +    }
   1.160 +
   1.161 +    UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos);
   1.162 +    UInt32 realProcessed;
   1.163 +    RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
   1.164 +    data = (void *)((Byte *)data + realProcessed);
   1.165 +    size -= realProcessed;
   1.166 +    subStream.Pos += realProcessed;
   1.167 +    _offsetPos += realProcessed;
   1.168 +    _absPos += realProcessed;
   1.169 +    if (_absPos > _length)
   1.170 +      _length = _absPos;
   1.171 +    if(processedSize != NULL)
   1.172 +      *processedSize += realProcessed;
   1.173 +    if (subStream.Pos == subStream.Size)
   1.174 +    {
   1.175 +      _streamIndex++;
   1.176 +      _offsetPos = 0;
   1.177 +    }
   1.178 +    if (realProcessed != curSize && realProcessed == 0)
   1.179 +      return E_FAIL;
   1.180 +  }
   1.181 +  return S_OK;
   1.182 +}
   1.183 +
   1.184 +STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
   1.185 +{
   1.186 +  if(seekOrigin >= 3)
   1.187 +    return STG_E_INVALIDFUNCTION;
   1.188 +  switch(seekOrigin)
   1.189 +  {
   1.190 +    case STREAM_SEEK_SET:
   1.191 +      _absPos = offset;
   1.192 +      break;
   1.193 +    case STREAM_SEEK_CUR:
   1.194 +      _absPos += offset;
   1.195 +      break;
   1.196 +    case STREAM_SEEK_END:
   1.197 +      _absPos = _length + offset;
   1.198 +      break;
   1.199 +  }
   1.200 +  _offsetPos = _absPos;
   1.201 +  _streamIndex = 0;
   1.202 +  return S_OK;
   1.203 +}
   1.204 +*/