misc/libphysfs/lzma/CPP/7zip/Archive/Common/MultiStream.cpp
changeset 13904 99b265e0d1d0
parent 13903 5f819b90d479
child 13905 b172a5d40eee
equal deleted inserted replaced
13903:5f819b90d479 13904:99b265e0d1d0
     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 */