message-read: support obj-path and signature

Change-Id: Iafc2f26a10f0c5c84805e1d28bea8f17eaadc03c
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/sdbusplus/message/read.hpp b/sdbusplus/message/read.hpp
index a601b1f..f7ab4d3 100644
--- a/sdbusplus/message/read.hpp
+++ b/sdbusplus/message/read.hpp
@@ -45,8 +45,12 @@
  *
  */
 template<typename T> struct can_read_multiple : std::true_type {};
-    // std::string needs a c_str() call.
+    // std::string needs a char* conversion.
 template<> struct can_read_multiple<std::string> : std::false_type {};
+    // object_path needs a char* conversion.
+template<> struct can_read_multiple<object_path> : std::false_type {};
+    // signature needs a char* conversion.
+template<> struct can_read_multiple<signature> : std::false_type {};
     // bool needs to be resized to int, per sdbus documentation.
 template<> struct can_read_multiple<bool> : std::false_type {};
     // std::vector needs a loop.
@@ -123,6 +127,20 @@
     }
 };
 
+/** @brief Specialization of read_single for details::string_wrapper. */
+template <typename T> struct read_single<details::string_wrapper<T>>
+{
+    template<typename S>
+    static void op(sd_bus_message* m, S&& s)
+    {
+        constexpr auto dbusType = std::get<0>(types::type_id<S>());
+        const char* str = nullptr;
+        sd_bus_message_read_basic(m, dbusType, &str);
+        s.str = str;
+    }
+};
+
+
 /** @brief Specialization of read_single for bools. */
 template <> struct read_single<bool>
 {
diff --git a/test/message/read.cpp b/test/message/read.cpp
index 329094e..2b137d7 100644
--- a/test/message/read.cpp
+++ b/test/message/read.cpp
@@ -224,6 +224,34 @@
         b.call_noreply(m);
     }
 
+    // Test object_path and signature.
+    {
+        auto m = newMethodCall__test(b);
+        auto o = sdbusplus::message::object_path("/asdf");
+        auto s = sdbusplus::message::signature("iii");
+        m.append(1, o, s, 4);
+        verifyTypeString = "iogi";
+
+        struct verify
+        {
+            static void op(sdbusplus::message::message& m)
+            {
+                int32_t a = 0, b = 0;
+                sdbusplus::message::object_path o;
+                sdbusplus::message::signature s;
+                m.read(a, o, s, b);
+                assert(a == 1);
+                assert(b == 4);
+                assert(std::string(o) == "/asdf"s);
+                assert(std::string(s) == "iii"s);
+            }
+        };
+        verifyCallback = &verify::op;
+
+        b.call_noreply(m);
+    }
+
+
     // Test vector.
     {
         auto m = newMethodCall__test(b);