]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
include/denc: add missing {encode,decode}_nohead for denc_traits
authorKefu Chai <kchai@redhat.com>
Fri, 24 Mar 2017 05:38:04 +0000 (13:38 +0800)
committerKefu Chai <kchai@redhat.com>
Sat, 25 Mar 2017 04:06:04 +0000 (12:06 +0800)
implement {encode,decode}_nohead() for dec_traits<basic_string> and
bufferlist.

so compiler can find an appropriate version of decode_nohead() when
performing overload resolution. in some architectures, compiler resolves
the __u32 to size_t, which leads to a compilation failure, because the
compiler fails to instantiate the ::decode_nohead() template exposing
traits::decode_nohead().

Fixes: http://tracker.ceph.com/issues/18938
Signed-off-by: Kefu Chai <kchai@redhat.com>
src/include/denc.h
src/test/encoding.cc

index 350178085b89d420b529b54857dd548f882d8412..355b64b3a62662e84060581a1a5a678411f73889 100644 (file)
@@ -546,11 +546,19 @@ public:
                     uint64_t f=0) {
     uint32_t len;
     ::denc(len, p);
+    decode_nohead(len, s, p);
+  }
+  static void decode_nohead(size_t len, value_type& s,
+                           buffer::ptr::iterator& p) {
     s.clear();
     if (len) {
       s.append(p.get_pos_add(len), len);
     }
   }
+  static void encode_nohead(const value_type& s,
+                           buffer::list::contiguous_appender& p) {
+    p.append(s.data(), s.length());
+  }
 };
 
 //
@@ -598,6 +606,17 @@ struct denc_traits<bufferlist> {
     v.clear();
     v.push_back(p.get_ptr(len));
   }
+  static void encode_nohead(const bufferlist& v,
+                           buffer::list::contiguous_appender& p) {
+    p.append(v);
+  }
+  static void decode_nohead(size_t len, bufferlist& v,
+                           buffer::ptr::iterator& p) {
+    v.clear();
+    if (len) {
+      v.append(p.get_ptr(len));
+    }
+  }
 };
 
 //
index 6a8da8b4b0bc069ec35ed5d0086cb6f963912a8d..29c3b99fddc3c8a5e5a88447a18c947372806f4f 100644 (file)
@@ -32,6 +32,40 @@ TEST(EncodingRoundTrip, StringNewline) {
   test_encode_and_decode < std::string >(my_str);
 }
 
+template <typename Size, typename T>
+static void test_encode_and_nohead_nohead(Size len, const T& src)
+{
+  bufferlist bl(1000000);
+  encode(len, bl);
+  encode_nohead(src, bl);
+  T dst;
+  bufferlist::iterator i(bl.begin());
+  decode(len, i);
+  decode_nohead(len, dst, i);
+  ASSERT_EQ(src, dst) << "Encoding roundtrip changed the string: orig=" << src << ", but new=" << dst;
+}
+
+TEST(EncodingRoundTrip, StringNoHead) {
+  const string str("The quick brown fox jumps over the lazy dog");
+  auto size = str.size();
+  test_encode_and_nohead_nohead(static_cast<int>(size), str);
+  test_encode_and_nohead_nohead(static_cast<unsigned>(size), str);
+  test_encode_and_nohead_nohead(static_cast<uint32_t>(size), str);
+  test_encode_and_nohead_nohead(static_cast<__u32>(size), str);
+  test_encode_and_nohead_nohead(static_cast<size_t>(size), str);
+}
+
+TEST(EncodingRoundTrip, BufferListNoHead) {
+  bufferlist bl;
+  bl.append("is this a dagger which i see before me?");
+  auto size = bl.length();
+  test_encode_and_nohead_nohead(static_cast<int>(size), bl);
+  test_encode_and_nohead_nohead(static_cast<unsigned>(size), bl);
+  test_encode_and_nohead_nohead(static_cast<uint32_t>(size), bl);
+  test_encode_and_nohead_nohead(static_cast<__u32>(size), bl);
+  test_encode_and_nohead_nohead(static_cast<size_t>(size), bl);
+}
+
 typedef std::multimap < int, std::string > multimap_t;
 typedef multimap_t::value_type my_val_ty;