Correction of VPD using ECC

ECC algorithm corrects VPD data in 32:1 bit ratio in the
event of corruption.
Main Test Cases:
1) Check correction of KW in records.
2) Check correction while writing and reading VPD.
3) Check for Module VPD correction.

Signed-off-by: Giridhari Krishna <giridharikrishnan@gmail.com>
Change-Id: I48a3db18df9d3a2aecde814610ab1b357e6f310d
diff --git a/impl.cpp b/impl.cpp
index a8bd694..7d51433 100644
--- a/impl.cpp
+++ b/impl.cpp
@@ -74,7 +74,7 @@
 }
 
 #ifdef IPZ_PARSER
-int Impl::vhdrEccCheck() const
+int Impl::vhdrEccCheck()
 {
     int rc = eccStatus::SUCCESS;
     auto vpdPtr = vpd.cbegin();
@@ -84,8 +84,32 @@
                           lengths::VHDR_RECORD_LENGTH,
                           const_cast<uint8_t*>(&vpdPtr[offsets::VHDR_ECC]),
                           lengths::VHDR_ECC_LENGTH);
-
-    if (l_status != VPD_ECC_OK)
+    if (l_status == VPD_ECC_CORRECTABLE_DATA)
+    {
+        try
+        {
+            if (vpdFileStream.is_open())
+            {
+                vpdFileStream.seekp(vpdStartOffset + offsets::VHDR_RECORD,
+                                    std::ios::beg);
+                vpdFileStream.write(
+                    reinterpret_cast<const char*>(&vpd[offsets::VHDR_RECORD]),
+                    lengths::VHDR_RECORD_LENGTH);
+            }
+            else
+            {
+                std::cerr << "File not open";
+                rc = eccStatus::FAILED;
+            }
+        }
+        catch (const std::fstream::failure& e)
+        {
+            std::cout << "Error while operating on file with exception:"
+                      << e.what();
+            rc = eccStatus::FAILED;
+        }
+    }
+    else if (l_status != VPD_ECC_OK)
     {
         rc = eccStatus::FAILED;
     }
@@ -93,7 +117,7 @@
     return rc;
 }
 
-int Impl::vtocEccCheck() const
+int Impl::vtocEccCheck()
 {
     int rc = eccStatus::SUCCESS;
     // Use another pointer to get ECC information from VHDR,
@@ -122,8 +146,31 @@
     auto l_status = vpdecc_check_data(
         const_cast<uint8_t*>(&vpdPtr[vtocOffset]), vtocLength,
         const_cast<uint8_t*>(&vpdPtr[vtocECCOffset]), vtocECCLength);
-
-    if (l_status != VPD_ECC_OK)
+    if (l_status == VPD_ECC_CORRECTABLE_DATA)
+    {
+        try
+        {
+            if (vpdFileStream.is_open())
+            {
+                vpdFileStream.seekp(vpdStartOffset + vtocOffset, std::ios::beg);
+                vpdFileStream.write(
+                    reinterpret_cast<const char*>(&vpdPtr[vtocOffset]),
+                    vtocLength);
+            }
+            else
+            {
+                std::cerr << "File not open";
+                rc = eccStatus::FAILED;
+            }
+        }
+        catch (const std::fstream::failure& e)
+        {
+            std::cout << "Error while operating on file with exception "
+                      << e.what();
+            rc = eccStatus::FAILED;
+        }
+    }
+    else if (l_status != VPD_ECC_OK)
     {
         rc = eccStatus::FAILED;
     }
@@ -131,7 +178,7 @@
     return rc;
 }
 
-int Impl::recordEccCheck(Binary::const_iterator iterator) const
+int Impl::recordEccCheck(Binary::const_iterator iterator)
 {
     int rc = eccStatus::SUCCESS;
 
@@ -163,7 +210,32 @@
     auto l_status = vpdecc_check_data(
         const_cast<uint8_t*>(&vpdPtr[recordOffset]), recordLength,
         const_cast<uint8_t*>(&vpdPtr[eccOffset]), eccLength);
-    if (l_status != VPD_ECC_OK)
+    if (l_status == VPD_ECC_CORRECTABLE_DATA)
+    {
+        try
+        {
+            if (vpdFileStream.is_open())
+            {
+                vpdFileStream.seekp(vpdStartOffset + recordOffset,
+                                    std::ios::beg);
+                vpdFileStream.write(
+                    reinterpret_cast<const char*>(&vpdPtr[recordOffset]),
+                    recordLength);
+            }
+            else
+            {
+                std::cerr << "File not open";
+                rc = eccStatus::FAILED;
+            }
+        }
+        catch (const std::fstream::failure& e)
+        {
+            std::cout << "Error while operating on file with exception "
+                      << e.what();
+            rc = eccStatus::FAILED;
+        }
+    }
+    else if (l_status != VPD_ECC_OK)
     {
         rc = eccStatus::FAILED;
     }
@@ -172,7 +244,7 @@
 }
 #endif
 
-void Impl::checkHeader() const
+void Impl::checkHeader()
 {
     if (vpd.empty() || (lengths::RECORD_MIN > vpd.size()))
     {
@@ -201,7 +273,7 @@
     }
 }
 
-std::size_t Impl::readTOC(Binary::const_iterator& iterator) const
+std::size_t Impl::readTOC(Binary::const_iterator& iterator)
 {
     // The offset to VTOC could be 1 or 2 bytes long
     RecordOffset vtocOffset = getVtocOffset();
@@ -244,7 +316,7 @@
 }
 
 internal::OffsetList Impl::readPT(Binary::const_iterator iterator,
-                                  std::size_t ptLength) const
+                                  std::size_t ptLength)
 {
     internal::OffsetList offsets{};