-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVariant.cpp
165 lines (153 loc) · 4.26 KB
/
Variant.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
* Copyright (c) 2022-2024 WangBin <wbsecg1 at gmail.com>
*/
#include "Variant.h"
#include "BStr.h"
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;
#define MS_ENSURE(f, ...) MS_CHECK(f, return __VA_ARGS__;)
#define MS_WARN(f) MS_CHECK(f)
#define MS_CHECK(f, ...) do { \
const HRESULT __ms_hr__ = (f); \
if (FAILED(__ms_hr__)) { \
std::clog << #f " ERROR@" << __LINE__ << __FUNCTION__ << ": (" << std::hex << __ms_hr__ << std::dec << ") " << std::error_code(__ms_hr__, std::system_category()).message() << std::endl << std::flush; \
__VA_ARGS__ \
} \
} while (false)
static_assert(sizeof(ScopedVariant) == sizeof(VARIANT), "ScopedVariant size mismatch");
ScopedVariant::ScopedVariant()
{
VariantInit(this);
}
ScopedVariant::~ScopedVariant()
{
if (vt == blackmagicRawVariantTypeString) {
// will be released and reset in VariantClear
}
VariantClear(this);
}
ScopedVariant* ScopedVariant::ReleaseAndGetAddressOf()
{
VariantClear(this);
return this;
}
string to_string(const VARIANT& v)
{
stringstream ss;
switch (v.vt) {
case blackmagicRawVariantTypeS16:
ss << v.iVal;
break;
case blackmagicRawVariantTypeU16:
ss << v.uiVal;
break;
case blackmagicRawVariantTypeS32:
ss << v.intVal;
break;
case blackmagicRawVariantTypeU32:
ss << v.uintVal;
break;
case blackmagicRawVariantTypeFloat32:
ss << v.fltVal;
break;
case blackmagicRawVariantTypeString:
return BStr::to_string(v.bstrVal);
case blackmagicRawVariantTypeSafeArray: {
auto sa = v.parray;
void* sad = nullptr;
MS_ENSURE(SafeArrayAccessData(sa, &sad), {});
VARTYPE vt;
MS_ENSURE(SafeArrayGetVartype(sa, &vt), {});
long lBound = 0;
MS_ENSURE(SafeArrayGetLBound(sa, 1, &lBound), {});
long uBound = 0;
MS_ENSURE(SafeArrayGetUBound(sa, 1, &uBound), {});
const auto saLen = (uBound - lBound) + 1;
const auto aLen = saLen > 32 ? 32 : saLen; // ?
for (long i = 0; i < aLen; ++i) {
if (i > 0)
ss << ' ';
switch (vt) {
case blackmagicRawVariantTypeU8:
ss << std::uppercase << std::setw(2) << std::setfill('0') << std::setbase(16) << (int)static_cast<uint8_t*>(sad)[i];
break;
case blackmagicRawVariantTypeS16:
ss << static_cast<int16_t*>(sad)[i];
break;
case blackmagicRawVariantTypeU16:
ss << static_cast<uint16_t*>(sad)[i];
break;
case blackmagicRawVariantTypeS32:
ss << static_cast<int32_t*>(sad)[i];
break;
case blackmagicRawVariantTypeU32:
ss << static_cast<uint32_t*>(sad)[i];
break;
case blackmagicRawVariantTypeFloat32:
ss << static_cast<float*>(sad)[i];
break;
}
}
}
break;
default:
return {};
}
return ss.str();
}
var_ptr make_v(int16_t x)
{
auto v = make_shared<VARIANT>();
VariantInit(v.get());
v->vt = blackmagicRawVariantTypeS16;
v->iVal = x;
return v;
}
var_ptr make_v(uint16_t x)
{
auto v = make_shared<VARIANT>();
VariantInit(v.get());
v->vt = blackmagicRawVariantTypeU16;
v->uiVal = x;
return v;
}
var_ptr make_v(int32_t x)
{
auto v = make_shared<VARIANT>();
VariantInit(v.get());
v->vt = blackmagicRawVariantTypeS32;
v->intVal = x;
return v;
}
var_ptr make_v(uint32_t x)
{
auto v = make_shared<VARIANT>();
VariantInit(v.get());
v->vt = blackmagicRawVariantTypeU32;
v->uintVal = x;
return v;
}
var_ptr make_v(float x)
{
auto v = make_shared<VARIANT>();
VariantInit(v.get());
v->vt = blackmagicRawVariantTypeFloat32;
v->fltVal = x;
return v;
}
var_ptr make_v(const string& x)
{
auto bs = new BStr(x.data());
auto deleter = [bs](VARIANT* p) {
default_delete<VARIANT>{}(p);
delete bs;
};
auto v = var_ptr(new VARIANT(), deleter);
VariantInit(v.get());
v->vt = blackmagicRawVariantTypeString;
v->bstrVal = bs->get();
return v;
}