-/*****************************************************************************\r
- * utils.h: ActiveX control for VLC\r
- *****************************************************************************\r
- * Copyright (C) 2005 VideoLAN\r
- *\r
- * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.\r
- *****************************************************************************/\r
-\r
-#ifndef __UTILS_H__\r
-#define __UTILS_H__\r
-\r
-#include <ole2.h>\r
-\r
-#include <vector>\r
-\r
-// utilities\r
-extern char *CStrFromBSTR(int codePage, BSTR bstr);\r
-extern BSTR BSTRFromCStr(int codePage, const char *s);\r
-\r
-// properties\r
-extern HRESULT GetObjectProperty(LPUNKNOWN object, DISPID dispID, VARIANT& v);\r
-\r
-// enumeration\r
-template<class T> class VLCEnum : IUnknown\r
-{\r
-\r
-public:\r
-\r
- VLCEnum(REFIID riid, std::vector<T> &);\r
- VLCEnum(const VLCEnum<T> &);\r
- virtual ~VLCEnum() {};\r
-\r
- VLCEnum<T>& operator=(const VLCEnum<T> &t);\r
-\r
- // IUnknown methods\r
- STDMETHODIMP QueryInterface(REFIID riid, void **);\r
- STDMETHODIMP_(ULONG) AddRef(void);\r
- STDMETHODIMP_(ULONG) Release(void);\r
-\r
- // IEnumXXXX methods\r
- STDMETHODIMP Next(ULONG, T *, ULONG *);\r
- STDMETHODIMP Skip(ULONG);\r
- STDMETHODIMP Reset(void);\r
- // cloning is implemented by subclasses and must use copy constructor\r
- //STDMETHODIMP Clone(VLCEnum<T> **);\r
- // cloning is implemented by subclasses and must use copy constructor\r
-\r
- typedef void (*retainer)(T);\r
-\r
- void setRetainOperation(retainer retain) { _retain = retain; };\r
-\r
-private:\r
-\r
- LONG _refcount;\r
- std::vector<T> _v;\r
- typename std::vector<T>::iterator _i;\r
- REFIID _riid;\r
- retainer _retain;\r
-};\r
-\r
-template<class T>\r
-VLCEnum<T>::VLCEnum(REFIID riid, std::vector<T> &v) :\r
- _refcount(1),\r
- _v(v),\r
- _riid(riid),\r
- _retain(NULL)\r
-{\r
- _i= v.begin();\r
-};\r
-\r
-template<class T>\r
-VLCEnum<T>::VLCEnum(const VLCEnum<T> &e) :\r
- _refcount(1),\r
- _v(e._v),\r
- _riid(e._riid)\r
-{\r
-};\r
-\r
-template<class T>\r
-VLCEnum<T>& VLCEnum<T>::operator=(const VLCEnum<T> &e)\r
-{\r
- this->_refcount = 1;\r
- this->_riid = e._riid;\r
- this->_v = e._v;\r
- this->_i = e._i;\r
-};\r
-\r
-template<class T>\r
-STDMETHODIMP VLCEnum<T>::QueryInterface(REFIID riid, void **ppv)\r
-{\r
- if( NULL == ppv ) return E_POINTER;\r
- if( (IID_IUnknown == riid) \r
- && ( _riid == riid) ) {\r
- AddRef();\r
- *ppv = reinterpret_cast<LPVOID>(this);\r
- return NOERROR;\r
- }\r
- return E_NOINTERFACE;\r
-};\r
-\r
-template<class T>\r
-STDMETHODIMP_(ULONG) VLCEnum<T>::AddRef(void)\r
-{\r
- return InterlockedIncrement(&_refcount);\r
-};\r
-\r
-template<class T>\r
-STDMETHODIMP_(ULONG) VLCEnum<T>::Release(void)\r
-{\r
- ULONG refcount = InterlockedDecrement(&_refcount);\r
- if( 0 == refcount )\r
- {\r
- delete this;\r
- return 0;\r
- }\r
- return refcount;\r
-};\r
-\r
-template<class T>\r
-STDMETHODIMP VLCEnum<T>::Next(ULONG celt, T *rgelt, ULONG *pceltFetched)\r
-{\r
- if( NULL == rgelt )\r
- return E_POINTER;\r
-\r
- if( (celt > 1) && (NULL == pceltFetched) )\r
- return E_INVALIDARG;\r
-\r
- ULONG c = 0;\r
- typename std::vector<T>::iterator end = _v.end();\r
-\r
- while( (c < celt) && (_i != end) )\r
- {\r
- rgelt[c] = *_i;\r
- if( NULL != _retain ) _retain(rgelt[c]);\r
- ++_i;\r
- ++c;\r
- }\r
-\r
- if( NULL != pceltFetched )\r
- *pceltFetched = c;\r
-\r
- return (c == celt) ? S_OK : S_FALSE;\r
-};\r
-\r
-template<class T>\r
-STDMETHODIMP VLCEnum<T>::Skip(ULONG celt)\r
-{\r
- ULONG c = 0;\r
- typename std::vector<T>::iterator end = _v.end();\r
-\r
- while( (c < celt) && (_i != end) )\r
- {\r
- ++_i;\r
- ++c;\r
- }\r
- return (c == celt) ? S_OK : S_FALSE;\r
-};\r
-\r
-template<class T>\r
-STDMETHODIMP VLCEnum<T>::Reset(void)\r
-{\r
- _i= _v.begin();\r
- return S_OK;\r
-};\r
-\r
-#endif\r
-\r
+/*****************************************************************************
+ * utils.h: ActiveX control for VLC
+ *****************************************************************************
+ * Copyright (C) 2005 the VideoLAN team
+ *
+ * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef __UTILS_H__
+#define __UTILS_H__
+
+#include <ole2.h>
+
+#include <vector>
+
+// utilities
+extern char *CStrFromWSTR(UINT codePage, LPCWSTR wstr, UINT len);
+extern char *CStrFromBSTR(UINT codePage, BSTR bstr);
+extern BSTR BSTRFromCStr(UINT codePage, LPCSTR s);
+
+// properties
+extern HRESULT GetObjectProperty(LPUNKNOWN object, DISPID dispID, VARIANT& v);
+
+// properties
+extern HDC CreateDevDC(DVTARGETDEVICE *ptd);
+extern void DPFromHimetric(HDC hdc, LPPOINT pt, int count);
+extern void HimetricFromDP(HDC hdc, LPPOINT pt, int count);
+
+// URL
+extern LPWSTR CombineURL(LPCWSTR baseUrl, LPCWSTR url);
+
+/**************************************************************************************************/
+
+/* this function object is used to dereference the iterator into a value */
+template <typename T, class Iterator>
+struct VLCDereference
+{
+ T operator()(const Iterator& i) const
+ {
+ return *i;
+ };
+};
+
+template<REFIID EnumeratorIID, class Enumerator, typename T, class Iterator, typename Dereference = VLCDereference<T, Iterator> >
+class VLCEnumIterator : public Enumerator
+{
+
+public:
+
+ VLCEnumIterator(const Iterator& from, const Iterator& to) :
+ _refcount(1),
+ _begin(from),
+ _curr(from),
+ _end(to)
+ {};
+
+ VLCEnumIterator(const VLCEnumIterator& e) :
+ Enumerator(),
+ _refcount(e._refcount),
+ _begin(e._begin),
+ _curr(e._curr),
+ _end(e._end)
+ {};
+
+ virtual ~VLCEnumIterator()
+ {};
+
+ // IUnknown methods
+ STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
+ {
+ if( NULL == ppv )
+ return E_POINTER;
+ if( (IID_IUnknown == riid)
+ || (EnumeratorIID == riid) )
+ {
+ AddRef();
+ *ppv = reinterpret_cast<LPVOID>(this);
+ return NOERROR;
+ }
+ // standalone object
+ return E_NOINTERFACE;
+ };
+
+ STDMETHODIMP_(ULONG) AddRef(void)
+ {
+ return InterlockedIncrement(&_refcount);
+ };
+
+ STDMETHODIMP_(ULONG) Release(void)
+ {
+ ULONG refcount = InterlockedDecrement(&_refcount);
+ if( 0 == refcount )
+ {
+ delete this;
+ return 0;
+ }
+ return refcount;
+ };
+
+
+ // IEnumXXXX methods
+ STDMETHODIMP Next(ULONG celt, T *rgelt, ULONG *pceltFetched)
+ {
+ if( NULL == rgelt )
+ return E_POINTER;
+
+ if( (celt > 1) && (NULL == pceltFetched) )
+ return E_INVALIDARG;
+
+ ULONG c = 0;
+
+ while( (c < celt) && (_curr != _end) )
+ {
+ rgelt[c] = dereference(_curr);
+ ++_curr;
+ ++c;
+ }
+
+ if( NULL != pceltFetched )
+ *pceltFetched = c;
+
+ return (c == celt) ? S_OK : S_FALSE;
+ };
+
+ STDMETHODIMP Skip(ULONG celt)
+ {
+ ULONG c = 0;
+
+ while( (c < celt) && (_curr != _end) )
+ {
+ ++_curr;
+ ++c;
+ }
+ return (c == celt) ? S_OK : S_FALSE;
+ };
+
+ STDMETHODIMP Reset(void)
+ {
+ _curr = _begin;
+ return S_OK;
+ };
+
+ STDMETHODIMP Clone(Enumerator **ppEnum)
+ {
+ if( NULL == ppEnum )
+ return E_POINTER;
+ *ppEnum = dynamic_cast<Enumerator *>(new VLCEnumIterator(*this));
+ return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
+ };
+
+private:
+
+ LONG _refcount;
+ Iterator _begin, _curr, _end;
+
+ Dereference dereference;
+
+};
+
+#endif
+