Home | History | Annotate | Download | only in Common
      1 // LimitedStreams.h
      2 
      3 #ifndef __LIMITED_STREAMS_H
      4 #define __LIMITED_STREAMS_H
      5 
      6 #include "../../Common/MyBuffer.h"
      7 #include "../../Common/MyCom.h"
      8 #include "../../Common/MyVector.h"
      9 #include "../IStream.h"
     10 
     11 class CLimitedSequentialInStream:
     12   public ISequentialInStream,
     13   public CMyUnknownImp
     14 {
     15   CMyComPtr<ISequentialInStream> _stream;
     16   UInt64 _size;
     17   UInt64 _pos;
     18   bool _wasFinished;
     19 public:
     20   void SetStream(ISequentialInStream *stream) { _stream = stream; }
     21   void ReleaseStream() { _stream.Release(); }
     22   void Init(UInt64 streamSize)
     23   {
     24     _size = streamSize;
     25     _pos = 0;
     26     _wasFinished = false;
     27   }
     28 
     29   MY_UNKNOWN_IMP1(ISequentialInStream)
     30 
     31   STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
     32   UInt64 GetSize() const { return _pos; }
     33   UInt64 GetRem() const { return _size - _pos; }
     34   bool WasFinished() const { return _wasFinished; }
     35 };
     36 
     37 class CLimitedInStream:
     38   public IInStream,
     39   public CMyUnknownImp
     40 {
     41   CMyComPtr<IInStream> _stream;
     42   UInt64 _virtPos;
     43   UInt64 _physPos;
     44   UInt64 _size;
     45   UInt64 _startOffset;
     46 
     47   HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
     48 public:
     49   void SetStream(IInStream *stream) { _stream = stream; }
     50   HRESULT InitAndSeek(UInt64 startOffset, UInt64 size)
     51   {
     52     _startOffset = startOffset;
     53     _physPos = startOffset;
     54     _virtPos = 0;
     55     _size = size;
     56     return SeekToPhys();
     57   }
     58 
     59   MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
     60 
     61   STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
     62   STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
     63 
     64   HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); }
     65 };
     66 
     67 HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream);
     68 
     69 class CClusterInStream:
     70   public IInStream,
     71   public CMyUnknownImp
     72 {
     73   UInt64 _virtPos;
     74   UInt64 _physPos;
     75   UInt32 _curRem;
     76 public:
     77   unsigned BlockSizeLog;
     78   UInt64 Size;
     79   CMyComPtr<IInStream> Stream;
     80   CRecordVector<UInt32> Vector;
     81   UInt64 StartOffset;
     82 
     83   HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
     84 
     85   HRESULT InitAndSeek()
     86   {
     87     _curRem = 0;
     88     _virtPos = 0;
     89     _physPos = StartOffset;
     90     if (Vector.Size() > 0)
     91     {
     92       _physPos = StartOffset + (Vector[0] << BlockSizeLog);
     93       return SeekToPhys();
     94     }
     95     return S_OK;
     96   }
     97 
     98   MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
     99 
    100   STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
    101   STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
    102 };
    103 
    104 struct CSeekExtent
    105 {
    106   UInt64 Phy;
    107   UInt64 Virt;
    108 };
    109 
    110 class CExtentsStream:
    111   public IInStream,
    112   public CMyUnknownImp
    113 {
    114   UInt64 _phyPos;
    115   UInt64 _virtPos;
    116   bool _needStartSeek;
    117 
    118   HRESULT SeekToPhys() { return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); }
    119 
    120 public:
    121   CMyComPtr<IInStream> Stream;
    122   CRecordVector<CSeekExtent> Extents;
    123 
    124   MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
    125   STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
    126   STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
    127   void ReleaseStream() { Stream.Release(); }
    128 
    129   void Init()
    130   {
    131     _virtPos = 0;
    132     _phyPos = 0;
    133     _needStartSeek = true;
    134   }
    135 };
    136 
    137 class CLimitedSequentialOutStream:
    138   public ISequentialOutStream,
    139   public CMyUnknownImp
    140 {
    141   CMyComPtr<ISequentialOutStream> _stream;
    142   UInt64 _size;
    143   bool _overflow;
    144   bool _overflowIsAllowed;
    145 public:
    146   MY_UNKNOWN_IMP1(ISequentialOutStream)
    147   STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
    148   void SetStream(ISequentialOutStream *stream) { _stream = stream; }
    149   void ReleaseStream() { _stream.Release(); }
    150   void Init(UInt64 size, bool overflowIsAllowed = false)
    151   {
    152     _size = size;
    153     _overflow = false;
    154     _overflowIsAllowed = overflowIsAllowed;
    155   }
    156   bool IsFinishedOK() const { return (_size == 0 && !_overflow); }
    157   UInt64 GetRem() const { return _size; }
    158 };
    159 
    160 
    161 class CTailInStream:
    162   public IInStream,
    163   public CMyUnknownImp
    164 {
    165   UInt64 _virtPos;
    166 public:
    167   CMyComPtr<IInStream> Stream;
    168   UInt64 Offset;
    169 
    170   void Init()
    171   {
    172     _virtPos = 0;
    173   }
    174 
    175   MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
    176 
    177   STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
    178   STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
    179 
    180   HRESULT SeekToStart() { return Stream->Seek(Offset, STREAM_SEEK_SET, NULL); }
    181 };
    182 
    183 class CLimitedCachedInStream:
    184   public IInStream,
    185   public CMyUnknownImp
    186 {
    187   CMyComPtr<IInStream> _stream;
    188   UInt64 _virtPos;
    189   UInt64 _physPos;
    190   UInt64 _size;
    191   UInt64 _startOffset;
    192 
    193   const Byte *_cache;
    194   size_t _cacheSize;
    195   size_t _cachePhyPos;
    196 
    197 
    198   HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
    199 public:
    200   CByteBuffer Buffer;
    201 
    202   void SetStream(IInStream *stream) { _stream = stream; }
    203   void SetCache(size_t cacheSize, size_t cachePos)
    204   {
    205     _cache = Buffer;
    206     _cacheSize = cacheSize;
    207     _cachePhyPos = cachePos;
    208   }
    209 
    210   HRESULT InitAndSeek(UInt64 startOffset, UInt64 size)
    211   {
    212     _startOffset = startOffset;
    213     _physPos = startOffset;
    214     _virtPos = 0;
    215     _size = size;
    216     return SeekToPhys();
    217   }
    218 
    219   MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)
    220 
    221   STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
    222   STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
    223 
    224   HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); }
    225 };
    226 
    227 class CTailOutStream:
    228   public IOutStream,
    229   public CMyUnknownImp
    230 {
    231   UInt64 _virtPos;
    232   UInt64 _virtSize;
    233 public:
    234   CMyComPtr<IOutStream> Stream;
    235   UInt64 Offset;
    236 
    237   virtual ~CTailOutStream() {}
    238 
    239   MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStream)
    240 
    241   void Init()
    242   {
    243     _virtPos = 0;
    244     _virtSize = 0;
    245   }
    246 
    247   STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
    248   STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
    249   STDMETHOD(SetSize)(UInt64 newSize);
    250 };
    251 
    252 #endif
    253