vpd-tool #kw support

This commit is to enable vpd-tool read and write support for pound
keywords starting with # and for numeric keywords.

This commit enables a way to read and write keyword values using --file
option, where --file takes a file with absolute path.

when --file option used with --readKeyword flag - vpd-tool saves the
output in the given file.
and when the file option used with --writeKeyword flag - the vpd-tool
takes the value from file and performs write operation.

Test:
-----------------------------------------------
Case 1: Read from hardware and save in text file
-----------------------------------------------
vpd-tool -r -H -O /sys/bus/i2c/drivers/at24/8-0050/eeprom -R PSPD -K "#D" --file /tmp/output.txt
Value read is saved in the file /tmp/output.txt

-----------------------------------------------
Case 2: Write to hardware by taking input from a text file
-----------------------------------------------
:~# cat /tmp/write.txt
00102030405060607020304050601020304050606040302010

:~# vpd-tool -w -O /sys/bus/i2c/drivers/at24/8-0050/eeprom -R PSPD -K "#D" --file /tmp/write.txt -H
Data updated successfully

:~# vpd-tool -r -H -O /sys/bus/i2c/drivers/at24/8-0050/eeprom -R PSPD -K "#D"
{
    "/sys/bus/i2c/drivers/at24/8-0050/eeprom": {
        "#D": "0x0010203040506060702030405060102030405060604030201000000000 ...0000"
    }
}

-----------------------------------------------
Case 3: Read from cache and pipe to text file
-----------------------------------------------
:~# vpd-tool -r -O /system/chassis/motherboard -R PSPD -K "#D" --file /tmp/read-motherboard-#D.txt
Value read is saved in the file /tmp/read-motherboard-#D.txt

-----------------------------------------------
Case 4: Write to cache by taking input from text file
-----------------------------------------------
:~# cat /tmp/write.txt
00102030405060607020304050601020304050606040302010

:~# vpd-tool -w -O /system/chassis/motherboard -R PSPD -K "#D" --file /tmp/write.txt
Data updated successfully

:~# vpd-tool -r -O /system/chassis/motherboard -R PSPD -K "#D"
{
    "/system/chassis/motherboard": {
        "#D": "0x0010203040506060702030405060102030405060604030201000000000000000000....."
    }
}

-----------------------------------------------
Case 5: Write to cache by taking hex input from console
-----------------------------------------------
:~# vpd-tool -w -O /system/chassis/motherboard -R PSPD -K "#D" -V 0x65
Data updated successfully

:~# vpd-tool -r -O /system/chassis/motherboard -R PSPD -K "#D"
{
    "/system/chassis/motherboard": {
        "#D": "0x65100c0c000000000000000 ...
    }
}

Case 5.1: Write to cache by providing ascii values as input from console

vpd-tool -w -O /system/chassis/motherboard -R PSPD -K "#D" -V abcd
Data updated successfully

vpd-tool -r -O /system/chassis/motherboard -R PSPD -K "#D"
{
    "/system/chassis/motherboard": {
        "#D": "0x6162636440506060702030405060102030405060604030201000000 .."
    }
}

-----------------------------------------------
Case 6: Read from cache and display on console
-----------------------------------------------
:~# vpd-tool -r -O /system/chassis/motherboard -R PSPD -K "#D"
{
    "/system/chassis/motherboard": {
        "#D": "0x00100c0c00000000000000000000000000000000000000 .....
    }
}

-----------------------------------------------
Case 7: Read from hardware and display on console
-----------------------------------------------
vpd-tool -r -O /sys/bus/i2c/drivers/at24/8-0050/eeprom -R PSPD -K "#D" -H
{
    "/sys/bus/i2c/drivers/at24/8-0050/eeprom": {
        "#D": "0x651020304050606070203040506010203040506060403020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ......... 000000000000000000000000000000000000000"
    }
}

-----------------------------------------------
Case 8: Write to hardware via console
-----------------------------------------------
vpd-tool -w -H -O /sys/bus/i2c/drivers/at24/8-0050/eeprom -R PSPD -K "#D" -V 0x00100c0c000000000000000000000000000000000000
Data updated successfully

vpd-tool -r -O /sys/bus/i2c/drivers/at24/8-0050/eeprom -R PSPD -K "#D" -H
{
    "/sys/bus/i2c/drivers/at24/8-0050/eeprom": {
        "#D": "0x00100c0c00000000000000000000000000000000000030201000000000000000000000000 ...
    }
}

-----------------------------------------------
Case 9: Write 10240 bytes on dbus
-----------------------------------------------
time vpd-tool -w -O /system/chassis/motherboard -R PSPD -K "#D" --file /tmp/output.txt

Data updated successfully

real	0m49.564s
user	0m0.047s
sys	0m0.009s

time vpd-tool -r -O /system/chassis/motherboard -R PSPD -K "#D"
{
    "/system/chassis/motherboard": {
        "#D": "0x01100c0c0000.....0000123456782746002"
    }
}

real	0m0.072s
user	0m0.057s
sys	0m0.001s
------------------------------------------------

Signed-off-by: Priyanga Ramasamy <priyanga24@in.ibm.com>
Change-Id: I3977a7778b28ebcada7788f619b18bbca6ed0c8c
diff --git a/vpd_tool_impl.hpp b/vpd_tool_impl.hpp
index 16c3a34..82a1b8c 100644
--- a/vpd_tool_impl.hpp
+++ b/vpd_tool_impl.hpp
@@ -172,6 +172,26 @@
     void getSystemDataFromCache(
         openpower::vpd::inventory::IntfPropMap& svpdBusData);
 
+    /**
+     * @brief Get data from file and store in binary format
+     *
+     * @param[out] data - The resulting binary data
+     *
+     * @return If operation is success return true, else on failure return
+     * false.
+     */
+    bool fileToVector(openpower::vpd::Binary& data);
+
+    /**
+     * @brief Copy string data to file.
+     *
+     * @param[in] input - input string
+     *
+     * @return If operation is success return true, else on failure return
+     * false.
+     */
+    bool copyStringToFile(const std::string& input);
+
   public:
     /**
      * @brief Dump the complete inventory in JSON format
@@ -191,7 +211,8 @@
      * @brief Read keyword
      * Read the given object path, record name and keyword
      * from the inventory and display the value of the keyword
-     * in JSON format.
+     * in JSON format. The read value will be piped to file if --file is given
+     * by the user. Else the value read will be displayed on console.
      */
     void readKeyword();
 
@@ -232,7 +253,8 @@
      * initialising the constructor.
      * The user can now read keyword from any hardware path irrespective of
      * whether its present or not in VPD JSON, by providing a valid offset. By
-     * default offset takes 0.
+     * default offset takes 0. The read value can be either saved in a
+     * file/displayed on console.
      *
      * @param[in] startOffset - VPD offset.
      */
@@ -277,18 +299,6 @@
     /**
      * @brief Constructor
      * Constructor is called during the
-     * object instantiation for readKeyword option.
-     */
-    VpdTool(const std::string&& fru, const std::string&& recName,
-            const std::string&& kw) :
-        fruPath(std::move(fru)),
-        recordName(std::move(recName)), keyword(std::move(kw))
-    {
-    }
-
-    /**
-     * @brief Constructor
-     * Constructor is called during the
      * object instantiation for updateKeyword option.
      */
 
@@ -299,4 +309,4 @@
         value(std::move(val))
     {
     }
-};
+};
\ No newline at end of file