xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // EnumFormatEtc.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "EnumFormatEtc.h"
6 #include "../../IDecl.h"
7 #include "MyCom2.h"
8 
9 class CEnumFormatEtc Z7_final:
10   public IEnumFORMATETC,
11   public CMyUnknownImp
12 {
13   Z7_COM_UNKNOWN_IMP_1_MT(IEnumFORMATETC)
14 
15   STDMETHOD(Next)(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) Z7_override;
16   STDMETHOD(Skip)(ULONG celt) Z7_override;
17   STDMETHOD(Reset)(void) Z7_override;
18   STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc) Z7_override;
19 
20   LONG m_RefCount;
21   ULONG m_NumFormats;
22   FORMATETC *m_Formats;
23   ULONG m_Index;
24 public:
25   CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats);
26   ~CEnumFormatEtc();
27 };
28 
DeepCopyFormatEtc(FORMATETC * dest,const FORMATETC * src)29 static void DeepCopyFormatEtc(FORMATETC *dest, const FORMATETC *src)
30 {
31   *dest = *src;
32   if (src->ptd)
33   {
34     dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
35     *(dest->ptd) = *(src->ptd);
36   }
37 }
38 
CEnumFormatEtc(const FORMATETC * pFormatEtc,ULONG numFormats)39 CEnumFormatEtc::CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats)
40 {
41   m_RefCount = 1;
42   m_Index = 0;
43   m_NumFormats = 0;
44   m_Formats = new FORMATETC[numFormats];
45   // if (m_Formats)
46   {
47     m_NumFormats = numFormats;
48     for (ULONG i = 0; i < numFormats; i++)
49       DeepCopyFormatEtc(&m_Formats[i], &pFormatEtc[i]);
50   }
51 }
52 
~CEnumFormatEtc()53 CEnumFormatEtc::~CEnumFormatEtc()
54 {
55   if (m_Formats)
56   {
57     for (ULONG i = 0; i < m_NumFormats; i++)
58       if (m_Formats[i].ptd)
59         CoTaskMemFree(m_Formats[i].ptd);
60     delete []m_Formats;
61   }
62 }
63 
Next(ULONG celt,FORMATETC * pFormatEtc,ULONG * pceltFetched)64 Z7_COMWF_B CEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched)
65 {
66   ULONG copied  = 0;
67   if (celt == 0 || !pFormatEtc)
68     return E_INVALIDARG;
69   while (m_Index < m_NumFormats && copied < celt)
70   {
71     DeepCopyFormatEtc(&pFormatEtc[copied], &m_Formats[m_Index]);
72     copied++;
73     m_Index++;
74   }
75   if (pceltFetched)
76     *pceltFetched = copied;
77   return (copied == celt) ? S_OK : S_FALSE;
78 }
79 
Skip(ULONG celt)80 Z7_COMWF_B CEnumFormatEtc::Skip(ULONG celt)
81 {
82   m_Index += celt;
83   return (m_Index <= m_NumFormats) ? S_OK : S_FALSE;
84 }
85 
Reset(void)86 Z7_COMWF_B CEnumFormatEtc::Reset(void)
87 {
88   m_Index = 0;
89   return S_OK;
90 }
91 
Clone(IEnumFORMATETC ** ppEnumFormatEtc)92 Z7_COMWF_B CEnumFormatEtc::Clone(IEnumFORMATETC ** ppEnumFormatEtc)
93 {
94   HRESULT hResult = CreateEnumFormatEtc(m_NumFormats, m_Formats, ppEnumFormatEtc);
95   if (hResult == S_OK)
96     ((CEnumFormatEtc *)*ppEnumFormatEtc)->m_Index = m_Index;
97   return hResult;
98 }
99 
100 // replacement for SHCreateStdEnumFmtEtc
CreateEnumFormatEtc(UINT numFormats,const FORMATETC * formats,IEnumFORMATETC ** enumFormat)101 HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat)
102 {
103   if (numFormats == 0 || !formats || !enumFormat)
104     return E_INVALIDARG;
105   *enumFormat = new CEnumFormatEtc(formats, numFormats);
106   return (*enumFormat) ? S_OK : E_OUTOFMEMORY;
107 }
108