diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Winamp/JSAPI_CallbackParameters.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Winamp/JSAPI_CallbackParameters.cpp')
-rw-r--r-- | Src/Winamp/JSAPI_CallbackParameters.cpp | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/Src/Winamp/JSAPI_CallbackParameters.cpp b/Src/Winamp/JSAPI_CallbackParameters.cpp new file mode 100644 index 00000000..281159da --- /dev/null +++ b/Src/Winamp/JSAPI_CallbackParameters.cpp @@ -0,0 +1,384 @@ +#include "JSAPI_CallbackParameters.h" +#include "JSAPI.h" + +JSAPI::CallbackParameters::CallbackParameters() +{ + refCount = 1; +} + +JSAPI::CallbackParameters::~CallbackParameters() +{ + //for (size_t p=0;p!=params.size();p++) + //{ + // ParameterList::value_type &property = params.at(p); + // // some types need to be specifically destroyed or released + // switch(property.second.vt) + // { + // case VT_DISPATCH: // add a reference if it's an IDispatch + // property.second.pdispVal->Release(); + // break; + // case VT_BSTR: // re-allocate + // SysFreeString(property.second.bstrVal); + // break; + // } + //} + for (auto ¶m : params) + { + // some types need to be specifically destroyed or released + switch(param.second.vt) + { + case VT_DISPATCH: // add a reference if it's an IDispatch + param.second.pdispVal->Release(); + break; + case VT_BSTR: // re-allocate + SysFreeString(param.second.bstrVal); + break; + } + } +} + +HRESULT JSAPI::CallbackParameters::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid) +{ + bool unknowns = false; + for (unsigned int i = 0;i != cNames;i++) + { + rgdispid[i] = DISPID_UNKNOWN; + const wchar_t *propertyName = rgszNames[i]; + + bool found=false; + //for (size_t p=0;p!=params.size();p++) + size_t p = 0; + for(auto it = params.begin(); it != params.end(); it++, p++) + { + //ParameterList::value_type &property = params.at(p); + if (!wcscmp(it->first.c_str(), propertyName)) + { + found=true; + rgdispid[i] = (DISPID)p; + break; + } + } + if (!found) + unknowns=true; + } + + if (unknowns) + return DISP_E_UNKNOWNNAME; + else + return S_OK; +} + +HRESULT JSAPI::CallbackParameters::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr) +{ + JSAPI_VERIFY_PARAMCOUNT(pdispparams, 0); + size_t index = (size_t)dispid; + if (index>=params.size()) + return DISP_E_MEMBERNOTFOUND; + if (wFlags & DISPATCH_PROPERTYGET) + { + if (pvarResult) + { + //ParameterList::value_type &property = params.at(index); + auto it = params.begin(); + while (index--) + { + it++; + } + + *pvarResult = it->second; + // do any type-specific allocations that are necessary + switch(pvarResult->vt) + { + case VT_DISPATCH: // add a reference if it's an IDispatch + pvarResult->pdispVal->AddRef(); + break; + case VT_BSTR: // re-allocate + pvarResult->bstrVal = SysAllocString(pvarResult->bstrVal); + break; + } + } + return S_OK; + } + else + return DISP_E_MEMBERNOTFOUND; +} + + +HRESULT JSAPI::CallbackParameters::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo) +{ + return E_NOTIMPL; +} + +HRESULT JSAPI::CallbackParameters::GetTypeInfoCount(unsigned int FAR * pctinfo) +{ + return E_NOTIMPL; +} + +STDMETHODIMP JSAPI::CallbackParameters::QueryInterface(REFIID riid, PVOID *ppvObject) +{ + if (!ppvObject) + return E_POINTER; + + else if (IsEqualIID(riid, IID_IDispatch)) + *ppvObject = (IDispatch *)this; + else if (IsEqualIID(riid, IID_IUnknown)) + *ppvObject = this; + else if (IsEqualIID(riid, IID_IDispatchEx)) + *ppvObject = (IDispatchEx *)this; + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + + AddRef(); + return S_OK; +} + +ULONG JSAPI::CallbackParameters::AddRef(void) +{ + return InterlockedIncrement(&refCount); +} + + +ULONG JSAPI::CallbackParameters::Release(void) +{ + LONG lRef = InterlockedDecrement(&refCount); + if (lRef == 0) delete this; + return lRef; +} + +HRESULT JSAPI::CallbackParameters::GetDispID(BSTR bstrName, DWORD grfdex, DISPID *pid) +{ + //for (size_t p=0;p!=params.size();p++) + //{ + // ParameterList::value_type &property = params.at(p); + // if (!wcscmp(property.first.c_str(), bstrName)) + // { + // *pid= (DISPID)p; + // return S_OK; + // } + //} + size_t p = 0; + for (auto it = params.begin(); it != params.end(); it++, p++) + { + if (!wcscmp(it->first.c_str(), bstrName)) + { + *pid = (DISPID)p; + return S_OK; + } + } + + return DISP_E_MEMBERNOTFOUND; +} + +HRESULT JSAPI::CallbackParameters::InvokeEx(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + JSAPI_VERIFY_PARAMCOUNT(pdp, 0); + size_t index = (size_t)id; + if (index>=params.size()) + return DISP_E_MEMBERNOTFOUND; + if (wFlags & DISPATCH_PROPERTYGET) + { + if (pvarRes) + { + //ParameterList::value_type &property = params.at(index); + auto it = params.begin(); + while (index--) + { + it++; + } + + *pvarRes = it->second; + // do any type-specific allocations that are necessary + switch(pvarRes->vt) + { + case VT_DISPATCH: // add a reference if it's an IDispatch + pvarRes->pdispVal->AddRef(); + break; + case VT_BSTR: // re-allocate + pvarRes->bstrVal = SysAllocString(pvarRes->bstrVal); + break; + } + } + return S_OK; + } + else + return DISP_E_MEMBERNOTFOUND; + +} + +HRESULT JSAPI::CallbackParameters::DeleteMemberByName(BSTR bstrName, DWORD grfdex) +{ + return E_NOTIMPL; +} + +HRESULT JSAPI::CallbackParameters::DeleteMemberByDispID(DISPID id) +{ + return E_NOTIMPL; +} + +HRESULT JSAPI::CallbackParameters::GetMemberProperties(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex) +{ + return E_NOTIMPL; +} + +HRESULT JSAPI::CallbackParameters::GetMemberName(DISPID id, BSTR *pbstrName) +{ + if (id >= 0 && (size_t)id < params.size()) + { + auto it = params.begin(); + while (id--) + { + it++; + } + *pbstrName = SysAllocString(it->first.c_str()); + return S_OK; + } + return E_NOTIMPL; +} + +HRESULT JSAPI::CallbackParameters::GetNextDispID(DWORD grfdex, DISPID id, DISPID *pid) +{ + if (grfdex == fdexEnumDefault) + { + if (id == DISPID_UNKNOWN) + { + if (params.size() == 0) + return S_FALSE; + else + { + *pid = 0; + return S_OK; + } + } + else + { + size_t index = id+1; + if (index >= params.size()) + { + return S_FALSE; + } + else + { + *pid = (DISPID)index; + return S_OK; + } + + } + } + + return E_NOTIMPL; +} + +HRESULT JSAPI::CallbackParameters::GetNameSpaceParent(IUnknown **ppunk) +{ + return E_NOTIMPL; +} + +void JSAPI::CallbackParameters::AddProperty(const wchar_t *name, const VARIANT &property) +{ + params[name]=property; +} + +void JSAPI::CallbackParameters::AddString(const wchar_t *name, const wchar_t *value) +{ + VARIANT bstrVar; + V_VT(&bstrVar) = VT_BSTR; + V_BSTR(&bstrVar) = SysAllocString(value); + AddProperty(name, bstrVar); +} + +void JSAPI::CallbackParameters::AddDispatch(const wchar_t *name, IDispatch *disp) +{ + VARIANT dispVar; + V_VT(&dispVar) = VT_DISPATCH; + V_DISPATCH(&dispVar) = disp; + disp->AddRef(); + AddProperty(name, dispVar); +} + +void JSAPI::CallbackParameters::AddLong(const wchar_t *name, LONG value) +{ + VARIANT i4Var; + V_VT(&i4Var) = VT_I4; + V_I4(&i4Var) = value; + AddProperty(name, i4Var); +} + +void JSAPI::CallbackParameters::AddBoolean(const wchar_t *name, bool value) +{ + VARIANT boolVar; + V_VT(&boolVar) = VT_BOOL; + V_BOOL(&boolVar) = value?VARIANT_TRUE:VARIANT_FALSE; + AddProperty(name, boolVar); +} + +size_t JSAPI::CallbackParameters::AddPropertyIndirect(const JSAPI::CallbackParameters::PropertyTemplate *entries, size_t count) +{ + if (NULL == entries) return 0; + + size_t inserted = 0; + VARIANT val; + + for (size_t i = 0; i < count; i++) + { + const PropertyTemplate *ppt = &entries[i]; + if (NULL == ppt->name) + continue; + + switch(ppt->type) + { + case typeBool: + V_VT(&val) = VT_BOOL; + V_BOOL(&val) = (FALSE != ((BOOL)ppt->value)) ? VARIANT_TRUE : VARIANT_FALSE; + break; + case typeString: + V_VT(&val) = VT_BSTR; + V_BSTR(&val) = SysAllocString((LPCWSTR)ppt->value); + break; + case typeLong: + V_VT(&val) = VT_I4; + V_I4(&val) = (ULONG)ppt->value; + break; + case typeDispatch: + V_VT(&val) = VT_DISPATCH; + V_DISPATCH(&val) = (IDispatch*)ppt->value; + if (NULL != val.pdispVal) + val.pdispVal->AddRef(); + break; + default: + continue; + break; + } + AddProperty(ppt->name, val); + inserted++; + } + + return inserted; +} + +/* ---------------------------------------------------------------------------- */ +HRESULT JSAPI::InvokeEvent(JSAPI::CallbackParameters *parameters, IDispatch *invokee) +{ + unsigned int ret; + DISPPARAMS params; + VARIANTARG arguments[1]; + + VariantInit(&arguments[0]); + V_VT(&arguments[0]) = VT_DISPATCH; + V_DISPATCH(&arguments[0]) = parameters; + parameters->AddRef(); + + params.cArgs = 1; + params.cNamedArgs = 0; + params.rgdispidNamedArgs = NULL; + params.rgvarg = arguments; + + HRESULT hr = invokee->Invoke(0, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, 0, 0, &ret); + + VariantClear(&arguments[0]); + + return hr; +} + |