vpd-tool:UTF-8 encoding support on hardware read

Keyword values when in unreadable format may need to be converted
to Hex. This code converts data from HW to readable format.

Test:
root@bonn003:~# tmp/vpd-tool -r -H -O "/sys/bus/i2c/drivers/at24/8-0050/eeprom" -R VINI -K SN
{
    "/sys/bus/i2c/drivers/at24/8-0050/eeprom": {
        "SN": "YF30UF31C007"
    }
}
root@bonn003:~# tmp/vpd-tool -r -H -O "/sys/bus/i2c/drivers/at24/8-0050/eeprom" -R VINI -K HW
{
    "/sys/bus/i2c/drivers/at24/8-0050/eeprom": {
        "HW": "0x8001"
    }
}

Change-Id: I28d9189d95202a565bcba81299f2e548cb4cb83a
Signed-off-by: Giridhari Krishna <giridharikrishnan@gmail.com>
diff --git a/ibm_vpd_utils.cpp b/ibm_vpd_utils.cpp
index 8d93606..f717c13 100644
--- a/ibm_vpd_utils.cpp
+++ b/ibm_vpd_utils.cpp
@@ -676,47 +676,57 @@
     return kwVal;
 }
 
-std::string byteArrayToHexString(const Binary& vec)
+std::string hexString(const std::variant<Binary, std::string>& kw)
 {
-    std::stringstream ss;
-    std::string hexRep = "0x";
-    ss << hexRep;
-    std::string str = ss.str();
-
-    // convert Decimal to Hex string
-    for (auto& v : vec)
-    {
-        ss << std::setfill('0') << std::setw(2) << std::hex << (int)v;
-        str = ss.str();
-    }
-    return str;
+    std::string hexString;
+    std::visit(
+        [&hexString](auto&& kw) {
+            for (auto& kwVal : kw)
+            {
+                std::stringstream ss;
+                std::string hexRep = "0x";
+                ss << hexRep;
+                ss << std::setfill('0') << std::setw(2) << std::hex
+                   << static_cast<int>(kwVal);
+                hexString = ss.str();
+            }
+        },
+        kw);
+    return hexString;
 }
 
-std::string getPrintableValue(const Binary& vec)
+std::string getPrintableValue(const std::variant<Binary, std::string>& kwVal)
 {
-    std::string str{};
-
-    // find for a non printable value in the vector
-    const auto it = std::find_if(vec.begin(), vec.end(),
-                                 [](const auto& ele) { return !isprint(ele); });
-
-    if (it != vec.end()) // if the given vector has any non printable value
-    {
-        for (auto itr = it; itr != vec.end(); itr++)
-        {
-            if (*itr != 0x00)
+    std::string kwString{};
+    std::visit(
+        [&kwString](auto&& kwVal) {
+            const auto it =
+                std::find_if(kwVal.begin(), kwVal.end(),
+                             [](const auto& kw) { return !isprint(kw); });
+            if (it != kwVal.end())
             {
-                str = byteArrayToHexString(vec);
-                return str;
+                bool printable = true;
+                for (auto itr = it; itr != kwVal.end(); itr++)
+                {
+                    if (*itr != 0x00)
+                    {
+                        kwString = hexString(kwVal);
+                        printable = false;
+                        break;
+                    }
+                }
+                if (printable)
+                {
+                    kwString = std::string(kwVal.begin(), it);
+                }
             }
-        }
-        str = std::string(vec.begin(), it);
-    }
-    else
-    {
-        str = std::string(vec.begin(), vec.end());
-    }
-    return str;
+            else
+            {
+                kwString = std::string(kwVal.begin(), kwVal.end());
+            }
+        },
+        kwVal);
+    return kwString;
 }
 
 void executePostFailAction(const nlohmann::json& json, const std::string& file)
@@ -1043,4 +1053,4 @@
     return vpdVector;
 }
 } // namespace vpd
-} // namespace openpower
+} // namespace openpower
\ No newline at end of file