blob: 755f24386e3421f95c00c5c3738fec92ae364422 [file] [log] [blame]
David Reisse71115b2010-10-06 17:09:56 +00001/*
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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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
17 * under the License.
18 */
19
20#ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_
21#define _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_ 1
22
Roger Meier4285ba22013-06-10 21:17:23 +020023#include <thrift/protocol/TBinaryProtocol.h>
zeshuai00786352b42020-06-15 17:00:33 +080024#include <thrift/transport/TTransportException.h>
David Reisse71115b2010-10-06 17:09:56 +000025
26#include <limits>
27
Konrad Grochowski16a23a62014-11-13 15:33:38 +010028namespace apache {
29namespace thrift {
30namespace protocol {
David Reisse71115b2010-10-06 17:09:56 +000031
Ben Craig384f9762015-07-08 20:33:03 -050032template <class Transport_, class ByteOrder_>
33uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMessageBegin(const std::string& name,
Konrad Grochowski7f4be5f2015-11-05 20:23:11 +010034 const TMessageType messageType,
35 const int32_t seqid) {
David Reisse71115b2010-10-06 17:09:56 +000036 if (this->strict_write_) {
37 int32_t version = (VERSION_1) | ((int32_t)messageType);
38 uint32_t wsize = 0;
39 wsize += writeI32(version);
40 wsize += writeString(name);
41 wsize += writeI32(seqid);
42 return wsize;
43 } else {
44 uint32_t wsize = 0;
45 wsize += writeString(name);
46 wsize += writeByte((int8_t)messageType);
47 wsize += writeI32(seqid);
48 return wsize;
49 }
50}
51
Ben Craig384f9762015-07-08 20:33:03 -050052template <class Transport_, class ByteOrder_>
53uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMessageEnd() {
David Reisse71115b2010-10-06 17:09:56 +000054 return 0;
55}
56
Ben Craig384f9762015-07-08 20:33:03 -050057template <class Transport_, class ByteOrder_>
58uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeStructBegin(const char* name) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010059 (void)name;
David Reisse71115b2010-10-06 17:09:56 +000060 return 0;
61}
62
Ben Craig384f9762015-07-08 20:33:03 -050063template <class Transport_, class ByteOrder_>
64uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeStructEnd() {
David Reisse71115b2010-10-06 17:09:56 +000065 return 0;
66}
67
Ben Craig384f9762015-07-08 20:33:03 -050068template <class Transport_, class ByteOrder_>
69uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeFieldBegin(const char* name,
Konrad Grochowski7f4be5f2015-11-05 20:23:11 +010070 const TType fieldType,
71 const int16_t fieldId) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010072 (void)name;
David Reisse71115b2010-10-06 17:09:56 +000073 uint32_t wsize = 0;
74 wsize += writeByte((int8_t)fieldType);
75 wsize += writeI16(fieldId);
76 return wsize;
77}
78
Ben Craig384f9762015-07-08 20:33:03 -050079template <class Transport_, class ByteOrder_>
80uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeFieldEnd() {
David Reisse71115b2010-10-06 17:09:56 +000081 return 0;
82}
83
Ben Craig384f9762015-07-08 20:33:03 -050084template <class Transport_, class ByteOrder_>
85uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeFieldStop() {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010086 return writeByte((int8_t)T_STOP);
David Reisse71115b2010-10-06 17:09:56 +000087}
88
Ben Craig384f9762015-07-08 20:33:03 -050089template <class Transport_, class ByteOrder_>
90uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMapBegin(const TType keyType,
Konrad Grochowski7f4be5f2015-11-05 20:23:11 +010091 const TType valType,
92 const uint32_t size) {
David Reisse71115b2010-10-06 17:09:56 +000093 uint32_t wsize = 0;
94 wsize += writeByte((int8_t)keyType);
95 wsize += writeByte((int8_t)valType);
96 wsize += writeI32((int32_t)size);
97 return wsize;
98}
99
Ben Craig384f9762015-07-08 20:33:03 -0500100template <class Transport_, class ByteOrder_>
101uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeMapEnd() {
David Reisse71115b2010-10-06 17:09:56 +0000102 return 0;
103}
104
Ben Craig384f9762015-07-08 20:33:03 -0500105template <class Transport_, class ByteOrder_>
Konrad Grochowski7f4be5f2015-11-05 20:23:11 +0100106uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeListBegin(const TType elemType,
107 const uint32_t size) {
David Reisse71115b2010-10-06 17:09:56 +0000108 uint32_t wsize = 0;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100109 wsize += writeByte((int8_t)elemType);
David Reisse71115b2010-10-06 17:09:56 +0000110 wsize += writeI32((int32_t)size);
111 return wsize;
112}
113
Ben Craig384f9762015-07-08 20:33:03 -0500114template <class Transport_, class ByteOrder_>
115uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeListEnd() {
David Reisse71115b2010-10-06 17:09:56 +0000116 return 0;
117}
118
Ben Craig384f9762015-07-08 20:33:03 -0500119template <class Transport_, class ByteOrder_>
Konrad Grochowski7f4be5f2015-11-05 20:23:11 +0100120uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeSetBegin(const TType elemType,
121 const uint32_t size) {
David Reisse71115b2010-10-06 17:09:56 +0000122 uint32_t wsize = 0;
123 wsize += writeByte((int8_t)elemType);
124 wsize += writeI32((int32_t)size);
125 return wsize;
126}
127
Ben Craig384f9762015-07-08 20:33:03 -0500128template <class Transport_, class ByteOrder_>
129uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeSetEnd() {
David Reisse71115b2010-10-06 17:09:56 +0000130 return 0;
131}
132
Ben Craig384f9762015-07-08 20:33:03 -0500133template <class Transport_, class ByteOrder_>
134uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeBool(const bool value) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100135 uint8_t tmp = value ? 1 : 0;
David Reisse71115b2010-10-06 17:09:56 +0000136 this->trans_->write(&tmp, 1);
137 return 1;
138}
139
Ben Craig384f9762015-07-08 20:33:03 -0500140template <class Transport_, class ByteOrder_>
141uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeByte(const int8_t byte) {
David Reisse71115b2010-10-06 17:09:56 +0000142 this->trans_->write((uint8_t*)&byte, 1);
143 return 1;
144}
145
Ben Craig384f9762015-07-08 20:33:03 -0500146template <class Transport_, class ByteOrder_>
147uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI16(const int16_t i16) {
Sebastian Zenker042580f2019-01-29 15:48:12 +0100148 auto net = (int16_t)ByteOrder_::toWire16(i16);
David Reisse71115b2010-10-06 17:09:56 +0000149 this->trans_->write((uint8_t*)&net, 2);
150 return 2;
151}
152
Ben Craig384f9762015-07-08 20:33:03 -0500153template <class Transport_, class ByteOrder_>
154uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI32(const int32_t i32) {
Sebastian Zenker042580f2019-01-29 15:48:12 +0100155 auto net = (int32_t)ByteOrder_::toWire32(i32);
David Reisse71115b2010-10-06 17:09:56 +0000156 this->trans_->write((uint8_t*)&net, 4);
157 return 4;
158}
159
Ben Craig384f9762015-07-08 20:33:03 -0500160template <class Transport_, class ByteOrder_>
161uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI64(const int64_t i64) {
Sebastian Zenker042580f2019-01-29 15:48:12 +0100162 auto net = (int64_t)ByteOrder_::toWire64(i64);
David Reisse71115b2010-10-06 17:09:56 +0000163 this->trans_->write((uint8_t*)&net, 8);
164 return 8;
165}
166
Ben Craig384f9762015-07-08 20:33:03 -0500167template <class Transport_, class ByteOrder_>
168uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeDouble(const double dub) {
cyy863262d2019-01-06 10:40:58 +0800169 static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)");
170 static_assert(std::numeric_limits<double>::is_iec559, "std::numeric_limits<double>::is_iec559");
David Reisse71115b2010-10-06 17:09:56 +0000171
Sebastian Zenker042580f2019-01-29 15:48:12 +0100172 auto bits = bitwise_cast<uint64_t>(dub);
Ben Craig384f9762015-07-08 20:33:03 -0500173 bits = ByteOrder_::toWire64(bits);
David Reisse71115b2010-10-06 17:09:56 +0000174 this->trans_->write((uint8_t*)&bits, 8);
175 return 8;
176}
177
Ben Craig384f9762015-07-08 20:33:03 -0500178template <class Transport_, class ByteOrder_>
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100179template <typename StrType>
Ben Craig384f9762015-07-08 20:33:03 -0500180uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeString(const StrType& str) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100181 if (str.size() > static_cast<size_t>((std::numeric_limits<int32_t>::max)()))
Roger Meierb69d24d2012-10-04 18:02:15 +0000182 throw TProtocolException(TProtocolException::SIZE_LIMIT);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100183 auto size = static_cast<uint32_t>(str.size());
David Reisse71115b2010-10-06 17:09:56 +0000184 uint32_t result = writeI32((int32_t)size);
185 if (size > 0) {
186 this->trans_->write((uint8_t*)str.data(), size);
187 }
188 return result + size;
189}
190
Ben Craig384f9762015-07-08 20:33:03 -0500191template <class Transport_, class ByteOrder_>
192uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeBinary(const std::string& str) {
193 return TBinaryProtocolT<Transport_, ByteOrder_>::writeString(str);
David Reisse71115b2010-10-06 17:09:56 +0000194}
195
196/**
197 * Reading functions
198 */
199
Ben Craig384f9762015-07-08 20:33:03 -0500200template <class Transport_, class ByteOrder_>
201uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMessageBegin(std::string& name,
Konrad Grochowski7f4be5f2015-11-05 20:23:11 +0100202 TMessageType& messageType,
203 int32_t& seqid) {
David Reisse71115b2010-10-06 17:09:56 +0000204 uint32_t result = 0;
205 int32_t sz;
206 result += readI32(sz);
207
208 if (sz < 0) {
209 // Check for correct version number
210 int32_t version = sz & VERSION_MASK;
211 if (version != VERSION_1) {
212 throw TProtocolException(TProtocolException::BAD_VERSION, "Bad version identifier");
213 }
214 messageType = (TMessageType)(sz & 0x000000ff);
215 result += readString(name);
216 result += readI32(seqid);
217 } else {
218 if (this->strict_read_) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100219 throw TProtocolException(TProtocolException::BAD_VERSION,
220 "No version identifier... old protocol client in strict mode?");
David Reisse71115b2010-10-06 17:09:56 +0000221 } else {
222 // Handle pre-versioned input
223 int8_t type;
224 result += readStringBody(name, sz);
225 result += readByte(type);
226 messageType = (TMessageType)type;
227 result += readI32(seqid);
228 }
229 }
230 return result;
231}
232
Ben Craig384f9762015-07-08 20:33:03 -0500233template <class Transport_, class ByteOrder_>
234uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMessageEnd() {
David Reisse71115b2010-10-06 17:09:56 +0000235 return 0;
236}
237
Ben Craig384f9762015-07-08 20:33:03 -0500238template <class Transport_, class ByteOrder_>
239uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readStructBegin(std::string& name) {
David Reisse71115b2010-10-06 17:09:56 +0000240 name = "";
241 return 0;
242}
243
Ben Craig384f9762015-07-08 20:33:03 -0500244template <class Transport_, class ByteOrder_>
245uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readStructEnd() {
David Reisse71115b2010-10-06 17:09:56 +0000246 return 0;
247}
248
Ben Craig384f9762015-07-08 20:33:03 -0500249template <class Transport_, class ByteOrder_>
250uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readFieldBegin(std::string& name,
Konrad Grochowski7f4be5f2015-11-05 20:23:11 +0100251 TType& fieldType,
252 int16_t& fieldId) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100253 (void)name;
David Reisse71115b2010-10-06 17:09:56 +0000254 uint32_t result = 0;
255 int8_t type;
256 result += readByte(type);
257 fieldType = (TType)type;
258 if (fieldType == T_STOP) {
259 fieldId = 0;
260 return result;
261 }
262 result += readI16(fieldId);
263 return result;
264}
265
Ben Craig384f9762015-07-08 20:33:03 -0500266template <class Transport_, class ByteOrder_>
267uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readFieldEnd() {
David Reisse71115b2010-10-06 17:09:56 +0000268 return 0;
269}
270
Ben Craig384f9762015-07-08 20:33:03 -0500271template <class Transport_, class ByteOrder_>
272uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMapBegin(TType& keyType,
Konrad Grochowski7f4be5f2015-11-05 20:23:11 +0100273 TType& valType,
274 uint32_t& size) {
David Reisse71115b2010-10-06 17:09:56 +0000275 int8_t k, v;
276 uint32_t result = 0;
277 int32_t sizei;
278 result += readByte(k);
279 keyType = (TType)k;
280 result += readByte(v);
281 valType = (TType)v;
282 result += readI32(sizei);
283 if (sizei < 0) {
284 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
285 } else if (this->container_limit_ && sizei > this->container_limit_) {
286 throw TProtocolException(TProtocolException::SIZE_LIMIT);
287 }
288 size = (uint32_t)sizei;
zeshuai00786352b42020-06-15 17:00:33 +0800289
290 TMap map(keyType, valType, size);
291 checkReadBytesAvailable(map);
292
David Reisse71115b2010-10-06 17:09:56 +0000293 return result;
294}
295
Ben Craig384f9762015-07-08 20:33:03 -0500296template <class Transport_, class ByteOrder_>
297uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readMapEnd() {
David Reisse71115b2010-10-06 17:09:56 +0000298 return 0;
299}
300
Ben Craig384f9762015-07-08 20:33:03 -0500301template <class Transport_, class ByteOrder_>
302uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readListBegin(TType& elemType, uint32_t& size) {
David Reisse71115b2010-10-06 17:09:56 +0000303 int8_t e;
304 uint32_t result = 0;
305 int32_t sizei;
306 result += readByte(e);
307 elemType = (TType)e;
308 result += readI32(sizei);
309 if (sizei < 0) {
310 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
311 } else if (this->container_limit_ && sizei > this->container_limit_) {
312 throw TProtocolException(TProtocolException::SIZE_LIMIT);
313 }
314 size = (uint32_t)sizei;
zeshuai00786352b42020-06-15 17:00:33 +0800315
316 TList list(elemType, size);
317 checkReadBytesAvailable(list);
318
David Reisse71115b2010-10-06 17:09:56 +0000319 return result;
320}
321
Ben Craig384f9762015-07-08 20:33:03 -0500322template <class Transport_, class ByteOrder_>
323uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readListEnd() {
David Reisse71115b2010-10-06 17:09:56 +0000324 return 0;
325}
326
Ben Craig384f9762015-07-08 20:33:03 -0500327template <class Transport_, class ByteOrder_>
328uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readSetBegin(TType& elemType, uint32_t& size) {
David Reisse71115b2010-10-06 17:09:56 +0000329 int8_t e;
330 uint32_t result = 0;
331 int32_t sizei;
332 result += readByte(e);
333 elemType = (TType)e;
334 result += readI32(sizei);
335 if (sizei < 0) {
336 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
337 } else if (this->container_limit_ && sizei > this->container_limit_) {
338 throw TProtocolException(TProtocolException::SIZE_LIMIT);
339 }
340 size = (uint32_t)sizei;
zeshuai00786352b42020-06-15 17:00:33 +0800341
342 TSet set(elemType, size);
343 checkReadBytesAvailable(set);
344
David Reisse71115b2010-10-06 17:09:56 +0000345 return result;
346}
347
Ben Craig384f9762015-07-08 20:33:03 -0500348template <class Transport_, class ByteOrder_>
349uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readSetEnd() {
David Reisse71115b2010-10-06 17:09:56 +0000350 return 0;
351}
352
Ben Craig384f9762015-07-08 20:33:03 -0500353template <class Transport_, class ByteOrder_>
354uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readBool(bool& value) {
David Reisse71115b2010-10-06 17:09:56 +0000355 uint8_t b[1];
356 this->trans_->readAll(b, 1);
357 value = *(int8_t*)b != 0;
358 return 1;
359}
360
Ben Craig384f9762015-07-08 20:33:03 -0500361template <class Transport_, class ByteOrder_>
362uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readByte(int8_t& byte) {
David Reisse71115b2010-10-06 17:09:56 +0000363 uint8_t b[1];
364 this->trans_->readAll(b, 1);
365 byte = *(int8_t*)b;
366 return 1;
367}
368
Ben Craig384f9762015-07-08 20:33:03 -0500369template <class Transport_, class ByteOrder_>
370uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readI16(int16_t& i16) {
Christian Lavoie2bbc3282011-02-08 23:05:47 +0000371 union bytes {
372 uint8_t b[2];
373 int16_t all;
374 } theBytes;
375 this->trans_->readAll(theBytes.b, 2);
Ben Craig384f9762015-07-08 20:33:03 -0500376 i16 = (int16_t)ByteOrder_::fromWire16(theBytes.all);
David Reisse71115b2010-10-06 17:09:56 +0000377 return 2;
378}
379
Ben Craig384f9762015-07-08 20:33:03 -0500380template <class Transport_, class ByteOrder_>
381uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readI32(int32_t& i32) {
Christian Lavoie2bbc3282011-02-08 23:05:47 +0000382 union bytes {
383 uint8_t b[4];
384 int32_t all;
385 } theBytes;
386 this->trans_->readAll(theBytes.b, 4);
Ben Craig384f9762015-07-08 20:33:03 -0500387 i32 = (int32_t)ByteOrder_::fromWire32(theBytes.all);
David Reisse71115b2010-10-06 17:09:56 +0000388 return 4;
389}
390
Ben Craig384f9762015-07-08 20:33:03 -0500391template <class Transport_, class ByteOrder_>
392uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readI64(int64_t& i64) {
Christian Lavoie2bbc3282011-02-08 23:05:47 +0000393 union bytes {
394 uint8_t b[8];
395 int64_t all;
396 } theBytes;
397 this->trans_->readAll(theBytes.b, 8);
Ben Craig384f9762015-07-08 20:33:03 -0500398 i64 = (int64_t)ByteOrder_::fromWire64(theBytes.all);
David Reisse71115b2010-10-06 17:09:56 +0000399 return 8;
400}
401
Ben Craig384f9762015-07-08 20:33:03 -0500402template <class Transport_, class ByteOrder_>
403uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readDouble(double& dub) {
cyy863262d2019-01-06 10:40:58 +0800404 static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)");
405 static_assert(std::numeric_limits<double>::is_iec559, "std::numeric_limits<double>::is_iec559");
David Reisse71115b2010-10-06 17:09:56 +0000406
Christian Lavoie2bbc3282011-02-08 23:05:47 +0000407 union bytes {
408 uint8_t b[8];
409 uint64_t all;
410 } theBytes;
411 this->trans_->readAll(theBytes.b, 8);
Ben Craig384f9762015-07-08 20:33:03 -0500412 theBytes.all = ByteOrder_::fromWire64(theBytes.all);
Christian Lavoie2bbc3282011-02-08 23:05:47 +0000413 dub = bitwise_cast<double>(theBytes.all);
David Reisse71115b2010-10-06 17:09:56 +0000414 return 8;
415}
416
Ben Craig384f9762015-07-08 20:33:03 -0500417template <class Transport_, class ByteOrder_>
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100418template <typename StrType>
Ben Craig384f9762015-07-08 20:33:03 -0500419uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readString(StrType& str) {
David Reisse71115b2010-10-06 17:09:56 +0000420 uint32_t result;
421 int32_t size;
422 result = readI32(size);
423 return result + readStringBody(str, size);
424}
425
Ben Craig384f9762015-07-08 20:33:03 -0500426template <class Transport_, class ByteOrder_>
427uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readBinary(std::string& str) {
428 return TBinaryProtocolT<Transport_, ByteOrder_>::readString(str);
David Reisse71115b2010-10-06 17:09:56 +0000429}
430
Ben Craig384f9762015-07-08 20:33:03 -0500431template <class Transport_, class ByteOrder_>
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100432template <typename StrType>
Ben Craig384f9762015-07-08 20:33:03 -0500433uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readStringBody(StrType& str, int32_t size) {
David Reisse71115b2010-10-06 17:09:56 +0000434 uint32_t result = 0;
435
436 // Catch error cases
437 if (size < 0) {
438 throw TProtocolException(TProtocolException::NEGATIVE_SIZE);
439 }
440 if (this->string_limit_ > 0 && size > this->string_limit_) {
441 throw TProtocolException(TProtocolException::SIZE_LIMIT);
442 }
443
444 // Catch empty string case
445 if (size == 0) {
Roger Meier92a90ff2012-04-13 14:50:32 +0000446 str.clear();
David Reisse71115b2010-10-06 17:09:56 +0000447 return result;
448 }
449
450 // Try to borrow first
451 const uint8_t* borrow_buf;
452 uint32_t got = size;
Sebastian Zenker042580f2019-01-29 15:48:12 +0100453 if ((borrow_buf = this->trans_->borrow(nullptr, &got))) {
David Reisse71115b2010-10-06 17:09:56 +0000454 str.assign((const char*)borrow_buf, size);
455 this->trans_->consume(size);
456 return size;
457 }
458
Ben Craigfd64c152013-10-09 15:26:05 -0500459 str.resize(size);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100460 this->trans_->readAll(reinterpret_cast<uint8_t*>(&str[0]), size);
David Reisse71115b2010-10-06 17:09:56 +0000461 return (uint32_t)size;
462}
zeshuai00786352b42020-06-15 17:00:33 +0800463
464// Return the minimum number of bytes a type will consume on the wire
465template <class Transport_, class ByteOrder_>
466int TBinaryProtocolT<Transport_, ByteOrder_>::getMinSerializedSize(TType type)
467{
468 switch (type)
469 {
470 case T_STOP: return 0;
471 case T_VOID: return 0;
472 case T_BOOL: return sizeof(int8_t);
473 case T_BYTE: return sizeof(int8_t);
474 case T_DOUBLE: return sizeof(double);
475 case T_I16: return sizeof(short);
476 case T_I32: return sizeof(int);
477 case T_I64: return sizeof(long);
478 case T_STRING: return sizeof(int); // string length
479 case T_STRUCT: return 0; // empty struct
480 case T_MAP: return sizeof(int); // element count
481 case T_SET: return sizeof(int); // element count
482 case T_LIST: return sizeof(int); // element count
483 default: throw TProtocolException(TProtocolException::UNKNOWN, "unrecognized type code");
484 }
485}
486
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100487}
488}
489} // apache::thrift::protocol
David Reisse71115b2010-10-06 17:09:56 +0000490
491#endif // #ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_