Changeset 3cf5be6981e175e78056e7923dcac4f942811ea2

Show
Ignore:
Timestamp:
21/09/06 19:01:45 (2 years ago)
Author:
Damien Fouilleul <damienf@videolan.org>
git-committer:
Damien Fouilleul <damienf@videolan.org> 1158858105 +0000
git-parent:

[68cb6a3aff01d9da486f1dc004780d2e7f9a4401]

git-author:
Damien Fouilleul <damienf@videolan.org> 1158858105 +0000
Message:

- ActiveX: optimized implementation of all IEnumXXX classes (more template obfuscation I'm afraid), fixed IConnectionPoints for DCOM

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • activex/connectioncontainer.cpp

    r727b4c3 r3cf5be6  
    3030//////////////////////////////////////////////////////////////////////////////////////////////// 
    3131 
    32 class VLCEnumConnections : public IEnumConnections 
     32/* this function object is used to return the value from a map pair */ 
     33struct VLCEnumConnectionsDereference 
     34
     35    CONNECTDATA operator()(const map<DWORD,LPUNKNOWN>::iterator& i) 
     36    { 
     37        CONNECTDATA cd; 
     38         
     39        cd.dwCookie = i->first; 
     40        cd.pUnk     = i->second; 
     41        return cd; 
     42    }; 
     43}; 
     44 
     45class VLCEnumConnections : public VLCEnumIterator<IID_IEnumConnections, 
     46    IEnumConnections, 
     47    CONNECTDATA, 
     48    map<DWORD,LPUNKNOWN>::iterator, 
     49    VLCEnumConnectionsDereference> 
    3350{ 
    3451public: 
    35     VLCEnumConnections(vector<CONNECTDATA> &v) : 
    36         e(VLCEnum<CONNECTDATA>(IID_IEnumConnections, v)) 
    37     { e.setRetainOperation((VLCEnum<CONNECTDATA>::retainer)&retain); }; 
    38  
    39     VLCEnumConnections(const VLCEnumConnections &vlcEnum) : IEnumConnections(), e(vlcEnum.e) {}; 
    40  
    41     virtual ~VLCEnumConnections() {}; 
    42  
    43     // IUnknown methods 
    44     STDMETHODIMP QueryInterface(REFIID riid, void **ppv) 
    45         { return e.QueryInterface(riid, ppv); }; 
    46     STDMETHODIMP_(ULONG) AddRef(void) 
    47         { return e.AddRef(); }; 
    48     STDMETHODIMP_(ULONG) Release(void) 
    49         {return e.Release(); }; 
    50  
    51     //IEnumConnectionPoints 
    52     STDMETHODIMP Next(ULONG celt, LPCONNECTDATA rgelt, ULONG *pceltFetched) 
    53         { return e.Next(celt, rgelt, pceltFetched); }; 
    54     STDMETHODIMP Skip(ULONG celt) 
    55         { return e.Skip(celt);}; 
    56     STDMETHODIMP Reset(void) 
    57         { return e.Reset();}; 
    58     STDMETHODIMP Clone(LPENUMCONNECTIONS *ppenum) 
    59         { if( NULL == ppenum ) return E_POINTER; 
    60           *ppenum = dynamic_cast<LPENUMCONNECTIONS>(new VLCEnumConnections(*this)); 
    61           return (NULL != *ppenum) ? S_OK : E_OUTOFMEMORY; 
    62         }; 
    63  
    64 private: 
    65  
    66     static void retain(CONNECTDATA cd) 
    67     { 
    68         cd.pUnk->AddRef(); 
    69     }; 
    70  
    71     VLCEnum<CONNECTDATA> e; 
     52    VLCEnumConnections(map<DWORD,LPUNKNOWN> &m) : 
     53        VLCEnumIterator<IID_IEnumConnections, 
     54            IEnumConnections, 
     55            CONNECTDATA, 
     56            map<DWORD,LPUNKNOWN>::iterator, 
     57            VLCEnumConnectionsDereference> (m.begin(), m.end()) 
     58    {}; 
     59}; 
     60 
     61//////////////////////////////////////////////////////////////////////////////////////////////// 
     62 
     63/* this function object is used to retain the dereferenced iterator value */ 
     64struct VLCEnumConnectionPointsDereference 
     65
     66    LPCONNECTIONPOINT operator()(const vector<LPCONNECTIONPOINT>::iterator& i) 
     67    { 
     68        LPCONNECTIONPOINT cp = *i; 
     69        cp->AddRef(); 
     70        return cp; 
     71    } 
     72}; 
     73 
     74class VLCEnumConnectionPoints: public VLCEnumIterator<IID_IEnumConnectionPoints, 
     75    IEnumConnectionPoints, 
     76    LPCONNECTIONPOINT, 
     77    vector<LPCONNECTIONPOINT>::iterator, 
     78    VLCEnumConnectionPointsDereference> 
     79
     80public: 
     81    VLCEnumConnectionPoints(vector<LPCONNECTIONPOINT>& v) : 
     82        VLCEnumIterator<IID_IEnumConnectionPoints, 
     83            IEnumConnectionPoints, 
     84            LPCONNECTIONPOINT, 
     85            vector<LPCONNECTIONPOINT>::iterator, 
     86            VLCEnumConnectionPointsDereference> (v.begin(), v.end()) 
     87    {}; 
    7288}; 
    7389 
     
    95111STDMETHODIMP VLCConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie) 
    96112{ 
     113    static DWORD dwCookieCounter = 0; 
     114 
    97115    if( (NULL == pUnk) || (NULL == pdwCookie) ) 
    98116        return E_POINTER; 
    99117 
    100     CONNECTDATA cd; 
    101  
    102118    pUnk->AddRef(); 
    103     cd.pUnk = pUnk; 
    104     *pdwCookie = cd.dwCookie = _connections.size()+1; 
    105  
    106     _connections.push_back(cd); 
     119 
     120    *pdwCookie = ++dwCookieCounter; 
     121    _connections[*pdwCookie] = pUnk; 
    107122 
    108123    return S_OK; 
     
    111126STDMETHODIMP VLCConnectionPoint::Unadvise(DWORD pdwCookie) 
    112127{ 
    113     if( (0 < pdwCookie) && (pdwCookie <= _connections.size()) ) 
    114     { 
    115         CONNECTDATA cd = _connections[pdwCookie-1]; 
    116         if( NULL != cd.pUnk ) 
    117         { 
    118             cd.pUnk->Release(); 
    119             cd.pUnk = NULL; 
    120             return S_OK; 
    121         } 
     128    map<DWORD,LPUNKNOWN>::iterator pcd = _connections.find((DWORD)pdwCookie); 
     129    if( pcd != _connections.end() ) 
     130    { 
     131        pcd->second->Release(); 
     132 
     133        _connections.erase(pdwCookie); 
     134        return S_OK; 
    122135    } 
    123136    return CONNECT_E_NOCONNECTION; 
     
    136149void VLCConnectionPoint::fireEvent(DISPID dispId, DISPPARAMS *pDispParams) 
    137150{ 
    138     vector<CONNECTDATA>::iterator end = _connections.end(); 
    139     vector<CONNECTDATA>::iterator iter = _connections.begin(); 
     151    map<DWORD,LPUNKNOWN>::iterator end = _connections.end(); 
     152    map<DWORD,LPUNKNOWN>::iterator iter = _connections.begin(); 
    140153 
    141154    while( iter != end ) 
    142155    { 
    143         CONNECTDATA cd = *iter
    144         if( NULL != cd.pUnk ) 
     156        LPUNKNOWN pUnk = iter->second
     157        if( NULL != pUnk ) 
    145158        { 
    146159            IDispatch *pDisp; 
    147             if( SUCCEEDED(cd.pUnk->QueryInterface(IID_IDispatch, (LPVOID *)&pDisp)) ) 
     160            if( SUCCEEDED(pUnk->QueryInterface(IID_IDispatch, (LPVOID *)&pDisp)) ) 
    148161            { 
    149162                pDisp->Invoke(dispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, pDispParams, NULL, NULL, NULL); 
     
    157170void VLCConnectionPoint::firePropChangedEvent(DISPID dispId) 
    158171{ 
    159     vector<CONNECTDATA>::iterator end = _connections.end(); 
    160     vector<CONNECTDATA>::iterator iter = _connections.begin(); 
     172    map<DWORD,LPUNKNOWN>::iterator end = _connections.end(); 
     173    map<DWORD,LPUNKNOWN>::iterator iter = _connections.begin(); 
    161174 
    162175    while( iter != end ) 
    163176    { 
    164         CONNECTDATA cd = *iter
    165         if( NULL != cd.pUnk ) 
     177        LPUNKNOWN pUnk = iter->second
     178        if( NULL != pUnk ) 
    166179        { 
    167180            IPropertyNotifySink *pPropSink; 
    168             if( SUCCEEDED(cd.pUnk->QueryInterface(IID_IPropertyNotifySink, (LPVOID *)&pPropSink)) ) 
     181            if( SUCCEEDED(pUnk->QueryInterface(IID_IPropertyNotifySink, (LPVOID *)&pPropSink)) ) 
    169182            { 
    170183                pPropSink->OnChanged(dispId); 
     
    174187        ++iter; 
    175188    } 
    176 }; 
    177  
    178 //////////////////////////////////////////////////////////////////////////////////////////////// 
    179  
    180 class VLCEnumConnectionPoints : public IEnumConnectionPoints 
    181 { 
    182 public: 
    183     VLCEnumConnectionPoints(vector<LPCONNECTIONPOINT> &v) : 
    184         e(VLCEnum<LPCONNECTIONPOINT>(IID_IEnumConnectionPoints, v)) 
    185     { e.setRetainOperation((VLCEnum<LPCONNECTIONPOINT>::retainer)&retain); }; 
    186  
    187     VLCEnumConnectionPoints(const VLCEnumConnectionPoints &vlcEnum) : IEnumConnectionPoints(), e(vlcEnum.e) {}; 
    188  
    189     virtual ~VLCEnumConnectionPoints() {}; 
    190  
    191     // IUnknown methods 
    192     STDMETHODIMP QueryInterface(REFIID riid, void **ppv) 
    193         { return e.QueryInterface(riid, ppv); }; 
    194     STDMETHODIMP_(ULONG) AddRef(void) 
    195         { return e.AddRef(); }; 
    196     STDMETHODIMP_(ULONG) Release(void) 
    197         {return e.Release(); }; 
    198  
    199     //IEnumConnectionPoints 
    200     STDMETHODIMP Next(ULONG celt, LPCONNECTIONPOINT *rgelt, ULONG *pceltFetched) 
    201         { return e.Next(celt, rgelt, pceltFetched); }; 
    202     STDMETHODIMP Skip(ULONG celt) 
    203         { return e.Skip(celt);}; 
    204     STDMETHODIMP Reset(void) 
    205         { return e.Reset();}; 
    206     STDMETHODIMP Clone(LPENUMCONNECTIONPOINTS *ppenum) 
    207         { if( NULL == ppenum ) return E_POINTER; 
    208           *ppenum = dynamic_cast<LPENUMCONNECTIONPOINTS>(new VLCEnumConnectionPoints(*this)); 
    209           return (NULL != *ppenum) ? S_OK : E_OUTOFMEMORY; 
    210         }; 
    211  
    212 private: 
    213  
    214     static void retain(LPCONNECTIONPOINT cp) 
    215     { 
    216         cp->AddRef(); 
    217     }; 
    218  
    219     VLCEnum<LPCONNECTIONPOINT> e; 
    220189}; 
    221190 
  • activex/connectioncontainer.h

    r054049c r3cf5be6  
    2727#include <vector> 
    2828#include <queue> 
     29#include <map> 
    2930 
    3031class VLCConnectionPoint : public IConnectionPoint 
     
    7071    REFIID _iid; 
    7172    IConnectionPointContainer *_p_cpc; 
    72     std::vector<CONNECTDATA> _connections; 
     73    std::map<DWORD, LPUNKNOWN> _connections; 
    7374}; 
    7475 
  • activex/dataobject.cpp

    r727b4c3 r3cf5be6  
    2727 
    2828using namespace std; 
    29  
    30 //////////////////////////////////////////////////////////////////////////////////////////////// 
    31  
    32 class VLCEnumFORMATETC : public IEnumFORMATETC 
    33 { 
    34 public: 
    35  
    36     VLCEnumFORMATETC(vector<FORMATETC> &v) : 
    37         e(VLCEnum<FORMATETC>(IID_IEnumFORMATETC, v)) {}; 
    38  
    39     VLCEnumFORMATETC(const VLCEnumFORMATETC &vlcEnum) : IEnumFORMATETC(), e(vlcEnum.e) {}; 
    40     virtual ~VLCEnumFORMATETC() {}; 
    41  
    42     // IUnknown methods 
    43     STDMETHODIMP QueryInterface(REFIID riid, void **ppv) 
    44         { return e.QueryInterface(riid, ppv); }; 
    45     STDMETHODIMP_(ULONG) AddRef(void) 
    46         { return e.AddRef(); }; 
    47     STDMETHODIMP_(ULONG) Release(void) 
    48         {return e.Release(); }; 
    49  
    50     //IEnumConnectionPoints 
    51     STDMETHODIMP Next(ULONG celt, LPFORMATETC rgelt, ULONG *pceltFetched) 
    52         { return e.Next(celt, rgelt, pceltFetched); }; 
    53     STDMETHODIMP Skip(ULONG celt) 
    54         { return e.Skip(celt);}; 
    55     STDMETHODIMP Reset(void) 
    56         { return e.Reset();}; 
    57     STDMETHODIMP Clone(LPENUMFORMATETC *ppenum) 
    58         { if( NULL == ppenum ) return E_POINTER; 
    59           *ppenum = dynamic_cast<LPENUMFORMATETC>(new VLCEnumFORMATETC(*this)); 
    60           return (NULL != *ppenum) ? S_OK : E_OUTOFMEMORY; 
    61         }; 
    62  
    63 private: 
    64  
    65     VLCEnum<FORMATETC> e; 
    66 }; 
    6729 
    6830//////////////////////////////////////////////////////////////////////////////////////////////// 
     
    8547    }; 
    8648 
     49class VLCEnumFORMATETC : public VLCEnumIterator<IID_IEnumFORMATETC, 
     50    IEnumFORMATETC, 
     51    FORMATETC, 
     52    vector<FORMATETC>::iterator> 
     53{ 
     54public: 
     55    VLCEnumFORMATETC(vector<FORMATETC> v) : 
     56        VLCEnumIterator<IID_IEnumFORMATETC, 
     57        IEnumFORMATETC, 
     58        FORMATETC, 
     59        vector<FORMATETC>::iterator>(v.begin(), v.end()) 
     60    {}; 
     61}; 
     62 
     63//////////////////////////////////////////////////////////////////////////////////////////////// 
     64 
    8765VLCDataObject::VLCDataObject(VLCPlugin *p_instance) : _p_instance(p_instance) 
    8866{ 
     
    11593}; 
    11694 
    117 STDMETHODIMP VLCDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumformatetc) 
    118 
    119     if( NULL == ppenumformatetc ) 
    120         return E_POINTER; 
    121  
    122     *ppenumformatetc = new VLCEnumFORMATETC(_v_formatEtc); 
    123     return NOERROR; 
     95STDMETHODIMP VLCDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppEnum) 
     96
     97    if( NULL == ppEnum ) 
     98        return E_POINTER; 
     99 
     100    *ppEnum = dynamic_cast<IEnumFORMATETC *>(new VLCEnumFORMATETC(_v_formatEtc)); 
     101 
     102    return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY; 
    124103}; 
    125104 
  • activex/utils.h

    r727b4c3 r3cf5be6  
    4444/**************************************************************************************************/ 
    4545 
    46 // enumeration 
    47 template<class T> class VLCEnum : IUnknown 
     46/* this function object is used to dereference the iterator into a value */ 
     47template <class T, class Iterator> 
     48struct VLCDereference 
     49
     50    T operator()(const Iterator& i) const 
     51    { 
     52        return *i; 
     53    }; 
     54}; 
     55 
     56template<REFIID EnumeratorIID, class Enumerator, class T, class Iterator, typename Dereference = VLCDereference<T, Iterator> > 
     57class VLCEnumIterator : public Enumerator 
    4858{ 
    4959 
    5060public: 
    5161 
    52     VLCEnum(REFIID riid, std::vector<T> &); 
    53     VLCEnum(const VLCEnum<T> &); 
    54     virtual ~VLCEnum() {}; 
     62    VLCEnumIterator(const Iterator& from, const Iterator& to) : 
     63        _refcount(1), 
     64        _begin(from), 
     65        _curr(from), 
     66        _end(to) 
     67    {}; 
    5568 
    56     VLCEnum<T>& operator=(const VLCEnum<T> &t); 
     69    VLCEnumIterator(const VLCEnumIterator& e) : 
     70        Enumerator(), 
     71        _refcount(e._refcount), 
     72        _begin(e._begin), 
     73        _curr(e._curr), 
     74        _end(e._end) 
     75    {}; 
     76 
     77    virtual ~VLCEnumIterator() 
     78    {}; 
    5779 
    5880    // IUnknown methods 
    59     STDMETHODIMP QueryInterface(REFIID riid, void **); 
    60     STDMETHODIMP_(ULONG) AddRef(void); 
    61     STDMETHODIMP_(ULONG) Release(void); 
     81    STDMETHODIMP QueryInterface(REFIID riid, void **ppv) 
     82    { 
     83        if( NULL == ppv ) 
     84            return E_POINTER; 
     85        if( (IID_IUnknown == riid)  
     86         || (EnumeratorIID == riid) ) 
     87        { 
     88            AddRef(); 
     89            *ppv = reinterpret_cast<LPVOID>(this); 
     90            return NOERROR; 
     91        } 
     92        // standalone object 
     93        return E_NOINTERFACE; 
     94    }; 
     95 
     96    STDMETHODIMP_(ULONG) AddRef(void) 
     97    { 
     98        return InterlockedIncrement(&_refcount); 
     99    }; 
     100 
     101    STDMETHODIMP_(ULONG) Release(void) 
     102    { 
     103        ULONG refcount = InterlockedDecrement(&_refcount); 
     104        if( 0 == refcount ) 
     105        { 
     106            delete this; 
     107            return 0; 
     108        } 
     109        return refcount; 
     110    }; 
     111 
    62112 
    63113    // IEnumXXXX methods 
    64     STDMETHODIMP Next(ULONG, T *, ULONG *); 
    65     STDMETHODIMP Skip(ULONG); 
    66     STDMETHODIMP Reset(void); 
    67     // cloning is implemented by subclasses and must use copy constructor 
    68     //STDMETHODIMP Clone(VLCEnum<T> **); 
     114    STDMETHODIMP Next(ULONG celt, T *rgelt, ULONG *pceltFetched) 
     115    { 
     116        if( NULL == rgelt ) 
     117            return E_POINTER; 
    69118 
    70     typedef void (*retainer)(T); 
     119        if( (celt > 1) && (NULL == pceltFetched) ) 
     120            return E_INVALIDARG; 
    71121 
    72     void setRetainOperation(retainer retain) { _retain = retain; }; 
     122        ULONG c = 0; 
     123 
     124        while( (c < celt) && (_curr != _end) ) 
     125        { 
     126            rgelt[c] = dereference(_curr); 
     127            ++_curr; 
     128            ++c; 
     129        } 
     130 
     131        if( NULL != pceltFetched ) 
     132            *pceltFetched = c; 
     133 
     134        return (c == celt) ? S_OK : S_FALSE; 
     135    }; 
     136 
     137    STDMETHODIMP Skip(ULONG celt) 
     138    { 
     139        ULONG c = 0; 
     140 
     141        while( (c < celt) && (_curr != _end) ) 
     142        { 
     143            ++_curr; 
     144            ++c; 
     145        } 
     146        return (c == celt) ? S_OK : S_FALSE; 
     147    }; 
     148 
     149    STDMETHODIMP Reset(void) 
     150    { 
     151        _curr = _begin; 
     152        return S_OK; 
     153    }; 
     154 
     155    STDMETHODIMP Clone(Enumerator **ppEnum) 
     156    { 
     157        if( NULL == ppEnum ) 
     158            return E_POINTER; 
     159        *ppEnum = dynamic_cast<Enumerator *>(new VLCEnumIterator(*this)); 
     160        return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY; 
     161    }; 
    73162 
    74163private: 
    75164 
    76     LONG                                _refcount; 
    77     std::vector<T>                      _v; 
    78     typename std::vector<T>::iterator   _i; 
    79     REFIID                              _riid; 
    80     retainer                            _retain; 
    81 }; 
     165    LONG     _refcount; 
     166    Iterator _begin, _curr, _end; 
    82167 
    83 template<class T> 
    84 VLCEnum<T>::VLCEnum(REFIID riid, std::vector<T> &v) : 
    85     _refcount(1), 
    86     _v(v), 
    87     _riid(riid), 
    88     _retain(NULL) 
    89 
    90     _i= v.begin(); 
    91 }; 
     168    Dereference dereference; 
    92169 
    93 template<class T> 
    94 VLCEnum<T>::VLCEnum(const VLCEnum<T> &e) : 
    95     IUnknown(), 
    96     _refcount(1), 
    97     _v(e._v), 
    98     _riid(e._riid) 
    99 { 
    100 }; 
    101  
    102 template<class T> 
    103 VLCEnum<T>& VLCEnum<T>::operator=(const VLCEnum<T> &e) 
    104 { 
    105     this->_refcount = 1; 
    106     this->_riid = e._riid; 
    107     this->_v    = e._v; 
    108     this->_i    = e._i; 
    109     return this; 
    110 }; 
    111  
    112 template<class T> 
    113 STDMETHODIMP VLCEnum<T>::QueryInterface(REFIID riid, void **ppv) 
    114 { 
    115     if( NULL == ppv ) 
    116         return E_POINTER; 
    117     if( (IID_IUnknown == riid)  
    118      || (_riid == riid) ) 
    119     { 
    120         AddRef(); 
    121         *ppv = reinterpret_cast<LPVOID>(this); 
    122         return NOERROR; 
    123     } 
    124     // standalone object 
    125     return E_NOINTERFACE; 
    126 }; 
    127  
    128 template<class T> 
    129 STDMETHODIMP_(ULONG) VLCEnum<T>::AddRef(void) 
    130 { 
    131     return InterlockedIncrement(&_refcount); 
    132 }; 
    133  
    134 template<class T> 
    135 STDMETHODIMP_(ULONG) VLCEnum<T>::Release(void) 
    136 { 
    137     ULONG refcount = InterlockedDecrement(&_refcount); 
    138     if( 0 == refcount ) 
    139     { 
    140         delete this; 
    141         return 0; 
    142     } 
    143     return refcount; 
    144 }; 
    145  
    146 template<class T> 
    147 STDMETHODIMP VLCEnum<T>::Next(ULONG celt, T *rgelt, ULONG *pceltFetched) 
    148 { 
    149     if( NULL == rgelt ) 
    150         return E_POINTER; 
    151  
    152     if( (celt > 1) && (NULL == pceltFetched) ) 
    153         return E_INVALIDARG; 
    154  
    155     ULONG c = 0; 
    156     typename std::vector<T>::iterator end = _v.end(); 
    157  
    158     while( (c < celt) && (_i != end) ) 
    159     { 
    160         rgelt[c] = *_i; 
    161         if( NULL != _retain ) _retain(rgelt[c]); 
    162         ++_i; 
    163         ++c; 
    164     } 
    165  
    166     if( NULL != pceltFetched ) 
    167         *pceltFetched = c; 
    168  
    169     return (c == celt) ? S_OK : S_FALSE; 
    170 }; 
    171  
    172 template<class T> 
    173 STDMETHODIMP VLCEnum<T>::Skip(ULONG celt) 
    174 { 
    175     ULONG c = 0; 
    176     typename std::vector<T>::iterator end = _v.end(); 
    177  
    178     while( (c < celt) && (_i != end) ) 
    179     { 
    180         ++_i; 
    181         ++c; 
    182     } 
    183     return (c == celt) ? S_OK : S_FALSE; 
    184 }; 
    185  
    186 template<class T> 
    187 STDMETHODIMP VLCEnum<T>::Reset(void) 
    188 { 
    189     _i= _v.begin(); 
    190     return S_OK; 
    191170}; 
    192171