DSMPropertyBag.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:8k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include "StdAfx.h"
  2. #include "DSUtil.h"
  3. #include "DSMPropertyBag.h"
  4. //
  5. // IDSMPropertyBagImpl
  6. //
  7. IDSMPropertyBagImpl::IDSMPropertyBagImpl()
  8. {
  9. }
  10. IDSMPropertyBagImpl::~IDSMPropertyBagImpl()
  11. {
  12. }
  13. // IPropertyBag
  14. STDMETHODIMP IDSMPropertyBagImpl::Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog* pErrorLog)
  15. {
  16. CheckPointer(pVar, E_POINTER);
  17. if(pVar->vt != VT_EMPTY) return E_INVALIDARG;
  18. CStringW value = Lookup(pszPropName);
  19. if(value.IsEmpty()) return E_FAIL;
  20. CComVariant(value).Detach(pVar);
  21. return S_OK;
  22. }
  23. STDMETHODIMP IDSMPropertyBagImpl::Write(LPCOLESTR pszPropName, VARIANT* pVar)
  24. {
  25. return SetProperty(pszPropName, pVar);
  26. }
  27. // IPropertyBag2
  28. STDMETHODIMP IDSMPropertyBagImpl::Read(ULONG cProperties, PROPBAG2* pPropBag, IErrorLog* pErrLog, VARIANT* pvarValue, HRESULT* phrError)
  29. {
  30. CheckPointer(pPropBag, E_POINTER);
  31. CheckPointer(pvarValue, E_POINTER);
  32. CheckPointer(phrError, E_POINTER);
  33. for(ULONG i = 0; i < cProperties; phrError[i] = S_OK, i++)
  34. CComVariant(Lookup(pPropBag[i].pstrName)).Detach(pvarValue);
  35. return S_OK;
  36. }
  37. STDMETHODIMP IDSMPropertyBagImpl::Write(ULONG cProperties, PROPBAG2* pPropBag, VARIANT* pvarValue)
  38. {
  39. CheckPointer(pPropBag, E_POINTER);
  40. CheckPointer(pvarValue, E_POINTER);
  41. for(ULONG i = 0; i < cProperties; i++)
  42. SetProperty(pPropBag[i].pstrName, &pvarValue[i]);
  43. return S_OK;
  44. }
  45. STDMETHODIMP IDSMPropertyBagImpl::CountProperties(ULONG* pcProperties)
  46. {
  47. CheckPointer(pcProperties, E_POINTER);
  48. *pcProperties = GetSize();
  49. return S_OK;
  50. }
  51. STDMETHODIMP IDSMPropertyBagImpl::GetPropertyInfo(ULONG iProperty, ULONG cProperties, PROPBAG2* pPropBag, ULONG* pcProperties)
  52. {
  53. CheckPointer(pPropBag, E_POINTER);
  54. CheckPointer(pcProperties, E_POINTER);
  55. for(ULONG i = 0; i < cProperties; i++, iProperty++, (*pcProperties)++) 
  56. {
  57. CStringW key = GetKeyAt(iProperty);
  58. pPropBag[i].pstrName = (BSTR)CoTaskMemAlloc((key.GetLength()+1)*sizeof(WCHAR));
  59. if(!pPropBag[i].pstrName) return E_FAIL;
  60.         wcscpy(pPropBag[i].pstrName, key);
  61. }
  62. return S_OK;
  63. }
  64. STDMETHODIMP IDSMPropertyBagImpl::LoadObject(LPCOLESTR pstrName, DWORD dwHint, IUnknown* pUnkObject, IErrorLog* pErrLog)
  65. {
  66. return E_NOTIMPL;
  67. }
  68. // IDSMProperyBag
  69. HRESULT IDSMPropertyBagImpl::SetProperty(LPCWSTR key, LPCWSTR value)
  70. {
  71. CheckPointer(key, E_POINTER);
  72. CheckPointer(value, E_POINTER);
  73. if(!Lookup(key).IsEmpty()) SetAt(key, value);
  74. else Add(key, value);
  75. return S_OK;
  76. }
  77. HRESULT IDSMPropertyBagImpl::SetProperty(LPCWSTR key, VARIANT* var)
  78. {
  79. CheckPointer(key, E_POINTER);
  80. CheckPointer(var, E_POINTER);
  81. if((var->vt & (VT_BSTR | VT_BYREF)) != VT_BSTR) return E_INVALIDARG;
  82. return SetProperty(key, var->bstrVal);
  83. }
  84. HRESULT IDSMPropertyBagImpl::GetProperty(LPCWSTR key, BSTR* value)
  85. {
  86. CheckPointer(key, E_POINTER);
  87. CheckPointer(value, E_POINTER);
  88. int i = FindKey(key);
  89. if(i < 0) return E_FAIL;
  90. *value = GetValueAt(i).AllocSysString();
  91. return S_OK;
  92. }
  93. HRESULT IDSMPropertyBagImpl::DelAllProperties()
  94. {
  95. RemoveAll();
  96. return S_OK;
  97. }
  98. HRESULT IDSMPropertyBagImpl::DelProperty(LPCWSTR key)
  99. {
  100. return Remove(key) ? S_OK : S_FALSE;
  101. }
  102. //
  103. // CDSMResource
  104. //
  105. CCritSec CDSMResource::m_csResources;
  106. CAtlMap<DWORD, CDSMResource*> CDSMResource::m_resources;
  107. CDSMResource::CDSMResource() 
  108. : mime(_T("application/octet-stream"))
  109. , tag(0)
  110. {
  111. CAutoLock cAutoLock(&m_csResources);
  112. m_resources.SetAt((DWORD)this, this);
  113. }
  114. CDSMResource::CDSMResource(LPCWSTR name, LPCWSTR desc, LPCWSTR mime, BYTE* pData, int len, DWORD_PTR tag)
  115. {
  116. this->name = name;
  117. this->desc = desc;
  118. this->mime = mime;
  119. data.SetSize(len);
  120. memcpy(data.GetData(), pData, data.GetSize());
  121. this->tag = tag;
  122. CAutoLock cAutoLock(&m_csResources);
  123. m_resources.SetAt((DWORD)this, this);
  124. }
  125. CDSMResource::~CDSMResource()
  126. {
  127. CAutoLock cAutoLock(&m_csResources);
  128. m_resources.RemoveKey((DWORD)this);
  129. }
  130. void CDSMResource::operator = (const CDSMResource& r)
  131. {
  132. tag = r.tag;
  133. name = r.name;
  134. desc = r.desc;
  135. mime = r.mime;
  136. data.Copy(r.data);
  137. }
  138. //
  139. // IDSMResourceBagImpl
  140. //
  141. IDSMResourceBagImpl::IDSMResourceBagImpl()
  142. {
  143. }
  144. // IDSMResourceBag
  145. STDMETHODIMP_(DWORD) IDSMResourceBagImpl::ResGetCount()
  146. {
  147. return m_resources.GetCount();
  148. }
  149. STDMETHODIMP IDSMResourceBagImpl::ResGet(DWORD iIndex, BSTR* ppName, BSTR* ppDesc, BSTR* ppMime, BYTE** ppData, DWORD* pDataLen, DWORD_PTR* pTag)
  150. {
  151. if(ppData) CheckPointer(pDataLen, E_POINTER);
  152. if((INT_PTR)iIndex >= m_resources.GetCount())
  153. return E_INVALIDARG;
  154. CDSMResource& r = m_resources[iIndex];
  155. if(ppName) *ppName = r.name.AllocSysString();
  156. if(ppDesc) *ppDesc = r.desc.AllocSysString();
  157. if(ppMime) *ppMime = r.mime.AllocSysString();
  158. if(ppData) {*pDataLen = r.data.GetSize(); memcpy(*ppData = (BYTE*)CoTaskMemAlloc(*pDataLen), r.data.GetData(), *pDataLen);}
  159. if(pTag) *pTag = r.tag;
  160. return S_OK;
  161. }
  162. STDMETHODIMP IDSMResourceBagImpl::ResSet(DWORD iIndex, LPCWSTR pName, LPCWSTR pDesc, LPCWSTR pMime, BYTE* pData, DWORD len, DWORD_PTR tag)
  163. {
  164. if((INT_PTR)iIndex >= m_resources.GetCount())
  165. return E_INVALIDARG;
  166. CDSMResource& r = m_resources[iIndex];
  167. if(pName) r.name = pName;
  168. if(pDesc) r.desc = pDesc;
  169. if(pMime) r.mime = pMime;
  170. if(pData || len == 0) {r.data.SetSize(len); if(pData) memcpy(r.data.GetData(), pData, r.data.GetSize());}
  171. r.tag = tag;
  172. return S_OK;
  173. }
  174. STDMETHODIMP IDSMResourceBagImpl::ResAppend(LPCWSTR pName, LPCWSTR pDesc, LPCWSTR pMime, BYTE* pData, DWORD len, DWORD_PTR tag)
  175. {
  176. return ResSet(m_resources.Add(CDSMResource()), pName, pDesc, pMime, pData, len, tag);
  177. }
  178. STDMETHODIMP IDSMResourceBagImpl::ResRemoveAt(DWORD iIndex)
  179. {
  180. if((INT_PTR)iIndex >= m_resources.GetCount())
  181. return E_INVALIDARG;
  182. m_resources.RemoveAt(iIndex);
  183. return S_OK;
  184. }
  185. STDMETHODIMP IDSMResourceBagImpl::ResRemoveAll(DWORD_PTR tag)
  186. {
  187. if(tag)
  188. {
  189. for(int i = m_resources.GetCount() - 1; i >= 0; i--)
  190. if(m_resources[i].tag == tag)
  191. m_resources.RemoveAt(i);
  192. }
  193. else
  194. {
  195. m_resources.RemoveAll();
  196. }
  197. return S_OK;
  198. }
  199. //
  200. // CDSMChapter
  201. //
  202. CDSMChapter::CDSMChapter(REFERENCE_TIME rt, LPCWSTR name)
  203. {
  204. this->rt = rt;
  205. this->name = name;
  206. }
  207. void CDSMChapter::operator = (const CDSMChapter& c)
  208. {
  209. rt = c.rt;
  210. name = c.name;
  211. }
  212. //
  213. // IDSMChapterBagImpl
  214. //
  215. IDSMChapterBagImpl::IDSMChapterBagImpl()
  216. {
  217. m_fSorted = false;
  218. }
  219. // IDSMRChapterBag
  220. STDMETHODIMP_(DWORD) IDSMChapterBagImpl::ChapGetCount()
  221. {
  222. return m_chapters.GetCount();
  223. }
  224. STDMETHODIMP IDSMChapterBagImpl::ChapGet(DWORD iIndex, REFERENCE_TIME* prt, BSTR* ppName)
  225. {
  226. if((INT_PTR)iIndex >= m_chapters.GetCount())
  227. return E_INVALIDARG;
  228. CDSMChapter& c = m_chapters[iIndex];
  229. if(prt) *prt = c.rt;
  230. if(ppName) *ppName = c.name.AllocSysString();
  231. return S_OK;
  232. }
  233. STDMETHODIMP IDSMChapterBagImpl::ChapSet(DWORD iIndex, REFERENCE_TIME rt, LPCWSTR pName)
  234. {
  235. if((INT_PTR)iIndex >= m_chapters.GetCount())
  236. return E_INVALIDARG;
  237. CDSMChapter& c = m_chapters[iIndex];
  238. c.rt = rt;
  239. if(pName) c.name = pName;
  240. m_fSorted = false;
  241. return S_OK;
  242. }
  243. STDMETHODIMP IDSMChapterBagImpl::ChapAppend(REFERENCE_TIME rt, LPCWSTR pName)
  244. {
  245. return ChapSet(m_chapters.Add(CDSMChapter()), rt, pName);
  246. }
  247. STDMETHODIMP IDSMChapterBagImpl::ChapRemoveAt(DWORD iIndex)
  248. {
  249. if((INT_PTR)iIndex >= m_chapters.GetCount())
  250. return E_INVALIDARG;
  251. m_chapters.RemoveAt(iIndex);
  252. return S_OK;
  253. }
  254. STDMETHODIMP IDSMChapterBagImpl::ChapRemoveAll()
  255. {
  256. m_chapters.RemoveAll();
  257. m_fSorted = false;
  258. return S_OK;
  259. }
  260. STDMETHODIMP_(long) IDSMChapterBagImpl::ChapLookup(REFERENCE_TIME* prt, BSTR* ppName)
  261. {
  262. CheckPointer(prt, -1);
  263. ChapSort();
  264. int i = range_bsearch(m_chapters, *prt);
  265. if(i < 0) return -1;
  266. *prt = m_chapters[i].rt;
  267. if(ppName) *ppName = m_chapters[i].name.AllocSysString();
  268. return i;
  269. }
  270. static int chapter_comp(const void* a, const void* b)
  271. {
  272. if(((CDSMChapter*)a)->rt > ((CDSMChapter*)b)->rt) return 1;
  273. else if(((CDSMChapter*)a)->rt < ((CDSMChapter*)b)->rt) return -1;
  274. return 0;
  275. }
  276. STDMETHODIMP IDSMChapterBagImpl::ChapSort()
  277. {
  278. if(m_fSorted) return S_FALSE;
  279. qsort(m_chapters.GetData(), m_chapters.GetCount(), sizeof(CDSMChapter), chapter_comp);
  280. m_fSorted = true;
  281. return S_OK;
  282. }
  283. //
  284. // CDSMChapterBag
  285. //
  286. CDSMChapterBag::CDSMChapterBag(LPUNKNOWN pUnk, HRESULT* phr) 
  287. : CUnknown(_T("CDSMChapterBag"), NULL)
  288. {
  289. }
  290. STDMETHODIMP CDSMChapterBag::NonDelegatingQueryInterface(REFIID riid, void** ppv)
  291. {
  292.     CheckPointer(ppv, E_POINTER);
  293. return
  294. QI(IDSMChapterBag)
  295.  __super::NonDelegatingQueryInterface(riid, ppv);
  296. }