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   class C_Filter_Releaser
157   {
158   public:
159     CFilterCoder *FilterCoder;
C_Filter_Releaser()160     C_Filter_Releaser(): FilterCoder(NULL) {}
~C_Filter_Releaser()161     ~C_Filter_Releaser() { if (FilterCoder) FilterCoder->Filter.Release(); }
162   };
163 
164 
165   MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
166 
167     MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
168     MY_QUERYINTERFACE_ENTRY(ICompressInitEncoder)
169 
170     MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
171     MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
172 
173     MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream)
174     MY_QUERYINTERFACE_ENTRY(ISequentialOutStream)
175     MY_QUERYINTERFACE_ENTRY(IOutStreamFinish)
176 
177     MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize)
178 
179     #ifndef _NO_CRYPTO
180     MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _SetPassword)
181     MY_QUERYINTERFACE_ENTRY_AG(ICryptoProperties, Filter, _CryptoProperties)
182     #endif
183 
184     #ifndef EXTRACT_ONLY
185     MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties)
186     MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _WriteCoderProperties)
187     // MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt)
188     MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector)
189     #endif
190 
191     MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _SetDecoderProperties2)
192   MY_QUERYINTERFACE_END
193   MY_ADDREF_RELEASE
194 
195 
196   STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
197       const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
198 
199   STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
200   STDMETHOD(InitEncoder)();
201 
202   STDMETHOD(SetInStream)(ISequentialInStream *inStream);
203   STDMETHOD(ReleaseInStream)();
204   STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
205 
206   STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
207   STDMETHOD(ReleaseOutStream)();
208   STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
209   STDMETHOD(OutStreamFinish)();
210 
211   STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
212   STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
213 
214   #ifndef _NO_CRYPTO
215   STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
216 
217   STDMETHOD(SetKey)(const Byte *data, UInt32 size);
218   STDMETHOD(SetInitVector)(const Byte *data, UInt32 size);
219   #endif
220 
221   #ifndef EXTRACT_ONLY
222   STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
223       const PROPVARIANT *properties, UInt32 numProperties);
224   STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
225   // STDMETHOD(ResetSalt)();
226   STDMETHOD(ResetInitVector)();
227   #endif
228 
229   STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
230 
231 
232   HRESULT Init_NoSubFilterInit();
233 };
234 
235 #endif
236