aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Vijay Pai <vpai@google.com>2017-08-04 10:20:24 -0700
committerGravatar GitHub <noreply@github.com>2017-08-04 10:20:24 -0700
commit09798bc3d682cae9a5fb160ae707a4cbbd5dd130 (patch)
tree0f21d59697aaf2449f3254e037833296b114a7df
parentb6385410ccc84cfeb7c3ab4f2c399905cb8271fa (diff)
parentce58cf8c44c9d41b50f85a9b87337f0736022e7a (diff)
Merge pull request #12065 from vjpai/moreslices
Add Slice constructors to match all grpc_slice cases
-rw-r--r--include/grpc++/support/slice.h14
-rw-r--r--src/cpp/util/slice_cc.cc7
-rw-r--r--test/cpp/util/slice_test.cc36
3 files changed, 57 insertions, 0 deletions
diff --git a/include/grpc++/support/slice.h b/include/grpc++/support/slice.h
index 0b4ba7cecb..bbf97f280e 100644
--- a/include/grpc++/support/slice.h
+++ b/include/grpc++/support/slice.h
@@ -67,6 +67,20 @@ class Slice final {
return *this;
}
+ /// Create a slice pointing at some data. Calls malloc to allocate a refcount
+ /// for the object, and arranges that destroy will be called with the
+ /// user data pointer passed in at destruction. Can be the same as buf or
+ /// different (e.g., if data is part of a larger structure that must be
+ /// destroyed when the data is no longer needed)
+ Slice(void* buf, size_t len, void (*destroy)(void*), void* user_data);
+
+ /// Specialization of above for common case where buf == user_data
+ Slice(void* buf, size_t len, void (*destroy)(void*))
+ : Slice(buf, len, destroy, buf) {}
+
+ /// Similar to the above but has a destroy that also takes slice length
+ Slice(void* buf, size_t len, void (*destroy)(void*, size_t));
+
/// Byte size.
size_t size() const { return GRPC_SLICE_LENGTH(slice_); }
diff --git a/src/cpp/util/slice_cc.cc b/src/cpp/util/slice_cc.cc
index 56e0328b94..486d0cdf0e 100644
--- a/src/cpp/util/slice_cc.cc
+++ b/src/cpp/util/slice_cc.cc
@@ -17,6 +17,7 @@
*/
#include <grpc++/support/slice.h>
+#include <grpc/slice.h>
namespace grpc {
@@ -43,4 +44,10 @@ Slice::Slice(const void* buf, size_t len, StaticSlice)
Slice::Slice(const Slice& other) : slice_(grpc_slice_ref(other.slice_)) {}
+Slice::Slice(void* buf, size_t len, void (*destroy)(void*), void* user_data)
+ : slice_(grpc_slice_new_with_user_data(buf, len, destroy, user_data)) {}
+
+Slice::Slice(void* buf, size_t len, void (*destroy)(void*, size_t))
+ : slice_(grpc_slice_new_with_len(buf, len, destroy)) {}
+
} // namespace grpc
diff --git a/test/cpp/util/slice_test.cc b/test/cpp/util/slice_test.cc
index 9e3329fab0..8a8962d7ee 100644
--- a/test/cpp/util/slice_test.cc
+++ b/test/cpp/util/slice_test.cc
@@ -63,6 +63,42 @@ TEST_F(SliceTest, StaticBuf) {
CheckSlice(spp, kContent);
}
+TEST_F(SliceTest, SliceNew) {
+ char* x = new char[strlen(kContent) + 1];
+ strcpy(x, kContent);
+ Slice spp(x, strlen(x), [](void* p) { delete[] reinterpret_cast<char*>(p); });
+ CheckSlice(spp, kContent);
+}
+
+TEST_F(SliceTest, SliceNewDoNothing) {
+ Slice spp(const_cast<char*>(kContent), strlen(kContent), [](void* p) {});
+ CheckSlice(spp, kContent);
+}
+
+TEST_F(SliceTest, SliceNewWithUserData) {
+ struct stest {
+ char* x;
+ int y;
+ };
+ auto* t = new stest;
+ t->x = new char[strlen(kContent) + 1];
+ strcpy(t->x, kContent);
+ Slice spp(t->x, strlen(t->x),
+ [](void* p) {
+ auto* t = reinterpret_cast<stest*>(p);
+ delete[] t->x;
+ delete t;
+ },
+ t);
+ CheckSlice(spp, kContent);
+}
+
+TEST_F(SliceTest, SliceNewLen) {
+ Slice spp(const_cast<char*>(kContent), strlen(kContent),
+ [](void* p, size_t l) { EXPECT_EQ(l, strlen(kContent)); });
+ CheckSlice(spp, kContent);
+}
+
TEST_F(SliceTest, Steal) {
grpc_slice s = grpc_slice_from_copied_string(kContent);
Slice spp(s, Slice::STEAL_REF);