⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 persiststreaminit.cpp

📁 VLC Player Source Code
💻 CPP
字号:
/***************************************************************************** * persiststreaminit.cpp: 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. *****************************************************************************/#include "plugin.h"#include "persiststreaminit.h"#include "utils.h"#include <map>#include <malloc.h>#include <wchar.h>using namespace std;class AxVLCVariant{public:    AxVLCVariant(void)    {        VariantInit(&_v);    };    ~AxVLCVariant(void)    {        VariantClear(&_v);    }    AxVLCVariant(VARIANTARG &v)    {        VariantInit(&_v);        VariantCopy(&_v, &v);    };    AxVLCVariant(VARIANTARG *v)    {        VariantInit(&_v);        VariantCopy(&_v, v);    };    AxVLCVariant(const AxVLCVariant &vv)    {        VariantInit(&_v);        VariantCopy(&_v, const_cast<VARIANTARG *>(&(vv._v)));    };    AxVLCVariant(int i)    {        V_VT(&_v) = VT_I4;        V_I4(&_v) = i;    };    AxVLCVariant(BSTR bstr)    {        VARIANT arg;        V_VT(&arg) = VT_BSTR;        V_BSTR(&arg) = bstr;        VariantInit(&_v);        VariantCopy(&_v, &arg);    };    inline const VARIANTARG *variantArg(void) const {        return &_v;    }    inline void swap(AxVLCVariant &v1, AxVLCVariant &v2)    {        VARIANTARG tmp = v1._v;        v1._v = v2._v;        v2._v = tmp;    };private:    VARIANTARG _v;};class AxVLCWSTR{public:    AxVLCWSTR(void) : _data(NULL) {};    virtual ~AxVLCWSTR()    {        if( NULL != _data )        {            ULONG refcount = InterlockedDecrement(&(_data->refcount));            if( 0 == refcount )                CoTaskMemFree(_data);        }    };    AxVLCWSTR(LPCWSTR s)    {        if( NULL != s )        {            size_t len = wcslen(s);            if( len > 0 )            {                size_t size = len*sizeof(WCHAR);                _data = (struct data *)CoTaskMemAlloc(sizeof(struct data)+size);                if( NULL != _data )                {                    _data->len = len;                    _data->refcount = 1;                    memcpy(_data->wstr, s, size);                    _data->wstr[len]=L'\0';                    return;                }            }        }        _data = NULL;    };    AxVLCWSTR(const AxVLCWSTR &s)    {        _data = s._data;        if( NULL != _data )            InterlockedIncrement(&(_data->refcount));    };    inline bool operator<(const AxVLCWSTR &s) const    {        return compareNoCase(s.wstr()) < 0;    };    inline bool operator<(LPCWSTR s) const    {        return compareNoCase(s) < 0;    };    inline bool operator==(const AxVLCWSTR &s) const    {        return size() == s.size() ?                    (compareNoCase(s.wstr()) == 0) : false;    };    inline bool operator==(LPCWSTR s) const    {        return compareNoCase(s) == 0;    };    LPCWSTR wstr(void) const    {        return (NULL != _data) ? _data->wstr : NULL;    };    size_t size(void) const    {        return (NULL != _data) ? _data->len : 0;    };private:    inline int compareNoCase(LPCWSTR s) const    {        if( NULL == _data )        {            return (NULL == s) ? 0 : -1;        }        if( NULL == s )            return 1;        return _wcsicmp(_data->wstr, s);    };    struct data {        size_t  len;        LONG    refcount;        wchar_t wstr[1];    } *_data;};typedef pair<class AxVLCWSTR, class AxVLCVariant> AxVLCPropertyPair;typedef map<class AxVLCWSTR, class AxVLCVariant> AxVLCPropertyMap;///////////////////////////class VLCPropertyBag : public IPropertyBag{public:    VLCPropertyBag(void) : _i_ref(1) {};    virtual ~VLCPropertyBag() {};    // IUnknown methods    STDMETHODIMP QueryInterface(REFIID riid, void **ppv)    {        if( NULL == ppv )            return E_POINTER;        if( (IID_IUnknown == riid)         || (IID_IPropertyBag == riid) )        {            AddRef();            *ppv = reinterpret_cast<LPVOID>(this);            return NOERROR;        }        // standalone object        return E_NOINTERFACE;    };    STDMETHODIMP_(ULONG) AddRef(void)        { return InterlockedIncrement(&_i_ref); };    STDMETHODIMP_(ULONG) Release(void)    {        ULONG refcount = InterlockedDecrement(&_i_ref);        if( 0 == refcount )        {            delete this;            return 0;        }        return refcount;    };    // IPropertyBag methods    STDMETHODIMP Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog)    {        if( (NULL == pszPropName) || (NULL == pVar) )            return E_POINTER;        AxVLCPropertyMap::const_iterator notfound = _pm.end();        AxVLCPropertyMap::const_iterator iter = _pm.find(pszPropName);        if( notfound != iter )        {            VARTYPE vtype = V_VT(pVar);            VARIANTARG v;            VariantInit(&v);            VariantCopy(&v, const_cast<VARIANTARG*>((*iter).second.variantArg()));            if( (V_VT(&v) != vtype) && FAILED(VariantChangeType(&v, &v, 0, vtype)) )            {                VariantClear(&v);                return E_FAIL;            }            *pVar = v;            return S_OK;        }        else            return E_INVALIDARG;    };     STDMETHODIMP Write(LPCOLESTR pszPropName, VARIANT *pVar)    {        if( (NULL == pszPropName) || (NULL == pVar) )            return E_POINTER;        AxVLCPropertyPair val(pszPropName, pVar);        pair<AxVLCPropertyMap::iterator, bool> p = _pm.insert(val);        if( false == p.second )            // replace existing key value            (*p.first).second = val.second;        return S_OK;    };    // custom methods    HRESULT Load(LPSTREAM pStm)    {        if( NULL == pStm )            return E_INVALIDARG;        HRESULT result;        AxVLCPropertyPair *val;        result = ReadProperty(pStm, &val);        if( SUCCEEDED(result) )        {            if( (val->first == L"(Count)") && (VT_I4 == V_VT(val->second.variantArg())) )            {                size_t count = V_I4(val->second.variantArg());                delete val;                while( count-- )                {                    result = ReadProperty(pStm, &val);                    if( FAILED(result) )                        return result;                    pair<AxVLCPropertyMap::iterator, bool> p = _pm.insert(*val);                    if( false == p.second )                        // replace existing key value                        (*p.first).second = val->second;                    delete val;                }            }        }        return result;    };    HRESULT Save(LPSTREAM pStm)    {        if( NULL == pStm )            return E_INVALIDARG;        HRESULT result;        AxVLCPropertyPair header(L"(Count)", _pm.size());        result = WriteProperty(pStm, header);        if( SUCCEEDED(result) )        {            AxVLCPropertyMap::const_iterator iter = _pm.begin();            AxVLCPropertyMap::const_iterator end  = _pm.end();            while( iter != end )            {                result = WriteProperty(pStm, *(iter++));                if( FAILED(result) )                    return result;            }        }        return result;    };    BOOL IsEmpty()    {        return _pm.size() == 0;    }private:    HRESULT WriteProperty(LPSTREAM pStm, const AxVLCPropertyPair &prop)    {        HRESULT result;        const AxVLCWSTR propName = prop.first;        ULONG len = propName.size();        if( 0 == len )            return E_INVALIDARG;        result = pStm->Write(&len, sizeof(len), NULL);        if( FAILED(result) )            return result;        result = pStm->Write(propName.wstr(), len*sizeof(WCHAR), NULL);        if( FAILED(result) )            return result;        const VARIANTARG *propValue = prop.second.variantArg();        VARTYPE vtype = V_VT(propValue);        switch( vtype )        {            case VT_BOOL:                result = pStm->Write(&vtype, sizeof(vtype), NULL);                if( FAILED(result) )                    return result;                result = pStm->Write(&V_BOOL(propValue), sizeof(V_BOOL(propValue)), NULL);                if( FAILED(result) )                    return result;                break;            case VT_I4:                result = pStm->Write(&vtype, sizeof(vtype), NULL);                if( FAILED(result) )                    return result;                result = pStm->Write(&V_I4(propValue), sizeof(V_I4(propValue)), NULL);                if( FAILED(result) )                    return result;                break;            case VT_BSTR:                result = pStm->Write(&vtype, sizeof(vtype), NULL);                if( FAILED(result) )                    return result;                len = SysStringLen(V_BSTR(propValue));                result = pStm->Write(&len, sizeof(len), NULL);                if( FAILED(result) )                    return result;                if( len > 0 )                {                    result = pStm->Write(V_BSTR(propValue), len*sizeof(OLECHAR), NULL);                    if( FAILED(result) )                        return result;                }                break;            default:                vtype = VT_EMPTY;                result = pStm->Write(&vtype, sizeof(vtype), NULL);                if( FAILED(result) )                    return result;        }        return result;    };    HRESULT ReadProperty(LPSTREAM pStm, AxVLCPropertyPair **prop)    {        HRESULT result;        ULONG len;        result = pStm->Read(&len, sizeof(len), NULL);        if( FAILED(result) )            return result;        if( 0 == len )            return E_INVALIDARG;        LPWSTR propName = (LPOLESTR)::alloca((len+1)*sizeof(WCHAR));        if( NULL == propName )            return E_OUTOFMEMORY;        result = pStm->Read(propName, len*sizeof(WCHAR), NULL);        if( FAILED(result) )            return result;        propName[len] = L'\0';        VARIANTARG propValue;        VARTYPE vtype;        result = pStm->Read(&vtype, sizeof(vtype), NULL);        if( FAILED(result) )            return result;        switch( vtype )        {            case VT_BOOL:                V_VT(&propValue) = vtype;                result = pStm->Read(&V_BOOL(&propValue), sizeof(V_BOOL(&propValue)), NULL);                if( FAILED(result) )                    return result;                break;            case VT_I4:                V_VT(&propValue) = vtype;                result = pStm->Read(&V_I4(&propValue), sizeof(V_I4(&propValue)), NULL);                if( FAILED(result) )                    return result;                break;            case VT_BSTR:                V_VT(&propValue) = vtype;                result = pStm->Read(&len, sizeof(len), NULL);                if( FAILED(result) )                    return result;                V_BSTR(&propValue) = NULL;                if( len > 0 )                {                    V_BSTR(&propValue) = SysAllocStringLen(NULL, len);                    if( NULL == V_BSTR(&propValue) )                        return E_OUTOFMEMORY;                    result = pStm->Read(V_BSTR(&propValue), len*sizeof(OLECHAR), NULL);                    if( FAILED(result) )                    {                        SysFreeString(V_BSTR(&propValue));                        return result;                    }                }                break;            default:                VariantInit(&propValue);        }        *prop = new AxVLCPropertyPair(propName, propValue);        return S_OK;    };    AxVLCPropertyMap _pm;    LONG _i_ref;};///////////////////////////VLCPersistStreamInit::VLCPersistStreamInit(VLCPlugin *p_instance) : _p_instance(p_instance){    _p_props = new VLCPropertyBag();};VLCPersistStreamInit::~VLCPersistStreamInit(){    _p_props->Release();};STDMETHODIMP VLCPersistStreamInit::GetClassID(LPCLSID pClsID){    if( NULL == pClsID )        return E_POINTER;    *pClsID = _p_instance->getClassID();    return S_OK;};STDMETHODIMP VLCPersistStreamInit::InitNew(void){    return _p_instance->onInit();};STDMETHODIMP VLCPersistStreamInit::Load(LPSTREAM pStm){    HRESULT result = _p_props->Load(pStm);    if( FAILED(result) )        return result;    LPPERSISTPROPERTYBAG pPersistPropBag;    if( FAILED(QueryInterface(IID_IPersistPropertyBag, (void**)&pPersistPropBag)) )        return E_FAIL;    result = pPersistPropBag->Load(_p_props, NULL);    pPersistPropBag->Release();    return result;};STDMETHODIMP VLCPersistStreamInit::Save(LPSTREAM pStm, BOOL fClearDirty){    if( NULL == pStm )        return E_INVALIDARG;    LPPERSISTPROPERTYBAG pPersistPropBag;    if( FAILED(QueryInterface(IID_IPersistPropertyBag, (void**)&pPersistPropBag)) )        return E_FAIL;    HRESULT result = pPersistPropBag->Save(_p_props, fClearDirty, _p_props->IsEmpty());    pPersistPropBag->Release();    if( FAILED(result) )        return result;    return _p_props->Save(pStm);};STDMETHODIMP VLCPersistStreamInit::IsDirty(void){    return _p_instance->isDirty() ? S_OK : S_FALSE;};STDMETHODIMP VLCPersistStreamInit::GetSizeMax(ULARGE_INTEGER *pcbSize){    pcbSize->HighPart = 0UL;    pcbSize->LowPart  = 16384UL; // just a guess    return S_OK;};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -