Define hex helper utils

This commit attempts to optimize some code and reduce our dependence on
boost libraries, as the coding standard recommends.  It does this by
introducing a new method, intToHexString, which is a greatly simplified
"to hex" converter that doesn't require std::locale, or stream buffers,
and is very efficient.  This deletes our need for boost::format, as well
as our need for boost::lexical_cast, both of which are fairly heavy
libraries.

Tested:
Unit tests pass.

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I3b0f6eeb10256f87320adcc0ae9396f6bcbc8740
diff --git a/redfish-core/include/utils/hex_utils.hpp b/redfish-core/include/utils/hex_utils.hpp
new file mode 100644
index 0000000..c9fe7ef
--- /dev/null
+++ b/redfish-core/include/utils/hex_utils.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <array>
+#include <string>
+
+template <typename IntegerType>
+inline std::string intToHexString(IntegerType value,
+                                  size_t digits = sizeof(IntegerType) << 1)
+{
+    static constexpr std::array<char, 16> digitsArray = {
+        '0', '1', '2', '3', '4', '5', '6', '7',
+        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+    std::string rc(digits, '0');
+    size_t bitIndex = (digits - 1) * 4;
+    for (size_t digitIndex = 0; digitIndex < digits; digitIndex++)
+    {
+        rc[digitIndex] = digitsArray[(value >> bitIndex) & 0x0f];
+        bitIndex -= 4;
+    }
+    return rc;
+}
diff --git a/redfish-core/lib/memory.hpp b/redfish-core/lib/memory.hpp
index 2d647dc..5d508c4 100644
--- a/redfish-core/lib/memory.hpp
+++ b/redfish-core/lib/memory.hpp
@@ -19,9 +19,9 @@
 
 #include <app.hpp>
 #include <boost/container/flat_map.hpp>
-#include <boost/format.hpp>
 #include <registries/privilege_registry.hpp>
 #include <utils/collection.hpp>
+#include <utils/hex_utils.hpp>
 #include <utils/json_utils.hpp>
 
 namespace redfish
@@ -154,7 +154,7 @@
         return;
     }
 
-    aResp->res.jsonValue[key] = (boost::format("0x%04x") % *value).str();
+    aResp->res.jsonValue[key] = "0x" + intToHexString(*value);
 }
 
 inline void getPersistentMemoryProperties(
diff --git a/redfish-core/lib/processor.hpp b/redfish-core/lib/processor.hpp
index d976264..59b7ff2 100644
--- a/redfish-core/lib/processor.hpp
+++ b/redfish-core/lib/processor.hpp
@@ -177,7 +177,7 @@
                 {
                     aResp->res
                         .jsonValue["ProcessorId"]["IdentificationRegisters"] =
-                        boost::lexical_cast<std::string>(*value);
+                        "0x" + intToHexString(*value);
                 }
             }
         }
diff --git a/redfish-core/ut/hex_utils_test.cpp b/redfish-core/ut/hex_utils_test.cpp
new file mode 100644
index 0000000..708cb86
--- /dev/null
+++ b/redfish-core/ut/hex_utils_test.cpp
@@ -0,0 +1,31 @@
+#include "utils/hex_utils.hpp"
+
+#include <gmock/gmock.h>
+
+TEST(ToHexString, uint64)
+{
+    EXPECT_EQ(intToHexString(0xFFFFFFFFFFFFFFFFULL), "FFFFFFFFFFFFFFFF");
+
+    EXPECT_EQ(intToHexString<uint64_t>(0), "0000000000000000");
+    EXPECT_EQ(intToHexString<uint64_t>(0, 4), "0000");
+    EXPECT_EQ(intToHexString<uint64_t>(0, 8), "00000000");
+    EXPECT_EQ(intToHexString<uint64_t>(0, 12), "000000000000");
+    EXPECT_EQ(intToHexString<uint64_t>(0, 16), "0000000000000000");
+
+    uint64_t deadbeef = 0xDEADBEEFBAD4F00DULL;
+    EXPECT_EQ(intToHexString<uint64_t>(deadbeef), "DEADBEEFBAD4F00D");
+    EXPECT_EQ(intToHexString<uint64_t>(deadbeef, 4), "F00D");
+    EXPECT_EQ(intToHexString<uint64_t>(deadbeef, 8), "BAD4F00D");
+    EXPECT_EQ(intToHexString<uint64_t>(deadbeef, 12), "BEEFBAD4F00D");
+    EXPECT_EQ(intToHexString<uint64_t>(deadbeef, 16), "DEADBEEFBAD4F00D");
+}
+
+TEST(ToHexString, uint16)
+{
+    uint16_t beef = 0xBEEF;
+    EXPECT_EQ(intToHexString(beef), "BEEF");
+    EXPECT_EQ(intToHexString(beef, 1), "F");
+    EXPECT_EQ(intToHexString(beef, 2), "EF");
+    EXPECT_EQ(intToHexString(beef, 3), "EEF");
+    EXPECT_EQ(intToHexString(beef, 4), "BEEF");
+}
\ No newline at end of file