1 // FilterCoder.h
2 
3 #ifndef __FILTER_CODER_H
4 #define __FILTER_CODER_H
5 
6 #include "../../../C/Alloc.h"
7 
8 #include "../../Common/MyCom.h"
9 #include "../ICoder.h"
10 
11 #ifndef _NO_CRYPTO
12 #include "../IPassword.h"
13 #endif
14 
15 #define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) else if (iid == IID_ ## i) \
16   { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
17     *outObject = (void *)(i *)this; }
18 
19 
20 struct CAlignedMidBuffer
21 {
22   #ifdef _WIN32
23 
24   Byte *_buf;
25 
CAlignedMidBufferCAlignedMidBuffer26   CAlignedMidBuffer(): _buf(NULL) {}
~CAlignedMidBufferCAlignedMidBuffer27   ~CAlignedMidBuffer() { ::MidFree(_buf); }
28 
AllocAlignedMaskCAlignedMidBuffer29   void AllocAlignedMask(size_t size, size_t)
30   {
31     ::MidFree(_buf);
32     _buf = (Byte *)::MidAlloc(size);
33   }
34 
35   #else
36 
37   Byte *_bufBase;
38   Byte *_buf;
39 
40   CAlignedMidBuffer(): _bufBase(NULL), _buf(NULL) {}
41   ~CAlignedMidBuffer() { ::MidFree(_bufBase); }
42 
43   void AllocAlignedMask(size_t size, size_t alignMask)
44   {
45     ::MidFree(_bufBase);
46     _buf = NULL;
47     _bufBase = (Byte *)::MidAlloc(size + alignMask);
48 
49     if (_bufBase)
50     {
51       // _buf = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask);
52          _buf = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask);
53     }
54   }
55 
56   #endif
57 };
58 
59 class CFilterCoder:
60   public ICompressCoder,
61 
62   public ICompressSetOutStreamSize,
63   public ICompressInitEncoder,
64 
65   public ICompressSetInStream,
66   public ISequentialInStream,
67 
68   public ICompressSetOutStream,
69   public ISequentialOutStream,
70   public IOutStreamFinish,
71 
72   public ICompressSetBufSize,
73 
74   #ifndef _NO_CRYPTO
75   public ICryptoSetPassword,
76   public ICryptoProperties,
77   #endif
78 
79   #ifndef EXTRACT_ONLY
80   public ICompressSetCoderProperties,
81   public ICompressWriteCoderProperties,
82   // public ICryptoResetSalt,
83   public ICryptoResetInitVector,
84   #endif
85 
86   public ICompressSetDecoderProperties2,
87   public CMyUnknownImp,
88   public CAlignedMidBuffer
89 {
90   UInt32 _bufSize;
91   UInt32 _inBufSize;
92   UInt32 _outBufSize;
93 
94   bool _encodeMode;
95   bool _outSizeIsDefined;
96   UInt64 _outSize;
97   UInt64 _nowPos64;
98 
99   CMyComPtr<ISequentialInStream> _inStream;
100   CMyComPtr<ISequentialOutStream> _outStream;
101   UInt32 _bufPos;
102   UInt32 _convPos;    // current pos in buffer for converted data
103   UInt32 _convSize;   // size of converted data starting from _convPos
104 
InitSpecVars()105   void InitSpecVars()
106   {
107     _bufPos = 0;
108     _convPos = 0;
109     _convSize = 0;
110 
111     _outSizeIsDefined = false;
112     _outSize = 0;
113     _nowPos64 = 0;
114   }
115 
116   HRESULT Alloc();
117   HRESULT Init_and_Alloc();
118   HRESULT Flush2();
119 
120   #ifndef _NO_CRYPTO
121   CMyComPtr<ICryptoSetPassword> _SetPassword;
122   CMyComPtr<ICryptoProperties> _CryptoProperties;
123   #endif
124 
125   #ifndef EXTRACT_ONLY
126   CMyComPtr<ICompressSetCoderProperties> _SetCoderProperties;
127   CMyComPtr<ICompressWriteCoderProperties> _WriteCoderProperties;
128   // CMyComPtr<ICryptoResetSalt> _CryptoResetSalt;
129   CMyComPtr<ICryptoResetInitVector> _CryptoResetInitVector;
130   #endif
131 
132   CMyComPtr<ICompressSetDecoderProperties2> _SetDecoderProperties2;
133 
134 public:
135   CMyComPtr<ICompressFilter> Filter;
136 
137   CFilterCoder(bool encodeMode);
138   ~CFilterCoder();
139 
140   class C_InStream_Releaser
141   {
142   public:
143     CFilterCoder *FilterCoder;
C_InStream_Releaser()144     C_InStream_Releaser(): FilterCoder(NULL) {}
~C_InStream_Releaser()145     ~C_InStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); }
146   };
147 
148   class C_OutStream_Releaser
149   {
150   public:
151     CFilterCoder *FilterCoder;
C_OutStream_Releaser()152     C_OutStream_Releaser(): FilterCoder(NULL) {}
~C_OutStream_Releaser()153     ~C_OutStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); }
154   };
155 
156   MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
157 
158     MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
159     MY_QUERYINTERFACE_ENTRY(ICompressInitEncoder)
160 
161     MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
162     MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
163 
164     MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream)
165     MY_QUERYINTERFACE_ENTRY(ISequentialOutStream)
166     MY_QUERYINTERFACE_ENTRY(IOutStreamFinish)
167 
168     MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize)
169 
170     #ifndef _NO_CRYPTO
171     MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _SetPassword)
172     MY_QUERYINTERFACE_ENTRY_AG(ICryptoProperties, Filter, _CryptoProperties)
173     #endif
174 
175     #ifndef EXTRACT_ONLY
176     MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties)
177     MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _WriteCoderProperties)
178     // MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt)
179     MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector)
180     #endif
181 
182     MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _SetDecoderProperties2)
183   MY_QUERYINTERFACE_END
184   MY_ADDREF_RELEASE
185 
186 
187   STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
188       const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
189 
190   STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
191   STDMETHOD(InitEncoder)();
192 
193   STDMETHOD(SetInStream)(ISequentialInStream *inStream);
194   STDMETHOD(ReleaseInStream)();
195   STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
196 
197   STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
198   STDMETHOD(ReleaseOutStream)();
199   STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
200   STDMETHOD(OutStreamFinish)();
201 
202   STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
203   STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
204 
205   #ifndef _NO_CRYPTO
206   STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
207 
208   STDMETHOD(SetKey)(const Byte *data, UInt32 size);
209   STDMETHOD(SetInitVector)(const Byte *data, UInt32 size);
210   #endif
211 
212   #ifndef EXTRACT_ONLY
213   STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
214       const PROPVARIANT *properties, UInt32 numProperties);
215   STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
216   // STDMETHOD(ResetSalt)();
217   STDMETHOD(ResetInitVector)();
218   #endif
219 
220   STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
221 
222 
223   HRESULT Init_NoSubFilterInit();
224 };
225 
226 #endif
227