xref: /aosp_15_r20/external/cronet/base/win/variant_conversions.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2020 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_WIN_VARIANT_CONVERSIONS_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_WIN_VARIANT_CONVERSIONS_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <oaidl.h>
9*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
10*6777b538SAndroid Build Coastguard Worker #include <wtypes.h>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker namespace base {
15*6777b538SAndroid Build Coastguard Worker namespace win {
16*6777b538SAndroid Build Coastguard Worker namespace internal {
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker // Returns true if a VARIANT of type |self| can be assigned to a
19*6777b538SAndroid Build Coastguard Worker // variant of type |other|.
20*6777b538SAndroid Build Coastguard Worker // Does not allow converting unsigned <-> signed or converting between
21*6777b538SAndroid Build Coastguard Worker // different sized types, but does allow converting IDispatch* -> IUnknown*.
VarTypeIsConvertibleTo(VARTYPE self,VARTYPE other)22*6777b538SAndroid Build Coastguard Worker constexpr bool VarTypeIsConvertibleTo(VARTYPE self, VARTYPE other) {
23*6777b538SAndroid Build Coastguard Worker   // IDispatch inherits from IUnknown, so it's safe to
24*6777b538SAndroid Build Coastguard Worker   // upcast a VT_DISPATCH into an IUnknown*.
25*6777b538SAndroid Build Coastguard Worker   return (self == other) || (self == VT_DISPATCH && other == VT_UNKNOWN);
26*6777b538SAndroid Build Coastguard Worker }
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker // VartypeToNativeType contains the underlying |Type| and offset to the
29*6777b538SAndroid Build Coastguard Worker // VARIANT union member related to the |ElementVartype| for simple types.
30*6777b538SAndroid Build Coastguard Worker template <VARTYPE ElementVartype>
31*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType final {};
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker template <>
34*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_BOOL> final {
35*6777b538SAndroid Build Coastguard Worker   using Type = VARIANT_BOOL;
36*6777b538SAndroid Build Coastguard Worker   static constexpr VARIANT_BOOL VARIANT::*kMemberOffset = &VARIANT::boolVal;
37*6777b538SAndroid Build Coastguard Worker };
38*6777b538SAndroid Build Coastguard Worker 
39*6777b538SAndroid Build Coastguard Worker template <>
40*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_I1> final {
41*6777b538SAndroid Build Coastguard Worker   using Type = int8_t;
42*6777b538SAndroid Build Coastguard Worker   static constexpr CHAR VARIANT::*kMemberOffset = &VARIANT::cVal;
43*6777b538SAndroid Build Coastguard Worker };
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker template <>
46*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_UI1> final {
47*6777b538SAndroid Build Coastguard Worker   using Type = uint8_t;
48*6777b538SAndroid Build Coastguard Worker   static constexpr BYTE VARIANT::*kMemberOffset = &VARIANT::bVal;
49*6777b538SAndroid Build Coastguard Worker };
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker template <>
52*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_I2> final {
53*6777b538SAndroid Build Coastguard Worker   using Type = int16_t;
54*6777b538SAndroid Build Coastguard Worker   static constexpr SHORT VARIANT::*kMemberOffset = &VARIANT::iVal;
55*6777b538SAndroid Build Coastguard Worker };
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker template <>
58*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_UI2> final {
59*6777b538SAndroid Build Coastguard Worker   using Type = uint16_t;
60*6777b538SAndroid Build Coastguard Worker   static constexpr USHORT VARIANT::*kMemberOffset = &VARIANT::uiVal;
61*6777b538SAndroid Build Coastguard Worker };
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker template <>
64*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_I4> final {
65*6777b538SAndroid Build Coastguard Worker   using Type = int32_t;
66*6777b538SAndroid Build Coastguard Worker   static constexpr LONG VARIANT::*kMemberOffset = &VARIANT::lVal;
67*6777b538SAndroid Build Coastguard Worker };
68*6777b538SAndroid Build Coastguard Worker 
69*6777b538SAndroid Build Coastguard Worker template <>
70*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_UI4> final {
71*6777b538SAndroid Build Coastguard Worker   using Type = uint32_t;
72*6777b538SAndroid Build Coastguard Worker   static constexpr ULONG VARIANT::*kMemberOffset = &VARIANT::ulVal;
73*6777b538SAndroid Build Coastguard Worker };
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker template <>
76*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_I8> final {
77*6777b538SAndroid Build Coastguard Worker   using Type = int64_t;
78*6777b538SAndroid Build Coastguard Worker   static constexpr LONGLONG VARIANT::*kMemberOffset = &VARIANT::llVal;
79*6777b538SAndroid Build Coastguard Worker };
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker template <>
82*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_UI8> final {
83*6777b538SAndroid Build Coastguard Worker   using Type = uint64_t;
84*6777b538SAndroid Build Coastguard Worker   static constexpr ULONGLONG VARIANT::*kMemberOffset = &VARIANT::ullVal;
85*6777b538SAndroid Build Coastguard Worker };
86*6777b538SAndroid Build Coastguard Worker 
87*6777b538SAndroid Build Coastguard Worker template <>
88*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_R4> final {
89*6777b538SAndroid Build Coastguard Worker   using Type = float;
90*6777b538SAndroid Build Coastguard Worker   static constexpr FLOAT VARIANT::*kMemberOffset = &VARIANT::fltVal;
91*6777b538SAndroid Build Coastguard Worker };
92*6777b538SAndroid Build Coastguard Worker 
93*6777b538SAndroid Build Coastguard Worker template <>
94*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_R8> final {
95*6777b538SAndroid Build Coastguard Worker   using Type = double;
96*6777b538SAndroid Build Coastguard Worker   static constexpr DOUBLE VARIANT::*kMemberOffset = &VARIANT::dblVal;
97*6777b538SAndroid Build Coastguard Worker };
98*6777b538SAndroid Build Coastguard Worker 
99*6777b538SAndroid Build Coastguard Worker template <>
100*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_DATE> final {
101*6777b538SAndroid Build Coastguard Worker   using Type = DATE;
102*6777b538SAndroid Build Coastguard Worker   static constexpr DATE VARIANT::*kMemberOffset = &VARIANT::date;
103*6777b538SAndroid Build Coastguard Worker };
104*6777b538SAndroid Build Coastguard Worker 
105*6777b538SAndroid Build Coastguard Worker template <>
106*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_BSTR> final {
107*6777b538SAndroid Build Coastguard Worker   using Type = BSTR;
108*6777b538SAndroid Build Coastguard Worker   static constexpr BSTR VARIANT::*kMemberOffset = &VARIANT::bstrVal;
109*6777b538SAndroid Build Coastguard Worker };
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker template <>
112*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_UNKNOWN> final {
113*6777b538SAndroid Build Coastguard Worker   using Type = IUnknown*;
114*6777b538SAndroid Build Coastguard Worker   static constexpr IUnknown* VARIANT::*kMemberOffset = &VARIANT::punkVal;
115*6777b538SAndroid Build Coastguard Worker };
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker template <>
118*6777b538SAndroid Build Coastguard Worker struct VartypeToNativeType<VT_DISPATCH> final {
119*6777b538SAndroid Build Coastguard Worker   using Type = IDispatch*;
120*6777b538SAndroid Build Coastguard Worker   static constexpr IDispatch* VARIANT::*kMemberOffset = &VARIANT::pdispVal;
121*6777b538SAndroid Build Coastguard Worker };
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker // VariantConverter contains the underlying |Type| and helper methods
124*6777b538SAndroid Build Coastguard Worker // related to the |ElementVartype| for simple types.
125*6777b538SAndroid Build Coastguard Worker template <VARTYPE ElementVartype>
126*6777b538SAndroid Build Coastguard Worker struct VariantConverter final {
127*6777b538SAndroid Build Coastguard Worker   using Type = typename VartypeToNativeType<ElementVartype>::Type;
128*6777b538SAndroid Build Coastguard Worker   static constexpr bool IsConvertibleTo(VARTYPE vartype) {
129*6777b538SAndroid Build Coastguard Worker     return VarTypeIsConvertibleTo(ElementVartype, vartype);
130*6777b538SAndroid Build Coastguard Worker   }
131*6777b538SAndroid Build Coastguard Worker   static constexpr bool IsConvertibleFrom(VARTYPE vartype) {
132*6777b538SAndroid Build Coastguard Worker     return VarTypeIsConvertibleTo(vartype, ElementVartype);
133*6777b538SAndroid Build Coastguard Worker   }
134*6777b538SAndroid Build Coastguard Worker   // Get the associated VARIANT union member value.
135*6777b538SAndroid Build Coastguard Worker   // Returns the value owned by the VARIANT without affecting the lifetime
136*6777b538SAndroid Build Coastguard Worker   // of managed contents.
137*6777b538SAndroid Build Coastguard Worker   // e.g. Does not affect IUnknown* reference counts or allocate a BSTR.
138*6777b538SAndroid Build Coastguard Worker   static Type RawGet(const VARIANT& var) {
139*6777b538SAndroid Build Coastguard Worker     DCHECK(IsConvertibleFrom(V_VT(&var)));
140*6777b538SAndroid Build Coastguard Worker     return var.*VartypeToNativeType<ElementVartype>::kMemberOffset;
141*6777b538SAndroid Build Coastguard Worker   }
142*6777b538SAndroid Build Coastguard Worker   // Set the associated VARIANT union member value.
143*6777b538SAndroid Build Coastguard Worker   // The caller is responsible for handling the lifetime of managed contents.
144*6777b538SAndroid Build Coastguard Worker   // e.g. Incrementing IUnknown* reference counts or allocating a BSTR.
145*6777b538SAndroid Build Coastguard Worker   static void RawSet(VARIANT* var, Type value) {
146*6777b538SAndroid Build Coastguard Worker     DCHECK(IsConvertibleTo(V_VT(var)));
147*6777b538SAndroid Build Coastguard Worker     var->*VartypeToNativeType<ElementVartype>::kMemberOffset = value;
148*6777b538SAndroid Build Coastguard Worker   }
149*6777b538SAndroid Build Coastguard Worker };
150*6777b538SAndroid Build Coastguard Worker 
151*6777b538SAndroid Build Coastguard Worker }  // namespace internal
152*6777b538SAndroid Build Coastguard Worker }  // namespace win
153*6777b538SAndroid Build Coastguard Worker }  // namespace base
154*6777b538SAndroid Build Coastguard Worker 
155*6777b538SAndroid Build Coastguard Worker #endif  // BASE_WIN_VARIANT_CONVERSIONS_H_
156