-
Notifications
You must be signed in to change notification settings - Fork 29
/
thrift_object.h
248 lines (204 loc) · 6.54 KB
/
thrift_object.h
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#pragma once
#include <list>
#include <memory>
#include "envoy/buffer/buffer.h"
#include "envoy/common/exception.h"
#include "source/common/common/utility.h"
#include "src/application_protocols/thrift/thrift.h"
namespace Envoy {
namespace Extensions {
namespace NetworkFilters {
namespace ThriftProxy {
class ThriftBase;
/**
* ThriftValue is a field or container (list, set, or map) element.
*/
class ThriftValue {
public:
virtual ~ThriftValue() = default;
/**
* @return FieldType the type of this value
*/
virtual FieldType type() const PURE;
/**
* @return const T& pointer to the value, provided that it can be cast to the given type
* @throw EnvoyException if the type T does not match the type
*/
template <typename T> const T& getValueTyped() const {
// Use the Traits template to determine what FieldType the value must have to be cast to T
// and throw if the value's type doesn't match.
FieldType expected_field_type = Traits<T>::getFieldType();
if (expected_field_type != type()) {
ExceptionUtil::throwEnvoyException(fmt::format("expected field type {}, got {}",
static_cast<int>(expected_field_type),
static_cast<int>(type())));
}
return *static_cast<const T*>(getValue());
}
protected:
/**
* @return void* pointing to the underlying value, to be dynamically cast in getValueTyped
*/
virtual const void* getValue() const PURE;
private:
/**
* Traits allows getValueTyped() to enforce that the field type is being cast to the desired type.
*/
template <typename T> class Traits {
public:
// Compilation failures where T does not have a member getFieldType typically mean that
// getValueTyped was called with a type T that is not used to encode Thrift values.
// The specializations below encode the valid types for Thrift primitive types.
static FieldType getFieldType() { return T::getFieldType(); }
};
};
// Explicit specializations of ThriftValue::Types for primitive types.
template <> class ThriftValue::Traits<bool> {
public:
static FieldType getFieldType() { return FieldType::Bool; }
};
template <> class ThriftValue::Traits<uint8_t> {
public:
static FieldType getFieldType() { return FieldType::Byte; }
};
template <> class ThriftValue::Traits<int16_t> {
public:
static FieldType getFieldType() { return FieldType::I16; }
};
template <> class ThriftValue::Traits<int32_t> {
public:
static FieldType getFieldType() { return FieldType::I32; }
};
template <> class ThriftValue::Traits<int64_t> {
public:
static FieldType getFieldType() { return FieldType::I64; }
};
template <> class ThriftValue::Traits<double> {
public:
static FieldType getFieldType() { return FieldType::Double; }
};
template <> class ThriftValue::Traits<std::string> {
public:
static FieldType getFieldType() { return FieldType::String; }
};
using ThriftValuePtr = std::unique_ptr<ThriftValue>;
using ThriftValuePtrList = std::list<ThriftValuePtr>;
using ThriftValuePtrPairList = std::list<std::pair<ThriftValuePtr, ThriftValuePtr>>;
/**
* ThriftField is a field within a ThriftStruct.
*/
class ThriftField {
public:
virtual ~ThriftField() = default;
/**
* @return FieldType this field's type
*/
virtual FieldType fieldType() const PURE;
/**
* @return int16_t the field's identifier
*/
virtual int16_t fieldId() const PURE;
/**
* @return const ThriftValue& containing the field's value
*/
virtual const ThriftValue& getValue() const PURE;
};
using ThriftFieldPtr = std::unique_ptr<ThriftField>;
using ThriftFieldPtrList = std::list<ThriftFieldPtr>;
/**
* ThriftListValue is an ordered list of ThriftValues.
*/
class ThriftListValue {
public:
virtual ~ThriftListValue() = default;
/**
* @return const ThriftValuePtrList& containing the ThriftValues that comprise the list
*/
virtual const ThriftValuePtrList& elements() const PURE;
/**
* @return FieldType of the underlying elements
*/
virtual FieldType elementType() const PURE;
/**
* Used by ThriftValue::Traits to enforce type safety.
*/
static FieldType getFieldType() { return FieldType::List; }
};
/**
* ThriftSetValue is a set of ThriftValues, maintained in their original order.
*/
class ThriftSetValue {
public:
virtual ~ThriftSetValue() = default;
/**
* @return const ThriftValuePtrList& containing the ThriftValues that comprise the set
*/
virtual const ThriftValuePtrList& elements() const PURE;
/**
* @return FieldType of the underlying elements
*/
virtual FieldType elementType() const PURE;
/**
* Used by ThriftValue::Traits to enforce type safety.
*/
static FieldType getFieldType() { return FieldType::Set; }
};
/**
* ThriftMapValue is a map of pairs of ThriftValues, maintained in their original order.
*/
class ThriftMapValue {
public:
virtual ~ThriftMapValue() = default;
/**
* @return const ThriftValuePtrPairList& containing the ThriftValue key-value pairs that comprise
* the map.
*/
virtual const ThriftValuePtrPairList& elements() const PURE;
/**
* @return FieldType of the underlying keys
*/
virtual FieldType keyType() const PURE;
/**
* @return FieldType of the underlying values
*/
virtual FieldType valueType() const PURE;
/**
* Used by ThriftValue::Traits to enforce type safety.
*/
static FieldType getFieldType() { return FieldType::Map; }
};
/**
* ThriftStructValue is a sequence of ThriftFields.
*/
class ThriftStructValue {
public:
virtual ~ThriftStructValue() = default;
/**
* @return const ThriftFieldPtrList& containing the ThriftFields that comprise the struct.
*/
virtual const ThriftFieldPtrList& fields() const PURE;
/**
* Used by ThriftValue::Traits to enforce type safety.
*/
static FieldType getFieldType() { return FieldType::Struct; }
};
/**
* ThriftObject is a ThriftStructValue that can be read from a Buffer::Instance.
*/
class ThriftObject : public ThriftStructValue {
public:
~ThriftObject() override = default;
/*
* Consumes bytes from the buffer until a single complete Thrift struct has been consumed.
* @param buffer starting with a Thrift struct
* @return true when a single complete struct has been consumed; false if more data is needed to
* complete decoding
* @throw EnvoyException if the struct is invalid
*/
virtual bool onData(Buffer::Instance& buffer) PURE;
};
using ThriftObjectPtr = std::unique_ptr<ThriftObject>;
} // namespace ThriftProxy
} // namespace NetworkFilters
} // namespace Extensions
} // namespace Envoy