Added new method to ByteBuffer & Slice (#26014)

pull/26383/head
Esun Kim 4 years ago committed by GitHub
parent e6782daf95
commit a99ead4bf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      include/grpcpp/impl/codegen/byte_buffer.h
  2. 11
      include/grpcpp/impl/codegen/slice.h
  3. 31
      src/cpp/util/byte_buffer_cc.cc
  4. 29
      test/cpp/util/byte_buffer_test.cc
  5. 6
      test/cpp/util/slice_test.cc

@ -114,6 +114,13 @@ class ByteBuffer final {
return *this;
}
// If this ByteBuffer's representation is a single flat slice, returns a
// slice referencing that array.
Status TrySingleSlice(Slice* slice) const;
/// Dump (read) the buffer contents into \a slics.
Status DumpToSingleSlice(Slice* slice) const;
/// Dump (read) the buffer contents into \a slices.
Status Dump(std::vector<Slice>* slices) const;

@ -74,6 +74,11 @@ class Slice final {
Slice(const Slice& other)
: slice_(g_core_codegen_interface->grpc_slice_ref(other.slice_)) {}
/// Move constructor, steals a reference.
Slice(Slice&& other) noexcept : slice_(other.slice_) {
other.slice_ = g_core_codegen_interface->grpc_empty_slice();
}
/// Assignment, reference count is unchanged.
Slice& operator=(Slice other) {
std::swap(slice_, other.slice_);
@ -107,6 +112,12 @@ class Slice final {
/// Raw pointer to the end (one byte \em past the last element) of the slice.
const uint8_t* end() const { return GRPC_SLICE_END_PTR(slice_); }
/// Returns a substring of the `slice` as another slice.
Slice sub(size_t begin, size_t end) const {
return Slice(g_core_codegen_interface->grpc_slice_sub(slice_, begin, end),
STEAL_REF);
}
/// Raw C slice. Caller needs to call grpc_slice_unref when done.
grpc_slice c_slice() const {
return g_core_codegen_interface->grpc_slice_ref(slice_);

@ -25,6 +25,37 @@ namespace grpc {
static internal::GrpcLibraryInitializer g_gli_initializer;
Status ByteBuffer::TrySingleSlice(Slice* slice) const {
if (!buffer_) {
return Status(StatusCode::FAILED_PRECONDITION, "Buffer not initialized");
}
if ((buffer_->type == GRPC_BB_RAW) &&
(buffer_->data.raw.compression == GRPC_COMPRESS_NONE) &&
(buffer_->data.raw.slice_buffer.count == 1)) {
grpc_slice internal_slice = buffer_->data.raw.slice_buffer.slices[0];
*slice = Slice(internal_slice, Slice::ADD_REF);
return Status::OK;
} else {
return Status(StatusCode::FAILED_PRECONDITION,
"Buffer isn't made up of a single uncompressed slice.");
}
}
Status ByteBuffer::DumpToSingleSlice(Slice* slice) const {
if (!buffer_) {
return Status(StatusCode::FAILED_PRECONDITION, "Buffer not initialized");
}
grpc_byte_buffer_reader reader;
if (!grpc_byte_buffer_reader_init(&reader, buffer_)) {
return Status(StatusCode::INTERNAL,
"Couldn't initialize byte buffer reader");
}
grpc_slice s = grpc_byte_buffer_reader_readall(&reader);
*slice = Slice(s, Slice::STEAL_REF);
grpc_byte_buffer_reader_destroy(&reader);
return Status::OK;
}
Status ByteBuffer::Dump(std::vector<Slice>* slices) const {
slices->clear();
if (!buffer_) {

@ -123,6 +123,35 @@ TEST_F(ByteBufferTest, SerializationMakesCopy) {
EXPECT_TRUE(send_buffer.Valid());
}
TEST_F(ByteBufferTest, TrySingleSliceWithSingleSlice) {
std::vector<Slice> slices;
slices.emplace_back(kContent1);
ByteBuffer buffer(&slices[0], 1);
Slice slice;
EXPECT_TRUE(buffer.TrySingleSlice(&slice).ok());
EXPECT_EQ(slice.size(), slices[0].size());
EXPECT_EQ(memcmp(slice.begin(), slices[0].begin(), slice.size()), 0);
}
TEST_F(ByteBufferTest, TrySingleSliceWithMultipleSlices) {
std::vector<Slice> slices;
slices.emplace_back(kContent1);
slices.emplace_back(kContent2);
ByteBuffer buffer(&slices[0], 2);
Slice slice;
EXPECT_FALSE(buffer.TrySingleSlice(&slice).ok());
}
TEST_F(ByteBufferTest, DumpToSingleSlice) {
std::vector<Slice> slices;
slices.emplace_back(kContent1);
slices.emplace_back(kContent2);
ByteBuffer buffer(&slices[0], 2);
Slice slice;
EXPECT_TRUE(buffer.DumpToSingleSlice(&slice).ok());
EXPECT_EQ(strlen(kContent1) + strlen(kContent2), slice.size());
}
} // namespace
} // namespace grpc

@ -124,6 +124,12 @@ TEST_F(SliceTest, Add) {
CheckSlice(spp, kContent);
}
TEST_F(SliceTest, Sub) {
Slice spp("0123456789");
Slice sub = spp.sub(1, 9);
CheckSlice(sub, "12345678");
}
TEST_F(SliceTest, Cslice) {
grpc_slice s = grpc_slice_from_copied_string(kContent);
Slice spp(s, Slice::STEAL_REF);

Loading…
Cancel
Save