MSW: fix DisableScreensaver and RestoreScreensaver definitions
[vlc/asuraparaju-public.git] / projects / activex / persiststreaminit.cpp
blob2ec4adb7e77c6ac77b9d702937fbfbd525c0ad42
1 /*****************************************************************************
2 * persiststreaminit.cpp: ActiveX control for VLC
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
6 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
23 #include "plugin.h"
24 #include "persiststreaminit.h"
26 #include "utils.h"
27 #include <map>
29 #include <malloc.h>
30 #include <wchar.h>
32 using namespace std;
34 class AxVLCVariant
37 public:
39 AxVLCVariant(void)
41 VariantInit(&_v);
44 ~AxVLCVariant(void)
46 VariantClear(&_v);
49 AxVLCVariant(VARIANTARG &v)
51 VariantInit(&_v);
52 VariantCopy(&_v, &v);
55 AxVLCVariant(VARIANTARG *v)
57 VariantInit(&_v);
58 VariantCopy(&_v, v);
61 AxVLCVariant(const AxVLCVariant &vv)
63 VariantInit(&_v);
64 VariantCopy(&_v, const_cast<VARIANTARG *>(&(vv._v)));
67 AxVLCVariant(int i)
69 V_VT(&_v) = VT_I4;
70 V_I4(&_v) = i;
73 AxVLCVariant(BSTR bstr)
75 VARIANT arg;
76 V_VT(&arg) = VT_BSTR;
77 V_BSTR(&arg) = bstr;
78 VariantInit(&_v);
79 VariantCopy(&_v, &arg);
82 inline const VARIANTARG *variantArg(void) const {
83 return &_v;
86 inline void swap(AxVLCVariant &v1, AxVLCVariant &v2)
88 VARIANTARG tmp = v1._v;
89 v1._v = v2._v;
90 v2._v = tmp;
93 private:
95 VARIANTARG _v;
98 class AxVLCWSTR
101 public:
103 AxVLCWSTR(void) : _data(NULL) {};
105 virtual ~AxVLCWSTR()
107 if( NULL != _data )
109 ULONG refcount = InterlockedDecrement(&(_data->refcount));
110 if( 0 == refcount )
111 CoTaskMemFree(_data);
115 AxVLCWSTR(LPCWSTR s)
117 if( NULL != s )
119 size_t len = wcslen(s);
120 if( len > 0 )
122 size_t size = len*sizeof(WCHAR);
123 _data = (struct data *)CoTaskMemAlloc(sizeof(struct data)+size);
124 if( NULL != _data )
126 _data->len = len;
127 _data->refcount = 1;
128 memcpy(_data->wstr, s, size);
129 _data->wstr[len]=L'\0';
130 return;
134 _data = NULL;
137 AxVLCWSTR(const AxVLCWSTR &s)
139 _data = s._data;
140 if( NULL != _data )
141 InterlockedIncrement(&(_data->refcount));
144 inline bool operator<(const AxVLCWSTR &s) const
146 return compareNoCase(s.wstr()) < 0;
149 inline bool operator<(LPCWSTR s) const
151 return compareNoCase(s) < 0;
154 inline bool operator==(const AxVLCWSTR &s) const
156 return size() == s.size() ?
157 (compareNoCase(s.wstr()) == 0) : false;
160 inline bool operator==(LPCWSTR s) const
162 return compareNoCase(s) == 0;
165 LPCWSTR wstr(void) const
167 return (NULL != _data) ? _data->wstr : NULL;
170 size_t size(void) const
172 return (NULL != _data) ? _data->len : 0;
175 private:
177 inline int compareNoCase(LPCWSTR s) const
179 if( NULL == _data )
181 return (NULL == s) ? 0 : -1;
183 if( NULL == s )
184 return 1;
186 return _wcsicmp(_data->wstr, s);
189 struct data {
190 size_t len;
191 LONG refcount;
192 wchar_t wstr[1];
193 } *_data;
196 typedef pair<class AxVLCWSTR, class AxVLCVariant> AxVLCPropertyPair;
197 typedef map<class AxVLCWSTR, class AxVLCVariant> AxVLCPropertyMap;
199 ///////////////////////////
201 class VLCPropertyBag : public IPropertyBag
204 public:
206 VLCPropertyBag(void) : _i_ref(1) {};
207 virtual ~VLCPropertyBag() {};
209 // IUnknown methods
210 STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
212 if( NULL == ppv )
213 return E_POINTER;
214 if( (IID_IUnknown == riid)
215 || (IID_IPropertyBag == riid) )
217 AddRef();
218 *ppv = reinterpret_cast<LPVOID>(this);
219 return NOERROR;
221 // standalone object
222 return E_NOINTERFACE;
225 STDMETHODIMP_(ULONG) AddRef(void)
226 { return InterlockedIncrement(&_i_ref); };
228 STDMETHODIMP_(ULONG) Release(void)
230 ULONG refcount = InterlockedDecrement(&_i_ref);
231 if( 0 == refcount )
233 delete this;
234 return 0;
236 return refcount;
239 // IPropertyBag methods
241 STDMETHODIMP Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog)
243 if( (NULL == pszPropName) || (NULL == pVar) )
244 return E_POINTER;
246 AxVLCPropertyMap::const_iterator notfound = _pm.end();
247 AxVLCPropertyMap::const_iterator iter = _pm.find(pszPropName);
248 if( notfound != iter )
250 VARTYPE vtype = V_VT(pVar);
251 VARIANTARG v;
252 VariantInit(&v);
253 VariantCopy(&v, const_cast<VARIANTARG*>((*iter).second.variantArg()));
254 if( (V_VT(&v) != vtype) && FAILED(VariantChangeType(&v, &v, 0, vtype)) )
256 VariantClear(&v);
257 return E_FAIL;
259 *pVar = v;
260 return S_OK;
262 else
263 return E_INVALIDARG;
266 STDMETHODIMP Write(LPCOLESTR pszPropName, VARIANT *pVar)
268 if( (NULL == pszPropName) || (NULL == pVar) )
269 return E_POINTER;
271 AxVLCPropertyPair val(pszPropName, pVar);
272 pair<AxVLCPropertyMap::iterator, bool> p = _pm.insert(val);
273 if( false == p.second )
274 // replace existing key value
275 (*p.first).second = val.second;
276 return S_OK;
279 // custom methods
281 HRESULT Load(LPSTREAM pStm)
283 if( NULL == pStm )
284 return E_INVALIDARG;
286 HRESULT result;
288 AxVLCPropertyPair *val;
289 result = ReadProperty(pStm, &val);
290 if( SUCCEEDED(result) )
292 if( (val->first == L"(Count)") && (VT_I4 == V_VT(val->second.variantArg())) )
294 size_t count = V_I4(val->second.variantArg());
295 delete val;
296 while( count-- )
298 result = ReadProperty(pStm, &val);
299 if( FAILED(result) )
300 return result;
302 pair<AxVLCPropertyMap::iterator, bool> p = _pm.insert(*val);
303 if( false == p.second )
304 // replace existing key value
305 (*p.first).second = val->second;
306 delete val;
310 return result;
313 HRESULT Save(LPSTREAM pStm)
315 if( NULL == pStm )
316 return E_INVALIDARG;
318 HRESULT result;
320 AxVLCPropertyPair header(L"(Count)", _pm.size());
321 result = WriteProperty(pStm, header);
322 if( SUCCEEDED(result) )
324 AxVLCPropertyMap::const_iterator iter = _pm.begin();
325 AxVLCPropertyMap::const_iterator end = _pm.end();
327 while( iter != end )
329 result = WriteProperty(pStm, *(iter++));
330 if( FAILED(result) )
331 return result;
334 return result;
337 BOOL IsEmpty()
339 return _pm.size() == 0;
342 private:
344 HRESULT WriteProperty(LPSTREAM pStm, const AxVLCPropertyPair &prop)
346 HRESULT result;
348 const AxVLCWSTR propName = prop.first;
350 ULONG len = propName.size();
352 if( 0 == len )
353 return E_INVALIDARG;
355 result = pStm->Write(&len, sizeof(len), NULL);
356 if( FAILED(result) )
357 return result;
359 result = pStm->Write(propName.wstr(), len*sizeof(WCHAR), NULL);
360 if( FAILED(result) )
361 return result;
363 const VARIANTARG *propValue = prop.second.variantArg();
364 VARTYPE vtype = V_VT(propValue);
365 switch( vtype )
367 case VT_BOOL:
368 result = pStm->Write(&vtype, sizeof(vtype), NULL);
369 if( FAILED(result) )
370 return result;
371 result = pStm->Write(&V_BOOL(propValue), sizeof(V_BOOL(propValue)), NULL);
372 if( FAILED(result) )
373 return result;
374 break;
375 case VT_I4:
376 result = pStm->Write(&vtype, sizeof(vtype), NULL);
377 if( FAILED(result) )
378 return result;
379 result = pStm->Write(&V_I4(propValue), sizeof(V_I4(propValue)), NULL);
380 if( FAILED(result) )
381 return result;
382 break;
383 case VT_BSTR:
384 result = pStm->Write(&vtype, sizeof(vtype), NULL);
385 if( FAILED(result) )
386 return result;
387 len = SysStringLen(V_BSTR(propValue));
388 result = pStm->Write(&len, sizeof(len), NULL);
389 if( FAILED(result) )
390 return result;
391 if( len > 0 )
393 result = pStm->Write(V_BSTR(propValue), len*sizeof(OLECHAR), NULL);
394 if( FAILED(result) )
395 return result;
397 break;
398 default:
399 vtype = VT_EMPTY;
400 result = pStm->Write(&vtype, sizeof(vtype), NULL);
401 if( FAILED(result) )
402 return result;
404 return result;
407 HRESULT ReadProperty(LPSTREAM pStm, AxVLCPropertyPair **prop)
409 HRESULT result;
411 ULONG len;
413 result = pStm->Read(&len, sizeof(len), NULL);
414 if( FAILED(result) )
415 return result;
417 if( 0 == len )
418 return E_INVALIDARG;
420 WCHAR propName[len + 1];
422 result = pStm->Read(propName, len*sizeof(WCHAR), NULL);
423 if( FAILED(result) )
424 return result;
426 propName[len] = L'\0';
428 VARIANTARG propValue;
430 VARTYPE vtype;
431 result = pStm->Read(&vtype, sizeof(vtype), NULL);
432 if( FAILED(result) )
433 return result;
435 switch( vtype )
437 case VT_BOOL:
438 V_VT(&propValue) = vtype;
439 result = pStm->Read(&V_BOOL(&propValue), sizeof(V_BOOL(&propValue)), NULL);
440 if( FAILED(result) )
441 return result;
442 break;
443 case VT_I4:
444 V_VT(&propValue) = vtype;
445 result = pStm->Read(&V_I4(&propValue), sizeof(V_I4(&propValue)), NULL);
446 if( FAILED(result) )
447 return result;
448 break;
449 case VT_BSTR:
450 V_VT(&propValue) = vtype;
451 result = pStm->Read(&len, sizeof(len), NULL);
452 if( FAILED(result) )
453 return result;
455 V_BSTR(&propValue) = NULL;
456 if( len > 0 )
458 V_BSTR(&propValue) = SysAllocStringLen(NULL, len);
459 if( NULL == V_BSTR(&propValue) )
460 return E_OUTOFMEMORY;
462 result = pStm->Read(V_BSTR(&propValue), len*sizeof(OLECHAR), NULL);
463 if( FAILED(result) )
465 SysFreeString(V_BSTR(&propValue));
466 return result;
469 break;
470 default:
471 VariantInit(&propValue);
474 *prop = new AxVLCPropertyPair(propName, propValue);
476 return S_OK;
479 AxVLCPropertyMap _pm;
480 LONG _i_ref;
483 ///////////////////////////
485 VLCPersistStreamInit::VLCPersistStreamInit(VLCPlugin *p_instance) : _p_instance(p_instance)
487 _p_props = new VLCPropertyBag();
490 VLCPersistStreamInit::~VLCPersistStreamInit()
492 _p_props->Release();
495 STDMETHODIMP VLCPersistStreamInit::GetClassID(LPCLSID pClsID)
497 if( NULL == pClsID )
498 return E_POINTER;
500 *pClsID = _p_instance->getClassID();
502 return S_OK;
505 STDMETHODIMP VLCPersistStreamInit::InitNew(void)
507 return _p_instance->onInit();
510 STDMETHODIMP VLCPersistStreamInit::Load(LPSTREAM pStm)
512 HRESULT result = _p_props->Load(pStm);
513 if( FAILED(result) )
514 return result;
516 LPPERSISTPROPERTYBAG pPersistPropBag;
517 if( FAILED(QueryInterface(IID_IPersistPropertyBag, (void**)&pPersistPropBag)) )
518 return E_FAIL;
520 result = pPersistPropBag->Load(_p_props, NULL);
521 pPersistPropBag->Release();
523 return result;
526 STDMETHODIMP VLCPersistStreamInit::Save(LPSTREAM pStm, BOOL fClearDirty)
528 if( NULL == pStm )
529 return E_INVALIDARG;
531 LPPERSISTPROPERTYBAG pPersistPropBag;
532 if( FAILED(QueryInterface(IID_IPersistPropertyBag, (void**)&pPersistPropBag)) )
533 return E_FAIL;
535 HRESULT result = pPersistPropBag->Save(_p_props, fClearDirty, _p_props->IsEmpty());
536 pPersistPropBag->Release();
537 if( FAILED(result) )
538 return result;
540 return _p_props->Save(pStm);
543 STDMETHODIMP VLCPersistStreamInit::IsDirty(void)
545 return _p_instance->isDirty() ? S_OK : S_FALSE;
548 STDMETHODIMP VLCPersistStreamInit::GetSizeMax(ULARGE_INTEGER *pcbSize)
550 pcbSize->HighPart = 0UL;
551 pcbSize->LowPart = 16384UL; // just a guess
553 return S_OK;