Skip to content

Commit 932f3a3

Browse files
iahsfacebook-github-bot
authored andcommitted
Specialize *Protocol::readStringBody for std::string
Summary: `folly::resizeWithoutInitialization` allows us to make this slightly more efficient than the general code Reviewed By: robertroeser Differential Revision: D68296464 fbshipit-source-id: a33d849336caa497b256bc5dab6e68559776d0d3
1 parent 110b233 commit 932f3a3

File tree

3 files changed

+46
-47
lines changed

3 files changed

+46
-47
lines changed

thrift/lib/cpp2/protocol/BinaryProtocol-inl.h

+1-26
Original file line numberDiff line numberDiff line change
@@ -580,32 +580,7 @@ inline void BinaryProtocolReader::readBinary(folly::IOBuf& str) {
580580
template <typename StrType>
581581
inline void BinaryProtocolReader::readStringBody(StrType& str, int32_t size) {
582582
checkStringSize(size);
583-
584-
// Catch empty string case
585-
if (size == 0) {
586-
str.clear();
587-
return;
588-
}
589-
590-
if (static_cast<int32_t>(in_.length()) < size) {
591-
if (!in_.canAdvance(size)) {
592-
protocol::TProtocolException::throwTruncatedData();
593-
}
594-
str.reserve(size); // only reserve for multi iter case below
595-
}
596-
str.clear();
597-
size_t size_left = size;
598-
while (size_left > 0) {
599-
auto data = in_.peekBytes();
600-
auto data_avail = std::min(data.size(), size_left);
601-
if (data.empty()) {
602-
TProtocolException::throwTruncatedData();
603-
}
604-
605-
str.append((const char*)data.data(), data_avail);
606-
size_left -= data_avail;
607-
in_.skipNoAdvance(data_avail);
608-
}
583+
detail::readStringBody(str, in_, size);
609584
}
610585

611586
inline bool BinaryProtocolReader::advanceToNextField(

thrift/lib/cpp2/protocol/CompactProtocol-inl.h

+2-19
Original file line numberDiff line numberDiff line change
@@ -736,25 +736,8 @@ inline void CompactProtocolReader::readStringSize(int32_t& size) {
736736

737737
template <typename StrType>
738738
inline void CompactProtocolReader::readStringBody(StrType& str, int32_t size) {
739-
if (static_cast<int32_t>(in_.length()) < size) {
740-
if (!in_.canAdvance(size)) {
741-
protocol::TProtocolException::throwTruncatedData();
742-
}
743-
str.reserve(size); // only reserve for multi iter case below
744-
}
745-
str.clear();
746-
size_t size_left = size;
747-
while (size_left > 0) {
748-
auto data = in_.peekBytes();
749-
auto data_avail = std::min(data.size(), size_left);
750-
if (data.empty()) {
751-
TProtocolException::throwTruncatedData();
752-
}
753-
754-
str.append((const char*)data.data(), data_avail);
755-
size_left -= data_avail;
756-
in_.skipNoAdvance(data_avail);
757-
}
739+
assert(size >= 0); // Checked in readStringSize
740+
detail::readStringBody(str, in_, size);
758741
}
759742

760743
template <typename StrType>

thrift/lib/cpp2/protocol/Protocol.h

+43-2
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@
2020
#include <sys/types.h>
2121

2222
#include <cstdint>
23-
#include <map>
2423
#include <memory>
2524
#include <string>
26-
#include <vector>
2725

2826
#include <glog/logging.h>
2927

28+
#include <folly/io/Cursor.h>
3029
#include <folly/io/IOBuf.h>
3130
#include <folly/io/IOBufQueue.h>
31+
#include <folly/memory/UninitializedMemoryHacks.h>
3232
#include <folly/portability/GFlags.h>
3333
#include <thrift/lib/cpp/Thrift.h>
3434
#include <thrift/lib/cpp/protocol/TProtocol.h>
@@ -400,6 +400,47 @@ struct StringTraits<std::unique_ptr<folly::IOBuf>> {
400400
}
401401
};
402402

403+
namespace detail {
404+
405+
template <typename StrType>
406+
inline void readStringBody(StrType& str, folly::io::Cursor& in, size_t size) {
407+
// Catch empty string case
408+
if (size == 0) {
409+
str.clear();
410+
return;
411+
}
412+
413+
if (in.length() < size) {
414+
if (!in.canAdvance(size)) {
415+
protocol::TProtocolException::throwTruncatedData();
416+
}
417+
str.reserve(size); // only reserve for multi iter case below
418+
}
419+
str.clear();
420+
size_t size_left = size;
421+
while (size_left > 0) {
422+
auto data = in.peekBytes();
423+
auto data_avail = std::min(data.size(), size_left);
424+
if (data.empty()) {
425+
TProtocolException::throwTruncatedData();
426+
}
427+
428+
str.append((const char*)data.data(), data_avail);
429+
size_left -= data_avail;
430+
in.skipNoAdvance(data_avail);
431+
}
432+
}
433+
434+
inline void readStringBody(
435+
std::string& str, folly::io::Cursor& in, size_t size) {
436+
folly::resizeWithoutInitialization(str, size);
437+
if (in.pullAtMost(str.data(), size) < size) {
438+
str.clear();
439+
protocol::TProtocolException::throwTruncatedData();
440+
}
441+
}
442+
} // namespace detail
443+
403444
} // namespace apache::thrift
404445

405446
#endif

0 commit comments

Comments
 (0)