00001 #include "StdAfx.h"
00002 #include "DSUtil.h"
00003 #include "DSMPropertyBag.h"
00004
00005
00006
00007
00008
00009 IDSMPropertyBagImpl::IDSMPropertyBagImpl()
00010 {
00011 }
00012
00013 IDSMPropertyBagImpl::~IDSMPropertyBagImpl()
00014 {
00015 }
00016
00017
00018
00019 STDMETHODIMP IDSMPropertyBagImpl::Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog* pErrorLog)
00020 {
00021 CheckPointer(pVar, E_POINTER);
00022 if(pVar->vt != VT_EMPTY) return E_INVALIDARG;
00023 CStringW value = Lookup(pszPropName);
00024 if(value.IsEmpty()) return E_FAIL;
00025 CComVariant(value).Detach(pVar);
00026 return S_OK;
00027 }
00028
00029 STDMETHODIMP IDSMPropertyBagImpl::Write(LPCOLESTR pszPropName, VARIANT* pVar)
00030 {
00031 return SetProperty(pszPropName, pVar);
00032 }
00033
00034
00035
00036 STDMETHODIMP IDSMPropertyBagImpl::Read(ULONG cProperties, PROPBAG2* pPropBag, IErrorLog* pErrLog, VARIANT* pvarValue, HRESULT* phrError)
00037 {
00038 CheckPointer(pPropBag, E_POINTER);
00039 CheckPointer(pvarValue, E_POINTER);
00040 CheckPointer(phrError, E_POINTER);
00041 for(ULONG i = 0; i < cProperties; phrError[i] = S_OK, i++)
00042 CComVariant(Lookup(pPropBag[i].pstrName)).Detach(pvarValue);
00043 return S_OK;
00044 }
00045
00046 STDMETHODIMP IDSMPropertyBagImpl::Write(ULONG cProperties, PROPBAG2* pPropBag, VARIANT* pvarValue)
00047 {
00048 CheckPointer(pPropBag, E_POINTER);
00049 CheckPointer(pvarValue, E_POINTER);
00050 for(ULONG i = 0; i < cProperties; i++)
00051 SetProperty(pPropBag[i].pstrName, &pvarValue[i]);
00052 return S_OK;
00053 }
00054
00055 STDMETHODIMP IDSMPropertyBagImpl::CountProperties(ULONG* pcProperties)
00056 {
00057 CheckPointer(pcProperties, E_POINTER);
00058 *pcProperties = GetSize();
00059 return S_OK;
00060 }
00061
00062 STDMETHODIMP IDSMPropertyBagImpl::GetPropertyInfo(ULONG iProperty, ULONG cProperties, PROPBAG2* pPropBag, ULONG* pcProperties)
00063 {
00064 CheckPointer(pPropBag, E_POINTER);
00065 CheckPointer(pcProperties, E_POINTER);
00066 for(ULONG i = 0; i < cProperties; i++, iProperty++, (*pcProperties)++)
00067 {
00068 CStringW key = GetKeyAt(iProperty);
00069 pPropBag[i].pstrName = (BSTR)CoTaskMemAlloc((key.GetLength()+1)*sizeof(WCHAR));
00070 if(!pPropBag[i].pstrName) return E_FAIL;
00071 wcscpy(pPropBag[i].pstrName, key);
00072 }
00073 return S_OK;
00074 }
00075
00076 STDMETHODIMP IDSMPropertyBagImpl::LoadObject(LPCOLESTR pstrName, DWORD dwHint, IUnknown* pUnkObject, IErrorLog* pErrLog)
00077 {
00078 return E_NOTIMPL;
00079 }
00080
00081
00082
00083 HRESULT IDSMPropertyBagImpl::SetProperty(LPCWSTR key, LPCWSTR value)
00084 {
00085 CheckPointer(key, E_POINTER);
00086 CheckPointer(value, E_POINTER);
00087 if(!Lookup(key).IsEmpty()) SetAt(key, value);
00088 else Add(key, value);
00089 return S_OK;
00090 }
00091
00092 HRESULT IDSMPropertyBagImpl::SetProperty(LPCWSTR key, VARIANT* var)
00093 {
00094 CheckPointer(key, E_POINTER);
00095 CheckPointer(var, E_POINTER);
00096 if((var->vt & (VT_BSTR | VT_BYREF)) != VT_BSTR) return E_INVALIDARG;
00097 return SetProperty(key, var->bstrVal);
00098 }
00099
00100 HRESULT IDSMPropertyBagImpl::GetProperty(LPCWSTR key, BSTR* value)
00101 {
00102 CheckPointer(key, E_POINTER);
00103 CheckPointer(value, E_POINTER);
00104 int i = FindKey(key);
00105 if(i < 0) return E_FAIL;
00106 *value = GetValueAt(i).AllocSysString();
00107 return S_OK;
00108 }
00109
00110 HRESULT IDSMPropertyBagImpl::DelAllProperties()
00111 {
00112 RemoveAll();
00113 return S_OK;
00114 }
00115
00116 HRESULT IDSMPropertyBagImpl::DelProperty(LPCWSTR key)
00117 {
00118 return Remove(key) ? S_OK : S_FALSE;
00119 }
00120
00121
00122
00123
00124
00125 CCritSec CDSMResource::m_csResources;
00126 CAtlMap<DWORD, CDSMResource*> CDSMResource::m_resources;
00127
00128 CDSMResource::CDSMResource()
00129 : mime(_T("application/octet-stream"))
00130 , tag(0)
00131 {
00132 CAutoLock cAutoLock(&m_csResources);
00133 m_resources.SetAt((DWORD)this, this);
00134 }
00135
00136 CDSMResource::CDSMResource(LPCWSTR name, LPCWSTR desc, LPCWSTR mime, BYTE* pData, int len, DWORD_PTR tag)
00137 {
00138 this->name = name;
00139 this->desc = desc;
00140 this->mime = mime;
00141 data.SetSize(len);
00142 memcpy(data.GetData(), pData, data.GetSize());
00143 this->tag = tag;
00144
00145 CAutoLock cAutoLock(&m_csResources);
00146 m_resources.SetAt((DWORD)this, this);
00147 }
00148
00149 CDSMResource::~CDSMResource()
00150 {
00151 CAutoLock cAutoLock(&m_csResources);
00152 m_resources.RemoveKey((DWORD)this);
00153 }
00154
00155 void CDSMResource::operator = (const CDSMResource& r)
00156 {
00157 tag = r.tag;
00158 name = r.name;
00159 desc = r.desc;
00160 mime = r.mime;
00161 data.Copy(r.data);
00162 }
00163
00164
00165
00166
00167
00168 IDSMResourceBagImpl::IDSMResourceBagImpl()
00169 {
00170 }
00171
00172
00173
00174 STDMETHODIMP_(DWORD) IDSMResourceBagImpl::ResGetCount()
00175 {
00176 return m_resources.GetCount();
00177 }
00178
00179 STDMETHODIMP IDSMResourceBagImpl::ResGet(DWORD iIndex, BSTR* ppName, BSTR* ppDesc, BSTR* ppMime, BYTE** ppData, DWORD* pDataLen, DWORD_PTR* pTag)
00180 {
00181 if(ppData) CheckPointer(pDataLen, E_POINTER);
00182
00183 if((INT_PTR)iIndex >= m_resources.GetCount())
00184 return E_INVALIDARG;
00185
00186 CDSMResource& r = m_resources[iIndex];
00187
00188 if(ppName) *ppName = r.name.AllocSysString();
00189 if(ppDesc) *ppDesc = r.desc.AllocSysString();
00190 if(ppMime) *ppMime = r.mime.AllocSysString();
00191 if(ppData) {*pDataLen = r.data.GetSize(); memcpy(*ppData = (BYTE*)CoTaskMemAlloc(*pDataLen), r.data.GetData(), *pDataLen);}
00192 if(pTag) *pTag = r.tag;
00193
00194 return S_OK;
00195 }
00196
00197 STDMETHODIMP IDSMResourceBagImpl::ResSet(DWORD iIndex, LPCWSTR pName, LPCWSTR pDesc, LPCWSTR pMime, BYTE* pData, DWORD len, DWORD_PTR tag)
00198 {
00199 if((INT_PTR)iIndex >= m_resources.GetCount())
00200 return E_INVALIDARG;
00201
00202 CDSMResource& r = m_resources[iIndex];
00203
00204 if(pName) r.name = pName;
00205 if(pDesc) r.desc = pDesc;
00206 if(pMime) r.mime = pMime;
00207 if(pData || len == 0) {r.data.SetSize(len); if(pData) memcpy(r.data.GetData(), pData, r.data.GetSize());}
00208 r.tag = tag;
00209
00210 return S_OK;
00211 }
00212
00213 STDMETHODIMP IDSMResourceBagImpl::ResAppend(LPCWSTR pName, LPCWSTR pDesc, LPCWSTR pMime, BYTE* pData, DWORD len, DWORD_PTR tag)
00214 {
00215 return ResSet(m_resources.Add(CDSMResource()), pName, pDesc, pMime, pData, len, tag);
00216 }
00217
00218 STDMETHODIMP IDSMResourceBagImpl::ResRemoveAt(DWORD iIndex)
00219 {
00220 if((INT_PTR)iIndex >= m_resources.GetCount())
00221 return E_INVALIDARG;
00222
00223 m_resources.RemoveAt(iIndex);
00224
00225 return S_OK;
00226 }
00227
00228 STDMETHODIMP IDSMResourceBagImpl::ResRemoveAll(DWORD_PTR tag)
00229 {
00230 if(tag)
00231 {
00232 for(int i = m_resources.GetCount() - 1; i >= 0; i--)
00233 if(m_resources[i].tag == tag)
00234 m_resources.RemoveAt(i);
00235 }
00236 else
00237 {
00238 m_resources.RemoveAll();
00239 }
00240
00241 return S_OK;
00242 }
00243
00244
00245
00246
00247
00248 CDSMChapter::CDSMChapter(REFERENCE_TIME rt, LPCWSTR name)
00249 {
00250 this->rt = rt;
00251 this->name = name;
00252 }
00253
00254 void CDSMChapter::operator = (const CDSMChapter& c)
00255 {
00256 rt = c.rt;
00257 name = c.name;
00258 }
00259
00260
00261
00262
00263
00264 IDSMChapterBagImpl::IDSMChapterBagImpl()
00265 {
00266 m_fSorted = false;
00267 }
00268
00269
00270
00271 STDMETHODIMP_(DWORD) IDSMChapterBagImpl::ChapGetCount()
00272 {
00273 return m_chapters.GetCount();
00274 }
00275
00276 STDMETHODIMP IDSMChapterBagImpl::ChapGet(DWORD iIndex, REFERENCE_TIME* prt, BSTR* ppName)
00277 {
00278 if((INT_PTR)iIndex >= m_chapters.GetCount())
00279 return E_INVALIDARG;
00280
00281 CDSMChapter& c = m_chapters[iIndex];
00282
00283 if(prt) *prt = c.rt;
00284 if(ppName) *ppName = c.name.AllocSysString();
00285
00286 return S_OK;
00287 }
00288
00289 STDMETHODIMP IDSMChapterBagImpl::ChapSet(DWORD iIndex, REFERENCE_TIME rt, LPCWSTR pName)
00290 {
00291 if((INT_PTR)iIndex >= m_chapters.GetCount())
00292 return E_INVALIDARG;
00293
00294 CDSMChapter& c = m_chapters[iIndex];
00295
00296 c.rt = rt;
00297 if(pName) c.name = pName;
00298
00299 m_fSorted = false;
00300
00301 return S_OK;
00302 }
00303
00304 STDMETHODIMP IDSMChapterBagImpl::ChapAppend(REFERENCE_TIME rt, LPCWSTR pName)
00305 {
00306 return ChapSet(m_chapters.Add(CDSMChapter()), rt, pName);
00307 }
00308
00309 STDMETHODIMP IDSMChapterBagImpl::ChapRemoveAt(DWORD iIndex)
00310 {
00311 if((INT_PTR)iIndex >= m_chapters.GetCount())
00312 return E_INVALIDARG;
00313
00314 m_chapters.RemoveAt(iIndex);
00315
00316 return S_OK;
00317 }
00318
00319 STDMETHODIMP IDSMChapterBagImpl::ChapRemoveAll()
00320 {
00321 m_chapters.RemoveAll();
00322
00323 m_fSorted = false;
00324
00325 return S_OK;
00326 }
00327
00328 STDMETHODIMP_(long) IDSMChapterBagImpl::ChapLookup(REFERENCE_TIME* prt, BSTR* ppName)
00329 {
00330 CheckPointer(prt, -1);
00331
00332 ChapSort();
00333
00334 int i = range_bsearch(m_chapters, *prt);
00335 if(i < 0) return -1;
00336
00337 *prt = m_chapters[i].rt;
00338 if(ppName) *ppName = m_chapters[i].name.AllocSysString();
00339
00340 return i;
00341 }
00342
00343 static int chapter_comp(const void* a, const void* b)
00344 {
00345 if(((CDSMChapter*)a)->rt > ((CDSMChapter*)b)->rt) return 1;
00346 else if(((CDSMChapter*)a)->rt < ((CDSMChapter*)b)->rt) return -1;
00347 return 0;
00348 }
00349
00350 STDMETHODIMP IDSMChapterBagImpl::ChapSort()
00351 {
00352 if(m_fSorted) return S_FALSE;
00353 qsort(m_chapters.GetData(), m_chapters.GetCount(), sizeof(CDSMChapter), chapter_comp);
00354 m_fSorted = true;
00355 return S_OK;
00356 }
00357
00358
00359
00360
00361
00362 CDSMChapterBag::CDSMChapterBag(LPUNKNOWN pUnk, HRESULT* phr)
00363 : CUnknown(_T("CDSMChapterBag"), NULL)
00364 {
00365 }
00366
00367 STDMETHODIMP CDSMChapterBag::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00368 {
00369 CheckPointer(ppv, E_POINTER);
00370
00371 return
00372 QI(IDSMChapterBag)
00373 __super::NonDelegatingQueryInterface(riid, ppv);
00374 }