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