/proc/self/cwd/source/extensions/filters/network/thrift_proxy/compact_protocol_impl.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include <stack> |
4 | | #include <string> |
5 | | |
6 | | #include "envoy/buffer/buffer.h" |
7 | | #include "envoy/common/pure.h" |
8 | | |
9 | | #include "source/extensions/filters/network/thrift_proxy/protocol.h" |
10 | | #include "source/extensions/filters/network/thrift_proxy/thrift.h" |
11 | | |
12 | | #include "absl/types/optional.h" |
13 | | |
14 | | namespace Envoy { |
15 | | namespace Extensions { |
16 | | namespace NetworkFilters { |
17 | | namespace ThriftProxy { |
18 | | |
19 | | /** |
20 | | * CompactProtocolImpl implements the Thrift Compact protocol. |
21 | | * See https://github.com/apache/thrift/blob/master/doc/specs/thrift-compact-protocol.md |
22 | | */ |
23 | | class CompactProtocolImpl : public Protocol { |
24 | | public: |
25 | 0 | CompactProtocolImpl() = default; |
26 | | |
27 | | // Protocol |
28 | 0 | const std::string& name() const override { return ProtocolNames::get().COMPACT; } |
29 | 0 | ProtocolType type() const override { return ProtocolType::Compact; } |
30 | | bool readMessageBegin(Buffer::Instance& buffer, MessageMetadata& metadata) override; |
31 | | bool readMessageEnd(Buffer::Instance& buffer) override; |
32 | | bool peekReplyPayload(Buffer::Instance& buffer, ReplyType& reply_type) override; |
33 | | bool readStructBegin(Buffer::Instance& buffer, std::string& name) override; |
34 | | bool readStructEnd(Buffer::Instance& buffer) override; |
35 | | bool readFieldBegin(Buffer::Instance& buffer, std::string& name, FieldType& field_type, |
36 | | int16_t& field_id) override; |
37 | | bool readFieldEnd(Buffer::Instance& buffer) override; |
38 | | bool readMapBegin(Buffer::Instance& buffer, FieldType& key_type, FieldType& value_type, |
39 | | uint32_t& size) override; |
40 | | bool readMapEnd(Buffer::Instance& buffer) override; |
41 | | bool readListBegin(Buffer::Instance& buffer, FieldType& elem_type, uint32_t& size) override; |
42 | | bool readListEnd(Buffer::Instance& buffer) override; |
43 | | bool readSetBegin(Buffer::Instance& buffer, FieldType& elem_type, uint32_t& size) override; |
44 | | bool readSetEnd(Buffer::Instance& buffer) override; |
45 | | bool readBool(Buffer::Instance& buffer, bool& value) override; |
46 | | bool readByte(Buffer::Instance& buffer, uint8_t& value) override; |
47 | | bool readInt16(Buffer::Instance& buffer, int16_t& value) override; |
48 | | bool readInt32(Buffer::Instance& buffer, int32_t& value) override; |
49 | | bool readInt64(Buffer::Instance& buffer, int64_t& value) override; |
50 | | bool readDouble(Buffer::Instance& buffer, double& value) override; |
51 | | bool readString(Buffer::Instance& buffer, std::string& value) override; |
52 | | bool readBinary(Buffer::Instance& buffer, std::string& value) override; |
53 | | void writeMessageBegin(Buffer::Instance& buffer, const MessageMetadata& metadata) override; |
54 | | void writeMessageEnd(Buffer::Instance& buffer) override; |
55 | | void writeStructBegin(Buffer::Instance& buffer, const std::string& name) override; |
56 | | void writeStructEnd(Buffer::Instance& buffer) override; |
57 | | void writeFieldBegin(Buffer::Instance& buffer, const std::string& name, FieldType field_type, |
58 | | int16_t field_id) override; |
59 | | void writeFieldEnd(Buffer::Instance& buffer) override; |
60 | | void writeMapBegin(Buffer::Instance& buffer, FieldType key_type, FieldType value_type, |
61 | | uint32_t size) override; |
62 | | void writeMapEnd(Buffer::Instance& buffer) override; |
63 | | void writeListBegin(Buffer::Instance& buffer, FieldType elem_type, uint32_t size) override; |
64 | | void writeListEnd(Buffer::Instance& buffer) override; |
65 | | void writeSetBegin(Buffer::Instance& buffer, FieldType elem_type, uint32_t size) override; |
66 | | void writeSetEnd(Buffer::Instance& buffer) override; |
67 | | void writeBool(Buffer::Instance& buffer, bool value) override; |
68 | | void writeByte(Buffer::Instance& buffer, uint8_t value) override; |
69 | | void writeInt16(Buffer::Instance& buffer, int16_t value) override; |
70 | | void writeInt32(Buffer::Instance& buffer, int32_t value) override; |
71 | | void writeInt64(Buffer::Instance& buffer, int64_t value) override; |
72 | | void writeDouble(Buffer::Instance& buffer, double value) override; |
73 | | void writeString(Buffer::Instance& buffer, const std::string& value) override; |
74 | | void writeBinary(Buffer::Instance& buffer, const std::string& value) override; |
75 | | |
76 | 0 | static bool isMagic(uint16_t word) { return (word & MagicMask) == Magic; } |
77 | | |
78 | | private: |
79 | | enum class CompactFieldType { |
80 | | Stop = 0, |
81 | | BoolTrue = 1, |
82 | | BoolFalse = 2, |
83 | | Byte = 3, |
84 | | I16 = 4, |
85 | | I32 = 5, |
86 | | I64 = 6, |
87 | | Double = 7, |
88 | | String = 8, |
89 | | List = 9, |
90 | | Set = 10, |
91 | | Map = 11, |
92 | | Struct = 12, |
93 | | }; |
94 | | |
95 | | FieldType convertCompactFieldType(CompactFieldType compact_field_type); |
96 | | CompactFieldType convertFieldType(FieldType field_type); |
97 | | |
98 | | void writeFieldBeginInternal(Buffer::Instance& buffer, FieldType field_type, int16_t field_id, |
99 | | absl::optional<CompactFieldType> field_type_override); |
100 | | |
101 | | static void validateFieldId(int32_t id); |
102 | | |
103 | | std::stack<int16_t> last_field_id_stack_{}; |
104 | | int16_t last_field_id_{0}; |
105 | | |
106 | | // Compact protocol encodes boolean struct fields as true/false *types* with no data. |
107 | | // This tracks the last boolean struct field's value for readBool. |
108 | | absl::optional<bool> bool_value_{}; |
109 | | |
110 | | // Similarly, track the field id for writeBool. |
111 | | absl::optional<int16_t> bool_field_id_{}; |
112 | | |
113 | | const static uint16_t Magic; |
114 | | const static uint16_t MagicMask; |
115 | | }; |
116 | | |
117 | | } // namespace ThriftProxy |
118 | | } // namespace NetworkFilters |
119 | | } // namespace Extensions |
120 | | } // namespace Envoy |