1// LimitedStreams.h
2
3#ifndef __LIMITED_STREAMS_H
4#define __LIMITED_STREAMS_H
5
6#include "../../Common/MyCom.h"
7#include "../../Common/MyVector.h"
8#include "../IStream.h"
9
10class CLimitedSequentialInStream:
11  public ISequentialInStream,
12  public CMyUnknownImp
13{
14  CMyComPtr<ISequentialInStream> _stream;
15  UInt64 _size;
16  UInt64 _pos;
17  bool _wasFinished;
18public:
19  void SetStream(ISequentialInStream *stream) { _stream = stream; }
20  void ReleaseStream() { _stream.Release(); }
21  void Init(UInt64 streamSize)
22  {
23    _size = streamSize;
24    _pos = 0;
25    _wasFinished = false;
26  }
27
28  MY_UNKNOWN_IMP
29
30  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
31  UInt64 GetSize() const { return _pos; }
32  bool WasFinished() const { return _wasFinished; }
33};
34
35class CLimitedInStream:
36  public IInStream,
37  public CMyUnknownImp
38{
39  CMyComPtr<IInStream> _stream;
40  UInt64 _virtPos;
41  UInt64 _physPos;
42  UInt64 _size;
43  UInt64 _startOffset;
44
45  HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
46public:
47  void SetStream(IInStream *stream) { _stream = stream; }
48  HRESULT InitAndSeek(UInt64 startOffset, UInt64 size)
49  {
50    _startOffset = startOffset;
51    _physPos = startOffset;
52    _virtPos = 0;
53    _size = size;
54    return SeekToPhys();
55  }
56
57  MY_UNKNOWN_IMP1(IInStream)
58
59  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
60  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
61
62  HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); }
63};
64
65class CClusterInStream:
66  public IInStream,
67  public CMyUnknownImp
68{
69  UInt64 _virtPos;
70  UInt64 _physPos;
71  UInt32 _curRem;
72public:
73  CMyComPtr<IInStream> Stream;
74  UInt64 StartOffset;
75  UInt64 Size;
76  int BlockSizeLog;
77  CRecordVector<UInt32> Vector;
78
79  HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
80
81  HRESULT InitAndSeek()
82  {
83    _curRem = 0;
84    _virtPos = 0;
85    _physPos = StartOffset;
86    if (Vector.Size() > 0)
87    {
88      _physPos = StartOffset + (Vector[0] << BlockSizeLog);
89      return SeekToPhys();
90    }
91    return S_OK;
92  }
93
94  MY_UNKNOWN_IMP1(IInStream)
95
96  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
97  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
98};
99
100HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream);
101
102class CLimitedSequentialOutStream:
103  public ISequentialOutStream,
104  public CMyUnknownImp
105{
106  CMyComPtr<ISequentialOutStream> _stream;
107  UInt64 _size;
108  bool _overflow;
109  bool _overflowIsAllowed;
110public:
111  MY_UNKNOWN_IMP
112  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
113  void SetStream(ISequentialOutStream *stream) { _stream = stream; }
114  void ReleaseStream() { _stream.Release(); }
115  void Init(UInt64 size, bool overflowIsAllowed = false)
116  {
117    _size = size;
118    _overflow = false;
119    _overflowIsAllowed = overflowIsAllowed;
120  }
121  bool IsFinishedOK() const { return (_size == 0 && !_overflow); }
122  UInt64 GetRem() const { return _size; }
123};
124
125#endif
126