native_types: Reduce append allocation

This builds the string from left to right, instead of dealing with
string inserts, optimizing for allocations. Uses our own hex encoder
instead of relying on systemd libraries. This maintains explicit
compatability with the systemd encoding scheme.

Change-Id: Ia6c2f4fb19984f549c6bac2d67d0b5d610022038
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/test/message/types.cpp b/test/message/types.cpp
index 3bbd937..5e4e982 100644
--- a/test/message/types.cpp
+++ b/test/message/types.cpp
@@ -53,6 +53,10 @@
     EXPECT_EQ(sdbusplus::message::object_path("/_2d").filename(), "-");
     EXPECT_EQ(sdbusplus::message::object_path("/_20").filename(), " ");
     EXPECT_EQ(sdbusplus::message::object_path("/_2F").filename(), "/");
+    EXPECT_EQ(sdbusplus::message::object_path("/_").filename(), "");
+    EXPECT_EQ(sdbusplus::message::object_path("/_2").filename(), "");
+    EXPECT_EQ(sdbusplus::message::object_path("/_2y").filename(), "");
+    EXPECT_EQ(sdbusplus::message::object_path("/_y2").filename(), "");
     EXPECT_EQ(sdbusplus::message::object_path("/bios_active").filename(),
               "bios_active");
 }
@@ -73,6 +77,8 @@
 {
     EXPECT_EQ(sdbusplus::message::object_path("/") / "abc",
               sdbusplus::message::object_path("/_61bc"));
+    EXPECT_EQ(sdbusplus::message::object_path("/") / "abc",
+              sdbusplus::message::object_path("/_61bc"));
     EXPECT_EQ(sdbusplus::message::object_path("/abc") / "def",
               sdbusplus::message::object_path("/abc/_64ef"));
     EXPECT_EQ(sdbusplus::message::object_path("/abc") / "-",
@@ -83,6 +89,10 @@
               sdbusplus::message::object_path("/abc/_2f"));
     EXPECT_EQ(sdbusplus::message::object_path("/abc") / "ab_cd",
               sdbusplus::message::object_path("/abc/_61b_5fcd"));
+    EXPECT_EQ(sdbusplus::message::object_path("/abc") / "_ab_cd",
+              sdbusplus::message::object_path("/abc/_5fab_5fcd"));
+    EXPECT_EQ(sdbusplus::message::object_path("/abc") / "ab-c_d",
+              sdbusplus::message::object_path("/abc/_61b_2dc_5fd"));
 
     // Test the std::string overload.  This is largely just for coverage
     EXPECT_EQ(sdbusplus::message::object_path("/") / std::string("abc"),
@@ -96,8 +106,8 @@
     EXPECT_EQ(path, sdbusplus::message::object_path("/_61bc"));
 
     sdbusplus::message::object_path path2("/");
-    path2 /= std::string("def");
-    EXPECT_EQ(path2, sdbusplus::message::object_path("/_64ef"));
+    path2 /= std::string("d-ef");
+    EXPECT_EQ(path2, sdbusplus::message::object_path("/_64_2def"));
 }
 
 TEST(MessageTypes, Signature)