xref: /third_party/lzma/CPP/Common/MyCom.h (revision 370b324c)
1// MyCom.h
2
3#ifndef ZIP7_INC_MY_COM_H
4#define ZIP7_INC_MY_COM_H
5
6#include "MyWindows.h"
7#include "MyTypes.h"
8
9template <class T>
10class CMyComPtr
11{
12  T* _p;
13public:
14  CMyComPtr(): _p(NULL) {}
15  CMyComPtr(T* p) throw() { if ((_p = p) != NULL) p->AddRef(); }
16  CMyComPtr(const CMyComPtr<T>& lp) throw() { if ((_p = lp._p) != NULL) _p->AddRef(); }
17  ~CMyComPtr() { if (_p) _p->Release(); }
18  void Release() { if (_p) { _p->Release(); _p = NULL; } }
19  operator T*() const {  return (T*)_p;  }
20  // T& operator*() const {  return *_p; }
21  T** operator&() { return &_p; }
22  T* operator->() const { return _p; }
23  T* operator=(T* p)
24  {
25    if (p)
26      p->AddRef();
27    if (_p)
28      _p->Release();
29    _p = p;
30    return p;
31  }
32  T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
33  bool operator!() const { return (_p == NULL); }
34  // bool operator==(T* pT) const {  return _p == pT; }
35  void Attach(T* p2)
36  {
37    Release();
38    _p = p2;
39  }
40  T* Detach()
41  {
42    T* pt = _p;
43    _p = NULL;
44    return pt;
45  }
46  #ifdef _WIN32
47  HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
48  {
49    return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
50  }
51  #endif
52  /*
53  HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
54  {
55    CLSID clsid;
56    HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
57    ATLASSERT(_p == NULL);
58    if (SUCCEEDED(hr))
59      hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
60    return hr;
61  }
62  */
63  template <class Q>
64  HRESULT QueryInterface(REFGUID iid, Q** pp) const throw()
65  {
66    // if (*pp) throw 20220216; // for debug
67    return _p->QueryInterface(iid, (void**)pp);
68  }
69};
70
71#define Z7_DECL_CMyComPtr_QI_FROM(i, v, unk) \
72  CMyComPtr<i> v; (unk)->QueryInterface(IID_ ## i, (void **)&v);
73
74
75//////////////////////////////////////////////////////////
76
77inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr)
78{
79  *bstr = ::SysAllocString(src);
80  return (*bstr) ? S_OK : E_OUTOFMEMORY;
81}
82
83class CMyComBSTR
84{
85  BSTR m_str;
86  Z7_CLASS_NO_COPY(CMyComBSTR)
87public:
88  CMyComBSTR(): m_str(NULL) {}
89  ~CMyComBSTR() { ::SysFreeString(m_str); }
90  BSTR* operator&() { return &m_str; }
91  operator LPCOLESTR() const { return m_str; }
92  // operator bool() const { return m_str != NULL; }
93  // bool operator!() const { return m_str == NULL; }
94
95  void Wipe_and_Free()
96  {
97    if (m_str)
98    {
99      memset(m_str, 0, ::SysStringLen(m_str) * sizeof(*m_str));
100      Empty();
101    }
102  }
103
104private:
105  // operator BSTR() const { return m_str; }
106
107  CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); }
108  // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
109  // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize);  }
110  // CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
111
112  /*
113  CMyComBSTR(REFGUID src)
114  {
115    LPOLESTR szGuid;
116    StringFromCLSID(src, &szGuid);
117    m_str = ::SysAllocString(szGuid);
118    CoTaskMemFree(szGuid);
119  }
120  */
121
122  /*
123  CMyComBSTR& operator=(const CMyComBSTR& src)
124  {
125    if (m_str != src.m_str)
126    {
127      if (m_str)
128        ::SysFreeString(m_str);
129      m_str = src.MyCopy();
130    }
131    return *this;
132  }
133  */
134
135  CMyComBSTR& operator=(LPCOLESTR src)
136  {
137    ::SysFreeString(m_str);
138    m_str = ::SysAllocString(src);
139    return *this;
140  }
141
142  unsigned Len() const { return ::SysStringLen(m_str); }
143
144  BSTR MyCopy() const
145  {
146    // We don't support Byte BSTRs here
147    return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
148    /*
149    UINT byteLen = ::SysStringByteLen(m_str);
150    BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
151    if (res && byteLen != 0 && m_str)
152      memcpy(res, m_str, byteLen);
153    return res;
154    */
155  }
156
157  /*
158  void Attach(BSTR src) { m_str = src; }
159  BSTR Detach()
160  {
161    BSTR s = m_str;
162    m_str = NULL;
163    return s;
164  }
165  */
166
167  void Empty()
168  {
169    ::SysFreeString(m_str);
170    m_str = NULL;
171  }
172};
173
174
175class CMyComBSTR_Wipe: public CMyComBSTR
176{
177  Z7_CLASS_NO_COPY(CMyComBSTR_Wipe)
178public:
179  CMyComBSTR_Wipe(): CMyComBSTR() {}
180  ~CMyComBSTR_Wipe() { Wipe_and_Free(); }
181};
182
183
184
185/*
186  If CMyUnknownImp doesn't use virtual destructor, the code size is smaller.
187  But if some class_1 derived from CMyUnknownImp
188    uses Z7_COM_ADDREF_RELEASE and IUnknown::Release()
189    and some another class_2 is derived from class_1,
190    then class_1 must use virtual destructor:
191      virtual ~class_1();
192    In that case, class_1::Release() calls correct destructor of class_2.
193  We can use virtual ~CMyUnknownImp() to disable warning
194    "class has virtual functions, but destructor is not virtual".
195  Also we can use virtual ~IUnknown() {} in MyWindows.h
196*/
197
198class CMyUnknownImp
199{
200  Z7_CLASS_NO_COPY(CMyUnknownImp)
201protected:
202  ULONG _m_RefCount;
203  CMyUnknownImp(): _m_RefCount(0) {}
204
205  #ifdef _WIN32
206  #if defined(__GNUC__) || defined(__clang__)
207  // virtual ~CMyUnknownImp() {} // to disable GCC/CLANG varnings
208  #endif
209  #endif
210};
211
212
213
214#define Z7_COM_QI_BEGIN \
215  private: STDMETHOD(QueryInterface) (REFGUID iid, void **outObject) throw() Z7_override Z7_final \
216    { *outObject = NULL;
217
218#define Z7_COM_QI_ENTRY(i) \
219  else if (iid == IID_ ## i) \
220    { i *ti = this;  *outObject = ti; }
221//   { *outObject = (void *)(i *)this; }
222
223#define Z7_COM_QI_ENTRY_UNKNOWN_0 \
224  if (iid == IID_IUnknown) \
225    { IUnknown *tu = this;  *outObject = tu; }
226
227#define Z7_COM_QI_ENTRY_UNKNOWN(i) \
228  if (iid == IID_IUnknown) \
229    { i *ti = this;  IUnknown *tu = ti;  *outObject = tu; }
230//    { *outObject = (void *)(IUnknown *)(i *)this; }
231
232#define Z7_COM_QI_BEGIN2(i) \
233  Z7_COM_QI_BEGIN \
234  Z7_COM_QI_ENTRY_UNKNOWN(i) \
235  Z7_COM_QI_ENTRY(i)
236
237#define Z7_COM_QI_END \
238  else return E_NOINTERFACE; \
239  ++_m_RefCount; /* AddRef(); */ return S_OK; }
240
241#define Z7_COM_ADDREF_RELEASE \
242  private: \
243  STDMETHOD_(ULONG, AddRef)() throw() Z7_override Z7_final \
244    { return ++_m_RefCount; } \
245  STDMETHOD_(ULONG, Release)() throw() Z7_override Z7_final \
246    { if (--_m_RefCount != 0) return _m_RefCount;  delete this;  return 0; } \
247
248#define Z7_COM_UNKNOWN_IMP_SPEC(i) \
249  Z7_COM_QI_BEGIN \
250  i \
251  Z7_COM_QI_END \
252  Z7_COM_ADDREF_RELEASE
253
254
255#define Z7_COM_UNKNOWN_IMP_0 \
256  Z7_COM_QI_BEGIN \
257  Z7_COM_QI_ENTRY_UNKNOWN_0 \
258  Z7_COM_QI_END \
259  Z7_COM_ADDREF_RELEASE
260
261#define Z7_COM_UNKNOWN_IMP_1(i) \
262  Z7_COM_UNKNOWN_IMP_SPEC( \
263  Z7_COM_QI_ENTRY_UNKNOWN(i) \
264  Z7_COM_QI_ENTRY(i) \
265  )
266
267#define Z7_COM_UNKNOWN_IMP_2(i1, i2) \
268  Z7_COM_UNKNOWN_IMP_SPEC( \
269  Z7_COM_QI_ENTRY_UNKNOWN(i1) \
270  Z7_COM_QI_ENTRY(i1) \
271  Z7_COM_QI_ENTRY(i2) \
272  )
273
274#define Z7_COM_UNKNOWN_IMP_3(i1, i2, i3) \
275  Z7_COM_UNKNOWN_IMP_SPEC( \
276  Z7_COM_QI_ENTRY_UNKNOWN(i1) \
277  Z7_COM_QI_ENTRY(i1) \
278  Z7_COM_QI_ENTRY(i2) \
279  Z7_COM_QI_ENTRY(i3) \
280  )
281
282#define Z7_COM_UNKNOWN_IMP_4(i1, i2, i3, i4) \
283  Z7_COM_UNKNOWN_IMP_SPEC( \
284  Z7_COM_QI_ENTRY_UNKNOWN(i1) \
285  Z7_COM_QI_ENTRY(i1) \
286  Z7_COM_QI_ENTRY(i2) \
287  Z7_COM_QI_ENTRY(i3) \
288  Z7_COM_QI_ENTRY(i4) \
289  )
290
291#define Z7_COM_UNKNOWN_IMP_5(i1, i2, i3, i4, i5) \
292  Z7_COM_UNKNOWN_IMP_SPEC( \
293  Z7_COM_QI_ENTRY_UNKNOWN(i1) \
294  Z7_COM_QI_ENTRY(i1) \
295  Z7_COM_QI_ENTRY(i2) \
296  Z7_COM_QI_ENTRY(i3) \
297  Z7_COM_QI_ENTRY(i4) \
298  Z7_COM_QI_ENTRY(i5) \
299  )
300
301#define Z7_COM_UNKNOWN_IMP_6(i1, i2, i3, i4, i5, i6) \
302  Z7_COM_UNKNOWN_IMP_SPEC( \
303  Z7_COM_QI_ENTRY_UNKNOWN(i1) \
304  Z7_COM_QI_ENTRY(i1) \
305  Z7_COM_QI_ENTRY(i2) \
306  Z7_COM_QI_ENTRY(i3) \
307  Z7_COM_QI_ENTRY(i4) \
308  Z7_COM_QI_ENTRY(i5) \
309  Z7_COM_QI_ENTRY(i6) \
310  )
311
312#define Z7_COM_UNKNOWN_IMP_7(i1, i2, i3, i4, i5, i6, i7) \
313  Z7_COM_UNKNOWN_IMP_SPEC( \
314  Z7_COM_QI_ENTRY_UNKNOWN(i1) \
315  Z7_COM_QI_ENTRY(i1) \
316  Z7_COM_QI_ENTRY(i2) \
317  Z7_COM_QI_ENTRY(i3) \
318  Z7_COM_QI_ENTRY(i4) \
319  Z7_COM_QI_ENTRY(i5) \
320  Z7_COM_QI_ENTRY(i6) \
321  Z7_COM_QI_ENTRY(i7) \
322  )
323
324
325#define Z7_IFACES_IMP_UNK_1(i1) \
326  Z7_COM_UNKNOWN_IMP_1(i1) \
327  Z7_IFACE_COM7_IMP(i1) \
328
329#define Z7_IFACES_IMP_UNK_2(i1, i2) \
330  Z7_COM_UNKNOWN_IMP_2(i1, i2) \
331  Z7_IFACE_COM7_IMP(i1) \
332  Z7_IFACE_COM7_IMP(i2) \
333
334#define Z7_IFACES_IMP_UNK_3(i1, i2, i3) \
335  Z7_COM_UNKNOWN_IMP_3(i1, i2, i3) \
336  Z7_IFACE_COM7_IMP(i1) \
337  Z7_IFACE_COM7_IMP(i2) \
338  Z7_IFACE_COM7_IMP(i3) \
339
340#define Z7_IFACES_IMP_UNK_4(i1, i2, i3, i4) \
341  Z7_COM_UNKNOWN_IMP_4(i1, i2, i3, i4) \
342  Z7_IFACE_COM7_IMP(i1) \
343  Z7_IFACE_COM7_IMP(i2) \
344  Z7_IFACE_COM7_IMP(i3) \
345  Z7_IFACE_COM7_IMP(i4) \
346
347#define Z7_IFACES_IMP_UNK_5(i1, i2, i3, i4, i5) \
348  Z7_COM_UNKNOWN_IMP_5(i1, i2, i3, i4, i5) \
349  Z7_IFACE_COM7_IMP(i1) \
350  Z7_IFACE_COM7_IMP(i2) \
351  Z7_IFACE_COM7_IMP(i3) \
352  Z7_IFACE_COM7_IMP(i4) \
353  Z7_IFACE_COM7_IMP(i5) \
354
355#define Z7_IFACES_IMP_UNK_6(i1, i2, i3, i4, i5, i6) \
356  Z7_COM_UNKNOWN_IMP_6(i1, i2, i3, i4, i5, i6) \
357  Z7_IFACE_COM7_IMP(i1) \
358  Z7_IFACE_COM7_IMP(i2) \
359  Z7_IFACE_COM7_IMP(i3) \
360  Z7_IFACE_COM7_IMP(i4) \
361  Z7_IFACE_COM7_IMP(i5) \
362  Z7_IFACE_COM7_IMP(i6) \
363
364
365#define Z7_CLASS_IMP_COM_0(c) \
366  Z7_class_final(c) : \
367  public IUnknown, \
368  public CMyUnknownImp { \
369  Z7_COM_UNKNOWN_IMP_0 \
370  private:
371
372#define Z7_CLASS_IMP_COM_1(c, i1) \
373  Z7_class_final(c) : \
374  public i1, \
375  public CMyUnknownImp { \
376  Z7_IFACES_IMP_UNK_1(i1) \
377  private:
378
379#define Z7_CLASS_IMP_COM_2(c, i1, i2) \
380  Z7_class_final(c) : \
381  public i1, \
382  public i2, \
383  public CMyUnknownImp { \
384  Z7_IFACES_IMP_UNK_2(i1, i2) \
385  private:
386
387#define Z7_CLASS_IMP_COM_3(c, i1, i2, i3) \
388  Z7_class_final(c) : \
389  public i1, \
390  public i2, \
391  public i3, \
392  public CMyUnknownImp { \
393  Z7_IFACES_IMP_UNK_3(i1, i2, i3) \
394  private:
395
396#define Z7_CLASS_IMP_COM_4(c, i1, i2, i3, i4) \
397  Z7_class_final(c) : \
398  public i1, \
399  public i2, \
400  public i3, \
401  public i4, \
402  public CMyUnknownImp { \
403  Z7_IFACES_IMP_UNK_4(i1, i2, i3, i4) \
404  private:
405
406#define Z7_CLASS_IMP_COM_5(c, i1, i2, i3, i4, i5) \
407  Z7_class_final(c) : \
408  public i1, \
409  public i2, \
410  public i3, \
411  public i4, \
412  public i5, \
413  public CMyUnknownImp { \
414  Z7_IFACES_IMP_UNK_5(i1, i2, i3, i4, i5) \
415  private:
416
417#define Z7_CLASS_IMP_COM_6(c, i1, i2, i3, i4, i5, i6) \
418  Z7_class_final(c) : \
419  public i1, \
420  public i2, \
421  public i3, \
422  public i4, \
423  public i5, \
424  public i6, \
425  public CMyUnknownImp { \
426  Z7_IFACES_IMP_UNK_6(i1, i2, i3, i4, i5, i6) \
427  private:
428
429
430/*
431#define Z7_CLASS_IMP_NOQIB_0(c) \
432  Z7_class_final(c) : \
433  public IUnknown, \
434  public CMyUnknownImp { \
435  Z7_COM_UNKNOWN_IMP_0 \
436  private:
437*/
438
439#define Z7_CLASS_IMP_NOQIB_1(c, i1) \
440  Z7_class_final(c) : \
441  public i1, \
442  public CMyUnknownImp { \
443  Z7_COM_UNKNOWN_IMP_0 \
444  Z7_IFACE_COM7_IMP(i1) \
445  private:
446
447#define Z7_CLASS_IMP_NOQIB_2(c, i1, i2) \
448  Z7_class_final(c) : \
449  public i1, \
450  public i2, \
451  public CMyUnknownImp { \
452  Z7_COM_UNKNOWN_IMP_1(i2) \
453  Z7_IFACE_COM7_IMP(i1) \
454  Z7_IFACE_COM7_IMP(i2) \
455  private:
456
457#define Z7_CLASS_IMP_NOQIB_3(c, i1, i2, i3) \
458  Z7_class_final(c) : \
459  public i1, \
460  public i2, \
461  public i3, \
462  public CMyUnknownImp { \
463  Z7_COM_UNKNOWN_IMP_2(i2, i3) \
464  Z7_IFACE_COM7_IMP(i1) \
465  Z7_IFACE_COM7_IMP(i2) \
466  Z7_IFACE_COM7_IMP(i3) \
467  private:
468
469#define Z7_CLASS_IMP_NOQIB_4(c, i1, i2, i3, i4) \
470  Z7_class_final(c) : \
471  public i1, \
472  public i2, \
473  public i3, \
474  public i4, \
475  public CMyUnknownImp { \
476  Z7_COM_UNKNOWN_IMP_3(i2, i3, i4) \
477  Z7_IFACE_COM7_IMP(i1) \
478  Z7_IFACE_COM7_IMP(i2) \
479  Z7_IFACE_COM7_IMP(i3) \
480  Z7_IFACE_COM7_IMP(i4) \
481
482/*
483#define Z7_CLASS_IMP_NOQIB_5(c, i1, i2, i3, i4, i5) \
484  Z7_class_final(c) : \
485  public i1, \
486  public i2, \
487  public i3, \
488  public i4, \
489  public i5, \
490  public CMyUnknownImp { \
491  Z7_COM_UNKNOWN_IMP_4(i2, i3, i4, i5) \
492  Z7_IFACE_COM7_IMP(i1) \
493  Z7_IFACE_COM7_IMP(i2) \
494  Z7_IFACE_COM7_IMP(i3) \
495  Z7_IFACE_COM7_IMP(i4) \
496  Z7_IFACE_COM7_IMP(i5) \
497*/
498
499
500#define Z7_CLASS_IMP_IInStream(c) \
501  class c Z7_final : \
502  public IInStream, \
503  public CMyUnknownImp { \
504  Z7_IFACES_IMP_UNK_2(ISequentialInStream, IInStream) \
505
506
507#define k_My_HRESULT_WritingWasCut 0x20000010
508
509#endif
510