server/interface: simplify property_changed

The previous property_changed implementation created a dynamic vector to
hold two elements.  Switch to std::array to simplify the code and
compiled function size.

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Ia2960fdd8b979ce9ccf661b013618de8d28f5e89
diff --git a/include/sdbusplus/sdbus.hpp b/include/sdbusplus/sdbus.hpp
index b30e989..25941da 100644
--- a/include/sdbusplus/sdbus.hpp
+++ b/include/sdbusplus/sdbus.hpp
@@ -46,7 +46,7 @@
     virtual int sd_bus_emit_properties_changed_strv(sd_bus* bus,
                                                     const char* path,
                                                     const char* interface,
-                                                    char** names) = 0;
+                                                    const char** names) = 0;
 
     virtual int sd_bus_error_set(sd_bus_error* e, const char* name,
                                  const char* message) = 0;
@@ -222,10 +222,19 @@
 
     int sd_bus_emit_properties_changed_strv(sd_bus* bus, const char* path,
                                             const char* interface,
-                                            char** names) override
+                                            const char** names) override
     {
         return ::sd_bus_emit_properties_changed_strv(bus, path, interface,
-                                                     names);
+                                                     const_cast<char**>(names));
+        // The const_cast above may seem unsafe, but it safe.  sd_bus's manpage
+        // shows a 'const char*' but the header does not.  I examined the code
+        // and no modification of the strings is done.  I tried to change sdbus
+        // directly but due to quirks of C you cannot implicitly convert a
+        // 'char **' to a 'const char**', so changing the implementation causes
+        // lots of compile failures due to an incompatible API change.
+        //
+        // Performing a const_cast allows us to avoid a memory allocation of
+        // the contained strings in 'interface::property_changed'.
     }
 
     int sd_bus_error_set(sd_bus_error* e, const char* name,
diff --git a/include/sdbusplus/server/interface.hpp b/include/sdbusplus/server/interface.hpp
index acf4a09..eb55792 100644
--- a/include/sdbusplus/server/interface.hpp
+++ b/include/sdbusplus/server/interface.hpp
@@ -94,13 +94,12 @@
      */
     void property_changed(const char* property)
     {
-        std::vector<std::string> values{property};
-        sdbusplus::bus::details::Strv p(values);
+        std::array<const char*, 2> values = {property, nullptr};
 
         // Note: Converting to use _strv version, could also mock two pointer
         // use-case explicitly.
         _intf->sd_bus_emit_properties_changed_strv(
-            _bus.get(), _path.c_str(), _interf.c_str(), static_cast<char**>(p));
+            _bus.get(), _path.c_str(), _interf.c_str(), values.data());
     }
 
     /** @brief Emit the interface is added on D-Bus */
diff --git a/include/sdbusplus/test/sdbus_mock.hpp b/include/sdbusplus/test/sdbus_mock.hpp
index ff007a4..df312e2 100644
--- a/include/sdbusplus/test/sdbus_mock.hpp
+++ b/include/sdbusplus/test/sdbus_mock.hpp
@@ -30,7 +30,7 @@
     MOCK_METHOD2(sd_bus_emit_object_added, int(sd_bus*, const char*));
     MOCK_METHOD2(sd_bus_emit_object_removed, int(sd_bus*, const char*));
     MOCK_METHOD4(sd_bus_emit_properties_changed_strv,
-                 int(sd_bus*, const char*, const char*, char**));
+                 int(sd_bus*, const char*, const char*, const char**));
 
     MOCK_METHOD3(sd_bus_error_set,
                  int(sd_bus_error*, const char*, const char*));