]>
git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/thrift/lib/py/src/ext/compact.h
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
20 #ifndef THRIFT_PY_COMPACT_H
21 #define THRIFT_PY_COMPACT_H
24 #include "ext/protocol.h"
25 #include "ext/endian.h"
33 class CompactProtocol
: public ProtocolBase
<CompactProtocol
> {
35 CompactProtocol() { readBool_
.exists
= false; }
37 virtual ~CompactProtocol() {}
39 void writeI8(int8_t val
) { writeBuffer(reinterpret_cast<char*>(&val
), 1); }
41 void writeI16(int16_t val
) { writeVarint(toZigZag(val
)); }
43 int writeI32(int32_t val
) { return writeVarint(toZigZag(val
)); }
45 void writeI64(int64_t val
) { writeVarint64(toZigZag64(val
)); }
47 void writeDouble(double dub
) {
52 transfer
.f
= htolell(dub
);
53 writeBuffer(reinterpret_cast<char*>(&transfer
.t
), sizeof(int64_t));
56 void writeBool(int v
) { writeByte(static_cast<uint8_t>(v
? CT_BOOLEAN_TRUE
: CT_BOOLEAN_FALSE
)); }
58 void writeString(PyObject
* value
, int32_t len
) {
60 writeBuffer(PyBytes_AS_STRING(value
), len
);
63 bool writeListBegin(PyObject
* value
, const SetListTypeArgs
& args
, int32_t len
) {
64 int ctype
= toCompactType(args
.element_type
);
66 writeByte(static_cast<uint8_t>(len
<< 4 | ctype
));
68 writeByte(0xf0 | ctype
);
74 bool writeMapBegin(PyObject
* value
, const MapTypeArgs
& args
, int32_t len
) {
79 int ctype
= toCompactType(args
.ktag
) << 4 | toCompactType(args
.vtag
);
85 bool writeStructBegin() {
89 bool writeStructEnd() {
94 bool writeField(PyObject
* value
, const StructItemSpec
& spec
) {
95 if (spec
.type
== T_BOOL
) {
96 doWriteFieldBegin(spec
, PyObject_IsTrue(value
) ? CT_BOOLEAN_TRUE
: CT_BOOLEAN_FALSE
);
99 doWriteFieldBegin(spec
, toCompactType(spec
.type
));
100 return encodeValue(value
, spec
.type
, spec
.typeargs
);
104 void writeFieldStop() { writeByte(0); }
106 bool readBool(bool& val
) {
107 if (readBool_
.exists
) {
108 readBool_
.exists
= false;
109 val
= readBool_
.value
;
113 if (!readBytes(&buf
, 1)) {
116 val
= buf
[0] == CT_BOOLEAN_TRUE
;
119 bool readI8(int8_t& val
) {
121 if (!readBytes(&buf
, 1)) {
128 bool readI16(int16_t& val
) {
130 if (readVarint
<uint16_t, 3>(uval
)) {
131 val
= fromZigZag
<int16_t, uint16_t>(uval
);
137 bool readI32(int32_t& val
) {
139 if (readVarint
<uint32_t, 5>(uval
)) {
140 val
= fromZigZag
<int32_t, uint32_t>(uval
);
146 bool readI64(int64_t& val
) {
148 if (readVarint
<uint64_t, 10>(uval
)) {
149 val
= fromZigZag
<int64_t, uint64_t>(uval
);
155 bool readDouble(double& val
) {
162 if (!readBytes(&buf
, 8)) {
165 memcpy(&transfer
.f
, buf
, sizeof(int64_t));
166 transfer
.f
= letohll(transfer
.f
);
171 int32_t readString(char** buf
) {
173 if (!readVarint
<uint32_t, 5>(len
) || !checkLengthLimit(len
, stringLimit())) {
179 if (!readBytes(buf
, len
)) {
185 int32_t readListBegin(TType
& etype
) {
190 etype
= getTType(b
& 0xf);
194 uint32_t len
= (b
>> 4) & 0xf;
195 if (len
== 15 && !readVarint
<uint32_t, 5>(len
)) {
198 if (!checkLengthLimit(len
, containerLimit())) {
204 int32_t readMapBegin(TType
& ktype
, TType
& vtype
) {
206 if (!readVarint
<uint32_t, 5>(len
) || !checkLengthLimit(len
, containerLimit())) {
211 if (!readByte(kvType
)) {
214 ktype
= getTType(kvType
>> 4);
215 vtype
= getTType(kvType
& 0xf);
216 if (ktype
== -1 || vtype
== -1) {
223 bool readStructBegin() {
227 bool readStructEnd() {
231 bool readFieldBegin(TType
& type
, int16_t& tag
);
235 return readBool(val
);
237 #define SKIPBYTES(n) \
239 if (!readBytes(&dummy_buf_, (n))) { \
244 bool skipByte() { SKIPBYTES(1); }
245 bool skipDouble() { SKIPBYTES(8); }
260 if (!readVarint
<uint32_t, 5>(len
)) {
270 CT_BOOLEAN_TRUE
= 0x01,
271 CT_BOOLEAN_FALSE
= 0x02,
284 static const uint8_t TTypeToCType
[];
286 TType
getTType(uint8_t type
);
288 int toCompactType(TType type
) {
289 int i
= static_cast<int>(type
);
290 return i
< 16 ? TTypeToCType
[i
] : -1;
293 uint32_t toZigZag(int32_t val
) { return (val
>> 31) ^ (val
<< 1); }
295 uint64_t toZigZag64(int64_t val
) { return (val
>> 63) ^ (val
<< 1); }
297 int writeVarint(uint32_t val
) {
299 while (val
& ~0x7fU
) {
300 writeByte(static_cast<char>((val
& 0x7fU
) | 0x80U
));
304 writeByte(static_cast<char>(val
));
308 int writeVarint64(uint64_t val
) {
310 while (val
& ~0x7fULL
) {
311 writeByte(static_cast<char>((val
& 0x7fULL
) | 0x80ULL
));
315 writeByte(static_cast<char>(val
));
319 template <typename T
, int Max
>
320 bool readVarint(T
& result
) {
324 for (int i
= 0; i
< Max
; ++i
) {
329 val
|= static_cast<T
>(b
& 0x7f) << shift
;
331 val
|= static_cast<T
>(b
) << shift
;
337 PyErr_Format(PyExc_OverflowError
, "varint exceeded %d bytes", Max
);
341 template <typename S
, typename U
>
342 S
fromZigZag(U val
) {
343 return (val
>> 1) ^ static_cast<U
>(-static_cast<S
>(val
& 1));
346 void doWriteFieldBegin(const StructItemSpec
& spec
, int ctype
) {
347 int diff
= spec
.tag
- writeTags_
.top();
348 if (diff
> 0 && diff
<= 15) {
349 writeByte(static_cast<uint8_t>(diff
<< 4 | ctype
));
351 writeByte(static_cast<uint8_t>(ctype
));
354 writeTags_
.top() = spec
.tag
;
357 std::stack
<int> writeTags_
;
358 std::stack
<int> readTags_
;
368 #endif // THRIFT_PY_COMPACT_H