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