- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# DSMPropertyBag.cpp

    00001 #include "StdAfx.h"
    00002 #include "DSUtil.h"
    00003 #include "DSMPropertyBag.h"
    00004
    00005 //
    00006 // IDSMPropertyBagImpl
    00007 //
    00008
    00009 IDSMPropertyBagImpl::IDSMPropertyBagImpl()
    00010 {
    00011 }
    00012
    00013 IDSMPropertyBagImpl::~IDSMPropertyBagImpl()
    00014 {
    00015 }
    00016
    00017 // IPropertyBag
    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 // IPropertyBag2
    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 // IDSMProperyBag
    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 // CDSMResource
    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 // IDSMResourceBagImpl
    00166 //
    00167
    00168 IDSMResourceBagImpl::IDSMResourceBagImpl()
    00169 {
    00170 }
    00171
    00172 // IDSMResourceBag
    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 // CDSMChapter
    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 // IDSMChapterBagImpl
    00262 //
    00263
    00264 IDSMChapterBagImpl::IDSMChapterBagImpl()
    00265 {
    00266         m_fSorted = false;
    00267 }
    00268
    00269 // IDSMRChapterBag
    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 // CDSMChapterBag
    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 }