Support unrar64.dll
[xy_vsfilter.git] / src / dsutil / DSMPropertyBag.cpp
blob3e8f9799798a156b2b5e26fd5e7854c35547ac7a
1 #include "StdAfx.h"
2 #include "DSUtil.h"
3 #include "DSMPropertyBag.h"
5 //
6 // IDSMPropertyBagImpl
7 //
9 IDSMPropertyBagImpl::IDSMPropertyBagImpl()
13 IDSMPropertyBagImpl::~IDSMPropertyBagImpl()
17 // IPropertyBag
19 STDMETHODIMP IDSMPropertyBagImpl::Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog* pErrorLog)
21 CheckPointer(pVar, E_POINTER);
22 if(pVar->vt != VT_EMPTY) return E_INVALIDARG;
23 CStringW value = Lookup(pszPropName);
24 if(value.IsEmpty()) return E_FAIL;
25 CComVariant(value).Detach(pVar);
26 return S_OK;
29 STDMETHODIMP IDSMPropertyBagImpl::Write(LPCOLESTR pszPropName, VARIANT* pVar)
31 return SetProperty(pszPropName, pVar);
34 // IPropertyBag2
36 STDMETHODIMP IDSMPropertyBagImpl::Read(ULONG cProperties, PROPBAG2* pPropBag, IErrorLog* pErrLog, VARIANT* pvarValue, HRESULT* phrError)
38 CheckPointer(pPropBag, E_POINTER);
39 CheckPointer(pvarValue, E_POINTER);
40 CheckPointer(phrError, E_POINTER);
41 for(ULONG i = 0; i < cProperties; phrError[i] = S_OK, i++)
42 CComVariant(Lookup(pPropBag[i].pstrName)).Detach(pvarValue);
43 return S_OK;
46 STDMETHODIMP IDSMPropertyBagImpl::Write(ULONG cProperties, PROPBAG2* pPropBag, VARIANT* pvarValue)
48 CheckPointer(pPropBag, E_POINTER);
49 CheckPointer(pvarValue, E_POINTER);
50 for(ULONG i = 0; i < cProperties; i++)
51 SetProperty(pPropBag[i].pstrName, &pvarValue[i]);
52 return S_OK;
55 STDMETHODIMP IDSMPropertyBagImpl::CountProperties(ULONG* pcProperties)
57 CheckPointer(pcProperties, E_POINTER);
58 *pcProperties = GetSize();
59 return S_OK;
62 STDMETHODIMP IDSMPropertyBagImpl::GetPropertyInfo(ULONG iProperty, ULONG cProperties, PROPBAG2* pPropBag, ULONG* pcProperties)
64 CheckPointer(pPropBag, E_POINTER);
65 CheckPointer(pcProperties, E_POINTER);
66 for(ULONG i = 0; i < cProperties; i++, iProperty++, (*pcProperties)++)
68 CStringW key = GetKeyAt(iProperty);
69 pPropBag[i].pstrName = (BSTR)CoTaskMemAlloc((key.GetLength()+1)*sizeof(WCHAR));
70 if(!pPropBag[i].pstrName) return E_FAIL;
71 wcscpy(pPropBag[i].pstrName, key);
73 return S_OK;
76 STDMETHODIMP IDSMPropertyBagImpl::LoadObject(LPCOLESTR pstrName, DWORD dwHint, IUnknown* pUnkObject, IErrorLog* pErrLog)
78 return E_NOTIMPL;
81 // IDSMProperyBag
83 HRESULT IDSMPropertyBagImpl::SetProperty(LPCWSTR key, LPCWSTR value)
85 CheckPointer(key, E_POINTER);
86 CheckPointer(value, E_POINTER);
87 if(!Lookup(key).IsEmpty()) SetAt(key, value);
88 else Add(key, value);
89 return S_OK;
92 HRESULT IDSMPropertyBagImpl::SetProperty(LPCWSTR key, VARIANT* var)
94 CheckPointer(key, E_POINTER);
95 CheckPointer(var, E_POINTER);
96 if((var->vt & (VT_BSTR | VT_BYREF)) != VT_BSTR) return E_INVALIDARG;
97 return SetProperty(key, var->bstrVal);
100 HRESULT IDSMPropertyBagImpl::GetProperty(LPCWSTR key, BSTR* value)
102 CheckPointer(key, E_POINTER);
103 CheckPointer(value, E_POINTER);
104 int i = FindKey(key);
105 if(i < 0) return E_FAIL;
106 *value = GetValueAt(i).AllocSysString();
107 return S_OK;
110 HRESULT IDSMPropertyBagImpl::DelAllProperties()
112 RemoveAll();
113 return S_OK;
116 HRESULT IDSMPropertyBagImpl::DelProperty(LPCWSTR key)
118 return Remove(key) ? S_OK : S_FALSE;
122 // CDSMResource
125 CCritSec CDSMResource::m_csResources;
126 CAtlMap<DWORD, CDSMResource*> CDSMResource::m_resources;
128 CDSMResource::CDSMResource()
129 : mime(_T("application/octet-stream"))
130 , tag(0)
132 CAutoLock cAutoLock(&m_csResources);
133 m_resources.SetAt((DWORD)this, this);
136 CDSMResource::CDSMResource(const CDSMResource& r)
138 *this = r;
140 CAutoLock cAutoLock(&m_csResources);
141 m_resources.SetAt((DWORD)this, this);
144 CDSMResource::CDSMResource(LPCWSTR name, LPCWSTR desc, LPCWSTR mime, BYTE* pData, int len, DWORD_PTR tag)
146 this->name = name;
147 this->desc = desc;
148 this->mime = mime;
149 data.SetCount(len);
150 memcpy(data.GetData(), pData, data.GetCount());
151 this->tag = tag;
153 CAutoLock cAutoLock(&m_csResources);
154 m_resources.SetAt((DWORD)this, this);
157 CDSMResource::~CDSMResource()
159 CAutoLock cAutoLock(&m_csResources);
160 m_resources.RemoveKey((DWORD)this);
163 void CDSMResource::operator = (const CDSMResource& r)
165 tag = r.tag;
166 name = r.name;
167 desc = r.desc;
168 mime = r.mime;
169 data.Copy(r.data);
173 // IDSMResourceBagImpl
176 IDSMResourceBagImpl::IDSMResourceBagImpl()
180 // IDSMResourceBag
182 STDMETHODIMP_(DWORD) IDSMResourceBagImpl::ResGetCount()
184 return m_resources.GetCount();
187 STDMETHODIMP IDSMResourceBagImpl::ResGet(DWORD iIndex, BSTR* ppName, BSTR* ppDesc, BSTR* ppMime, BYTE** ppData, DWORD* pDataLen, DWORD_PTR* pTag)
189 if(ppData) CheckPointer(pDataLen, E_POINTER);
191 if((INT_PTR)iIndex >= m_resources.GetCount())
192 return E_INVALIDARG;
194 CDSMResource& r = m_resources[iIndex];
196 if(ppName) *ppName = r.name.AllocSysString();
197 if(ppDesc) *ppDesc = r.desc.AllocSysString();
198 if(ppMime) *ppMime = r.mime.AllocSysString();
199 if(ppData) {*pDataLen = r.data.GetCount(); memcpy(*ppData = (BYTE*)CoTaskMemAlloc(*pDataLen), r.data.GetData(), *pDataLen);}
200 if(pTag) *pTag = r.tag;
202 return S_OK;
205 STDMETHODIMP IDSMResourceBagImpl::ResSet(DWORD iIndex, LPCWSTR pName, LPCWSTR pDesc, LPCWSTR pMime, BYTE* pData, DWORD len, DWORD_PTR tag)
207 if((INT_PTR)iIndex >= m_resources.GetCount())
208 return E_INVALIDARG;
210 CDSMResource& r = m_resources[iIndex];
212 if(pName) r.name = pName;
213 if(pDesc) r.desc = pDesc;
214 if(pMime) r.mime = pMime;
215 if(pData || len == 0) {r.data.SetCount(len); if(pData) memcpy(r.data.GetData(), pData, r.data.GetCount());}
216 r.tag = tag;
218 return S_OK;
221 STDMETHODIMP IDSMResourceBagImpl::ResAppend(LPCWSTR pName, LPCWSTR pDesc, LPCWSTR pMime, BYTE* pData, DWORD len, DWORD_PTR tag)
223 return ResSet(m_resources.Add(CDSMResource()), pName, pDesc, pMime, pData, len, tag);
226 STDMETHODIMP IDSMResourceBagImpl::ResRemoveAt(DWORD iIndex)
228 if((INT_PTR)iIndex >= m_resources.GetCount())
229 return E_INVALIDARG;
231 m_resources.RemoveAt(iIndex);
233 return S_OK;
236 STDMETHODIMP IDSMResourceBagImpl::ResRemoveAll(DWORD_PTR tag)
238 if(tag)
240 for(int i = m_resources.GetCount() - 1; i >= 0; i--)
241 if(m_resources[i].tag == tag)
242 m_resources.RemoveAt(i);
244 else
246 m_resources.RemoveAll();
249 return S_OK;
253 // CDSMChapter
256 CDSMChapter::CDSMChapter()
258 order = counter++;
259 rt = 0;
262 CDSMChapter::CDSMChapter(REFERENCE_TIME rt, LPCWSTR name)
264 order = counter++;
265 this->rt = rt;
266 this->name = name;
269 void CDSMChapter::operator = (const CDSMChapter& c)
271 order = c.counter;
272 rt = c.rt;
273 name = c.name;
276 int CDSMChapter::counter = 0;
278 int CDSMChapter::Compare(const void* a, const void* b)
280 const CDSMChapter* ca = (const CDSMChapter*)a;
281 const CDSMChapter* cb = (const CDSMChapter*)b;
283 if(ca->rt > cb->rt) return 1;
284 else if(ca->rt < cb->rt) return -1;
286 return ca->order - cb->order;
290 // IDSMChapterBagImpl
293 IDSMChapterBagImpl::IDSMChapterBagImpl()
295 m_fSorted = false;
298 // IDSMRChapterBag
300 STDMETHODIMP_(DWORD) IDSMChapterBagImpl::ChapGetCount()
302 return m_chapters.GetCount();
305 STDMETHODIMP IDSMChapterBagImpl::ChapGet(DWORD iIndex, REFERENCE_TIME* prt, BSTR* ppName)
307 if((INT_PTR)iIndex >= m_chapters.GetCount())
308 return E_INVALIDARG;
310 CDSMChapter& c = m_chapters[iIndex];
312 if(prt) *prt = c.rt;
313 if(ppName) *ppName = c.name.AllocSysString();
315 return S_OK;
318 STDMETHODIMP IDSMChapterBagImpl::ChapSet(DWORD iIndex, REFERENCE_TIME rt, LPCWSTR pName)
320 if((INT_PTR)iIndex >= m_chapters.GetCount())
321 return E_INVALIDARG;
323 CDSMChapter& c = m_chapters[iIndex];
325 c.rt = rt;
326 if(pName) c.name = pName;
328 m_fSorted = false;
330 return S_OK;
333 STDMETHODIMP IDSMChapterBagImpl::ChapAppend(REFERENCE_TIME rt, LPCWSTR pName)
335 return ChapSet(m_chapters.Add(CDSMChapter()), rt, pName);
338 STDMETHODIMP IDSMChapterBagImpl::ChapRemoveAt(DWORD iIndex)
340 if((INT_PTR)iIndex >= m_chapters.GetCount())
341 return E_INVALIDARG;
343 m_chapters.RemoveAt(iIndex);
345 return S_OK;
348 STDMETHODIMP IDSMChapterBagImpl::ChapRemoveAll()
350 m_chapters.RemoveAll();
352 m_fSorted = false;
354 return S_OK;
357 STDMETHODIMP_(long) IDSMChapterBagImpl::ChapLookup(REFERENCE_TIME* prt, BSTR* ppName)
359 CheckPointer(prt, -1);
361 ChapSort();
363 int i = range_bsearch(m_chapters, *prt);
364 if(i < 0) return -1;
366 *prt = m_chapters[i].rt;
367 if(ppName) *ppName = m_chapters[i].name.AllocSysString();
369 return i;
372 STDMETHODIMP IDSMChapterBagImpl::ChapSort()
374 if(m_fSorted) return S_FALSE;
375 qsort(m_chapters.GetData(), m_chapters.GetCount(), sizeof(CDSMChapter), CDSMChapter::Compare);
376 m_fSorted = true;
377 return S_OK;
381 // CDSMChapterBag
384 CDSMChapterBag::CDSMChapterBag(LPUNKNOWN pUnk, HRESULT* phr)
385 : CUnknown(_T("CDSMChapterBag"), NULL)
389 STDMETHODIMP CDSMChapterBag::NonDelegatingQueryInterface(REFIID riid, void** ppv)
391 CheckPointer(ppv, E_POINTER);
393 return
394 QI(IDSMChapterBag)
395 __super::NonDelegatingQueryInterface(riid, ppv);