📄 statevar.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "pch.h"
#pragma hdrstop
#include "variant.h"
#include "DataType.hxx"
#include "StateVar.h"
StateVar::type_pair StateVar::m_aTypes[StateVar::number_of_types] =
{
L"ui1", ui1,
L"ui2", ui2,
L"ui4", ui4,
L"i1", i1,
L"i2", i2,
L"i4", i4,
L"int", Int,
L"r4", r4,
L"r8", r8,
L"number", number,
L"fixed.14.4", fixed_14_4,
L"float", Float,
L"char", Char,
L"string", string,
L"date", date,
L"dateTime", dateTime,
L"dateTime.tz", dateTime_tz,
L"time", time,
L"time.tz", time_tz,
L"boolean", boolean,
L"bin.base64", bin_base64,
L"bin.hex", bin_hex,
L"uri", uri,
L"uuid", uuid
};
// StateVar
StateVar::StateVar(LPCWSTR pwszName, LPCWSTR pwszType, bool bSendEvents)
: m_strName(pwszName),
m_type(unknown_type),
m_bSendEvents(bSendEvents)
{
// make sure types array is initialized for all types
Assert(m_aTypes[number_of_types - 1].type == number_of_types - 1);
for(int i = 0; i < number_of_types; ++i)
if(0 == _wcsicmp(pwszType, m_aTypes[i].pwszName))
{
m_type = m_aTypes[i].type;
break;
}
}
// GetVartype
VARTYPE StateVar::GetVartype() const
{
// var types in order of StateVar::type
static VARTYPE vartypes[] = {
VT_UI1, // ui1,
VT_UI2, // ui2,
VT_UI4, // ui4,
VT_I1, // i1,
VT_I2, // i2,
VT_I4, // i4,
VT_I4, // Int,
VT_R4, // r4,
VT_R8, // r8,
VT_BSTR, // number,
VT_CY, // fixed_14_4,
VT_R8, // Float,
VT_UI2, // Char,
VT_BSTR, // string,
VT_DATE, // date,
VT_DATE, // dateTime,
VT_DATE, // dateTime_tz,
VT_DATE, // time,
VT_DATE, // time_tz,
VT_BOOL, // boolean,
VT_ARRAY | VT_UI1, // bin_base64
VT_ARRAY | VT_UI1, // bin_hex,
VT_BSTR, // uri,
VT_BSTR}; // uuid
if(m_type < sizeof(vartypes)/sizeof(*vartypes))
return vartypes[m_type];
else
return 0xFFFF;
}
// GetDataType
DataType StateVar::GetDataType() const
{
// data types in order of StateVar::type
static DataType datatypes[] = {
DT_NONE, // ui1,
DT_NONE, // ui2,
DT_NONE, // ui4,
DT_NONE, // i1,
DT_NONE, // i2,
DT_NONE, // i4,
DT_NONE, // Int,
DT_NONE, // r4,
DT_NONE, // r8,
DT_NONE, // number,
DT_NONE, // fixed_14_4,
DT_NONE, // Float,
DT_NONE, // Char,
DT_NONE, // string,
DT_DATE_ISO8601, // date,
DT_DATETIME_ISO8601, // dateTime,
DT_DATETIME_ISO8601TZ, // dateTime_tz,
DT_TIME_ISO8601, // time,
DT_TIME_ISO8601TZ, // time_tz,
DT_NONE, // boolean,
DT_NONE, // bin_base64
DT_NONE, // bin_hex,
DT_NONE, // uri,
DT_NONE}; // uuid
if(m_type < sizeof(datatypes)/sizeof(*datatypes))
return datatypes[m_type];
else
return DT_NONE;
}
// Decode
bool StateVar::Decode(LPCWSTR pwszValue, VARIANT* pvarValue) const
{
Assert(pvarValue);
ce::variant varTemp;
const wchar_t* pwcNext;
int cch;
cch = wcslen(pwszValue);
VariantClear(pvarValue);
switch(m_type)
{
case StateVar::ui1:
case StateVar::ui2:
case StateVar::ui4:
case StateVar::i1:
case StateVar::i2:
case StateVar::i4:
case StateVar::Int:
case StateVar::r4:
case StateVar::r8:
case StateVar::number:
case StateVar::fixed_14_4:
case StateVar::Float:
case StateVar::string:
case StateVar::uri:
case StateVar::uuid:
varTemp = pwszValue;
if(SUCCEEDED(VariantChangeType(pvarValue, &varTemp, 0, GetVartype())))
return true;
break;
case StateVar::Char:
Assert(pvarValue->vt == VT_EMPTY);
pvarValue->vt = VT_UI2;
V_UI2(pvarValue) = *pwszValue;
return true;
case StateVar::date:
case StateVar::dateTime:
case StateVar::dateTime_tz:
case StateVar::time:
case StateVar::time_tz:
if(SUCCEEDED(ParseISO8601(pwszValue, cch, GetDataType(), &V_DATE(pvarValue), &pwcNext)))
{
pvarValue->vt = VT_DATE;
return true;
}
break;
case StateVar::bin_hex:
case StateVar::bin_base64:
{
Assert(pvarValue->vt == VT_EMPTY);
SAFEARRAY *psa;
SAFEARRAYBOUND rgsabound[1];
BYTE *pData;
int cbData;
HRESULT hr;
if(StateVar::bin_hex == m_type)
{
cbData = (cch + 1)/2;
}
else
{
Assert(StateVar::bin_base64 == m_type);
cbData = cch;
}
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = cbData;
psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
if(psa == NULL)
{
pvarValue->vt = VT_ERROR;
pvarValue->scode = E_OUTOFMEMORY;
return false;
}
SafeArrayAccessData(psa, (void**)&pData);
if(StateVar::bin_hex == m_type)
{
hr = ParseBinHex(pwszValue, cch, pData, &cbData, &pwcNext);
}
else
{
Assert(StateVar::bin_base64 == m_type);
hr = ParseBase64(pwszValue, cch, pData, &cbData, &pwcNext);
}
if(SUCCEEDED(hr))
{
pvarValue->parray = psa;
pvarValue->vt = VT_ARRAY | VT_UI1;
SafeArrayUnaccessData(psa);
rgsabound[0].cElements = cbData;
SafeArrayRedim(psa, rgsabound);
return true;
}
else
{
SafeArrayUnaccessData(psa);
SafeArrayDestroy(psa);
}
}
break;
case StateVar::boolean:
Assert(pvarValue->vt == VT_EMPTY);
if(0 == wcscmp(pwszValue, L"true") ||
0 == wcscmp(pwszValue, L"yes") ||
0 == wcscmp(pwszValue, L"1"))
{
pvarValue->vt = VT_BOOL;
pvarValue->boolVal = VARIANT_TRUE;
return true;
}
if(0 == wcscmp(pwszValue, L"false") ||
0 == wcscmp(pwszValue, L"no") ||
0 == wcscmp(pwszValue, L"0"))
{
pvarValue->vt = VT_BOOL;
pvarValue->boolVal = VARIANT_FALSE;
return true;
}
break;
default: Assert(pvarValue->vt == VT_EMPTY);
pvarValue->vt = VT_ERROR;
pvarValue->scode = DISP_E_BADVARTYPE;
return false;
}
Assert(pvarValue->vt == VT_EMPTY);
pvarValue->vt = VT_ERROR;
pvarValue->scode = DISP_E_TYPEMISMATCH;
return false;
}
// Encode
bool StateVar::Encode(const VARIANT& varValue, ce::wstring* pstrValue) const
{
Assert(pstrValue);
ce::variant varTemp;
pstrValue->resize(0);
if(FAILED(varTemp.ChangeType(GetVartype(), &varValue)))
return true;
switch(m_type)
{
case StateVar::ui1:
case StateVar::ui2:
case StateVar::ui4:
case StateVar::i1:
case StateVar::i2:
case StateVar::i4:
case StateVar::Int:
case StateVar::r4:
case StateVar::r8:
case StateVar::number:
case StateVar::fixed_14_4:
case StateVar::Float:
case StateVar::string:
case StateVar::uri:
case StateVar::uuid:
if(SUCCEEDED(varTemp.ChangeType(VT_BSTR)))
{
*pstrValue = V_BSTR(&varTemp);
break;
}
break;
case StateVar::Char:
Assert(varTemp.vt == VT_UI2);
pstrValue->assign(V_UI2(&varTemp));
break;
case StateVar::date:
case StateVar::dateTime:
case StateVar::dateTime_tz:
case StateVar::time:
case StateVar::time_tz:
Assert(varTemp.vt == VT_DATE);
UnparseISO8601(pstrValue, GetDataType(), &V_DATE(&varTemp));
break;
case StateVar::bin_base64:
case StateVar::bin_hex:
{
Assert(varTemp.vt == (VT_ARRAY | VT_UI1));
BYTE *pData;
int cbData;
long lBound, uBound;
SafeArrayGetLBound(varTemp.parray, 1, &lBound);
SafeArrayGetUBound(varTemp.parray, 1, &uBound);
cbData = uBound - lBound + 1;
SafeArrayAccessData(varTemp.parray, (void**)&pData);
if(StateVar::bin_hex == m_type)
{
UnparseBinHex(pstrValue, pData, cbData);
}
else
{
Assert(StateVar::bin_base64 == m_type);
UnparseBase64(pData, cbData, pstrValue);
}
SafeArrayUnaccessData(varTemp.parray);
}
break;
case StateVar::boolean:
Assert(varTemp.vt == VT_BOOL);
if(V_BOOL(&varTemp) != VARIANT_FALSE)
*pstrValue = L"1";
else
*pstrValue = L"0";
break;
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -