Created primary API wrappers for the Isolator class

This is an attempt to abstract the internal workings of the isolator
class from the user application.

Change-Id: Ic898b202da6a0ddb368411c11218ca019d1f23fd
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/src/hei_includes.hpp b/src/hei_includes.hpp
index dbb8b35..36aa51a 100644
--- a/src/hei_includes.hpp
+++ b/src/hei_includes.hpp
@@ -10,5 +10,5 @@
 #include <hei_user_defines.hpp> // For HEI_ASSERT, HEI_INF, and HEI_ERR
 
 // Internal includes
-#include "hei_return_code.hpp"
+#include <hei_return_code.hpp>
 
diff --git a/src/hei_isolation_data.hpp b/src/hei_isolation_data.hpp
index 57344bd..66de234 100644
--- a/src/hei_isolation_data.hpp
+++ b/src/hei_isolation_data.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
-#include "hei_includes.hpp"
+#include <hei_includes.hpp>
+#include <chip_data/hei_chip_data.hpp>
 
 namespace libhei
 {
@@ -14,8 +15,17 @@
 {
   public:
 
-    /** @brief Default constructor. */
-    IsolationData() = default;
+    /**
+     * @brief Default constructor.
+     * @param i_chip     See iv_chip.
+     * @param i_chipType See iv_chipType.
+     */
+    IsolationData( void * i_chip, ChipType_t i_chipType ) :
+        iv_chip(i_chip), iv_chipType(i_chipType)
+    {}
+
+    /** @brief Destructor. */
+    ~IsolationData() = default;
 
     /** @brief Copy constructor. */
     IsolationData( const IsolationData & ) = default;
@@ -23,11 +33,35 @@
     /** @brief Assignment operator. */
     IsolationData & operator=( const IsolationData & ) = default;
 
-    /** @brief Destructor. */
-    ~IsolationData() = default;
+    /** @return The target chip pointer. */
+    void * getChip() const { return iv_chip; }
+
+    /** @return The target chip type. */
+    ChipType_t getChipType() const { return iv_chipType; }
+
+    /** @brief Flushes the data to ensure a clean slate for next isolation. */
+    void clear() {}
 
   private:
 
+    /**
+     * This is simply a pointer to a user application object that represents
+     * the target chip. The isolator does not know anything about this object
+     * nor how to use it. This parameter's only purpose is to eventually get
+     * passed back to the user application in a hardware access operation, which
+     * will be defined by the user application.
+     */
+    void * const iv_chip;
+
+    /**
+     * Each Chip Data File contains a unique chip type identifier. The user
+     * application will need to input this value so that the isolator will know
+     * which set of the isolation objects to reference.
+     */
+    const ChipType_t iv_chipType;
+
+    // TODO: add error signature list and register dump.
+
 }; // end class IsolationData
 
 } // end namespace libhei
diff --git a/src/hei_isolator.cpp b/src/hei_isolator.cpp
deleted file mode 100644
index 6a81707..0000000
--- a/src/hei_isolator.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-
-#include "hei_isolator.hpp"
-
-namespace libhei
-{
-
-ReturnCode Isolator::initialize( void * i_buffer, size_t i_bufferSize,
-                                 bool i_forceInit )
-{
-    ReturnCode rc;
-
-    // BEGIN temporary code for compilation
-    HEI_INF( "Isolator::initialize(%p,%lu,%d)", i_buffer, i_bufferSize,
-             i_forceInit );
-    // END temporary code for compilation
-
-    return rc;
-}
-
-ReturnCode Isolator::isolate( void * i_chip, ChipType_t i_chipType,
-                              IsolationData & o_isoData )
-{
-    ReturnCode rc;
-
-    // BEGIN temporary code for compilation
-    o_isoData = IsolationData();
-    HEI_INF( "Isolator::isolate(%p,%u)", i_chip, i_chipType );
-    // END temporary code for compilation
-
-    return rc;
-}
-
-} // end namespace libhei
diff --git a/src/hei_isolator.hpp b/src/hei_isolator.hpp
deleted file mode 100644
index 3a07d75..0000000
--- a/src/hei_isolator.hpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#pragma once
-
-#include "hei_includes.hpp"
-#include "hei_isolation_data.hpp"
-#include "chip_data/hei_chip_data.hpp"
-
-namespace libhei
-{
-
-/**
- * @brief This is the main API for Hardware Error Isolation (aka the isolator).
- *
- * The intended flow is to:
- *  - Create a singleton instance of an Isolator object.
- *  - Use initialize() to input each necessary Chip Data File (provided by the
- *    user application).
- *  - Call isolate() each time you want to find all active errors being
- *    reported by a chip.
- *  - Once isolation is no longer needed, the Isolator singleton can be deleted
- *    to free up internal resources.
- *
- * The purpose of the singleton instance is to avoid initializing the object
- * each time isolation is required. The data provided by the Chip Data Files is
- * static. So reinitializing would be a waste of time, unless for some reason
- * the Chip Data Files themselves are updated, which would require
- * reinitialization anyway. Of course, leaving the object in memory chews up
- * resources. So, some users may need to weigh performance vs. memory usage.
- */
-class Isolator
-{
-  public:
-
-    /** @brief Default constructor. */
-    Isolator() = default;
-
-    /** @brief Destructor. */
-    ~Isolator() = default;
-
-    /** @brief Copy constructor. */
-    Isolator( const Isolator & ) = delete;
-
-    /** @brief Assignment operator. */
-    Isolator & operator=( const Isolator & ) = delete;
-
-    /**
-     * @brief Initializes internal isolation objects based on data from the
-     *        given Chip Data File.
-     *
-     * This function only takes one Chip Data File at a time. Therefore, the
-     * user application must call this function for each Chip Data File required
-     * for isolation.
-     *
-     * Storage and management of the Chip Data Files will vary per user
-     * application. Therefore, the user application is responsible for loading
-     * the Chip Data Files into memory, as needed, and providing the location
-     * and size of the data.
-     *
-     * Once initialization has successfully completed with a Chip Data File, the
-     * file is no longer needed in memory.
-     *
-     * Details of the Chip Data File format can be found in CHIP_DATA.md.
-     *
-     * @param i_buffer     A pointer to the buffer containing a single Chip
-     *                     Data File.
-     *
-     * @param i_bufferSize The size (in bytes) of the target Chip Data File.
-     *
-     * @param i_forceInit  It is possible the user application could call this
-     *                     function for a chip type that has already been
-     *                     initialized. This is useful if for some reason the
-     *                     Chip Data File is for a chip type has been updated.
-     *                     If this function is called and a chip type has
-     *                     already been initialized:
-     *                      - false (default), the function will return
-     *                        RC_CDF_INITIALIZED and exit.
-     *                      - true, the function will delete previous isolation
-     *                        objects for this chip type and reinitialize.
-     *
-     * @return RC_SUCCESS or RC_CDF_INVALID or RC_CDF_INITIALIZED
-     */
-    ReturnCode initialize( void * i_buffer, size_t i_bufferSize,
-                           bool i_forceInit = false );
-
-    /**
-     * @brief Isolates all active hardware errors found on the given chip.
-     *
-     * This functions requires initialize() to be called with the Chip Data File
-     * corresponding to the given chip type.
-     *
-     * @param i_chip     This is simply a pointer to a user application object
-     *                   that represents the target chip. The isolator does not
-     *                   know anything about this object or how to use it. This
-     *                   parameter's only purpose is to eventually get passed
-     *                   back to the user application in a deviceRead()
-     *                   operation.
-     *
-     * @param i_chipType Each Chip Data File contains a unique chip type
-     *                   identifier. The user application will need to input
-     *                   this value so the isolator will know which set of the
-     *                   isolation objects to reference.
-     *
-     * @param o_isoData  This return object will contain a list of all active
-     *                   hardware errors on this chip, the contents of any
-     *                   registers associated with the active errors, and any
-     *                   other data that can be useful for debug.
-     *
-     * @return RC_SUCCESS or RC_CHIP_DATA_MISSING
-     */
-    ReturnCode isolate( void * i_chip, ChipType_t i_chipType,
-                        IsolationData & o_isoData );
-
-  private:
-
-}; // end class Isolator
-
-} // end namespace libhei
diff --git a/src/hei_main.hpp b/src/hei_main.hpp
new file mode 100644
index 0000000..241b625
--- /dev/null
+++ b/src/hei_main.hpp
@@ -0,0 +1,103 @@
+/**
+ * @file hei_main.hpp
+ *
+ * These are the primary APIs for Hardware Error Isolation (aka the isolator).
+ * The intended flow is to:
+ *
+ *  - Call initialize() for each necessary Chip Data File.
+ *
+ *  - Call isolate() for each chip that needs error isolation.
+ *
+ *  - Once isolation is no longer needed, call uninitialize() to free up
+ *    resources used for isolation.
+ *
+ * Note that initialize() allocates many objects used for isolation and keeps
+ * them in memory. Its purpose is to avoid initializing the objects each time
+ * isolation is required. The data provided by the Chip Data Files is static.
+ * So reinitializing would be a waste of time, unless for some reason the Chip
+ * Data Files themselves are updated, which would require reinitialization
+ * anyway. Of course, leaving the object in memory chews up resources. So, some
+ * users may need to weigh performance vs. memory usage.
+ */
+
+#pragma once
+
+#include <hei_includes.hpp>
+#include <hei_isolation_data.hpp>
+#include <isolator/hei_isolator.hpp>
+
+namespace libhei
+{
+
+/**
+ * @brief Initializes all isolation objects based on data from the given Chip
+ *        Data File.
+ *
+ * This function only takes one Chip Data File at a time. Therefore, the
+ * user application must call this function for each Chip Data File required
+ * for isolation.
+ *
+ * Storage and management of the Chip Data Files will vary per user application.
+ * Therefore, the user application is responsible for loading the Chip Data
+ * Files into memory as needed, and providing the location and size of the data.
+ *
+ * Once this function returns, the Chip Data File is no longer needed in memory.
+ *
+ * Details of the Chip Data File format can be found in CHIP_DATA.md.
+ *
+ * @param i_buffer     A pointer to the buffer containing a single Chip
+ *                     Data File.
+ *
+ * @param i_bufferSize The size (in bytes) of the target Chip Data File.
+ *
+ * @param i_forceInit  It is possible the user application could call this
+ *                     function for a chip type that has already been
+ *                     initialized. This is useful if for some reason the Chip
+ *                     Data File for a specific chip type has been updated. If
+ *                     this function is called and a chip type has already been
+ *                     initialized:
+ *                      - false (default), the function will return
+ *                        RC_CDF_INITIALIZED and exit.
+ *                      - true, the function will delete the previous isolation
+ *                        objects for this chip type and reinitialize.
+ *
+ * @return RC_SUCCESS or RC_CDF_INVALID or RC_CDF_INITIALIZED
+ */
+inline ReturnCode initialize( void * i_buffer, size_t i_bufferSize,
+                              bool i_forceInit = false )
+{
+    return Isolator::getSingleton().initialize( i_buffer, i_bufferSize,
+                                                i_forceInit );
+}
+
+/**
+ * @brief Deletes all internal isolation objects that were created by
+ *        initialize().
+ */
+inline void uninitialize()
+{
+    Isolator::getSingleton().uninitialize();
+}
+
+/**
+ * @brief Isolates all active hardware errors found on the given chip.
+ *
+ * This functions requires initialize() to be called with the Chip Data File
+ * corresponding to the given chip type.
+ *
+ * @param o_isoData  This parameter will contain a reference to the target chip
+ *                   and its chip type. The rest of the data in the object will
+ *                   be flushed and then repopulated with a list of all active
+ *                   hardware errors on this chip, the contents of any
+ *                   registers associated with the active errors, and any
+ *                   other data that can be useful for debug.
+ *
+ * @return RC_SUCCESS or RC_CHIP_DATA_MISSING
+ */
+inline ReturnCode isolate( IsolationData & o_isoData )
+{
+    return Isolator::getSingleton().isolate( o_isoData );
+}
+
+} // end namespace libhei
+
diff --git a/src/isolator/hei_isolator.cpp b/src/isolator/hei_isolator.cpp
new file mode 100644
index 0000000..64cfe3e
--- /dev/null
+++ b/src/isolator/hei_isolator.cpp
@@ -0,0 +1,42 @@
+
+#include <isolator/hei_isolator.hpp>
+
+namespace libhei
+{
+
+ReturnCode Isolator::initialize( void * i_buffer, size_t i_bufferSize,
+                                 bool i_forceInit )
+{
+    ReturnCode rc;
+
+    // BEGIN temporary code
+    HEI_INF( "Isolator::initialize(%p,%lu,%d)", i_buffer, i_bufferSize,
+             i_forceInit );
+    // END temporary code
+
+    return rc;
+}
+
+void Isolator::uninitialize()
+{
+    // BEGIN temporary code
+    HEI_INF( "Isolator::uninitialize()" );
+    // END temporary code
+}
+
+ReturnCode Isolator::isolate( IsolationData & o_isoData ) const
+{
+    ReturnCode rc;
+
+    // Flush the isolation data to ensure a clean slate.
+    o_isoData.clear();
+
+    // BEGIN temporary code
+    HEI_INF( "Isolator::isolate(%p,%u)", o_isoData.getChip(),
+             o_isoData.getChipType() );
+    // END temporary code
+
+    return rc;
+}
+
+} // end namespace libhei
diff --git a/src/isolator/hei_isolator.hpp b/src/isolator/hei_isolator.hpp
new file mode 100644
index 0000000..4687b4f
--- /dev/null
+++ b/src/isolator/hei_isolator.hpp
@@ -0,0 +1,78 @@
+#pragma once
+
+#include <hei_includes.hpp>
+#include <hei_isolation_data.hpp>
+#include <chip_data/hei_chip_data.hpp>
+
+namespace libhei
+{
+
+/**
+ * @brief This class is a complement to the main APIs. Its purpose is to store
+ *        and maintain all of the objects necessary for isolation.
+ *
+ * The intended flow is to:
+ *  - Create a singleton instance of an Isolator object via getSingleton().
+ *  - Use initialize() to input each necessary Chip Data File provided by the
+ *    user application.
+ *  - Call isolate() each time you want to find all active errors being
+ *    reported by a chip.
+ *  - Once isolation is no longer needed, use uninitialize() to free up
+ *    internal resources.
+ *
+ * The purpose of the singleton instance is to avoid initializing the object
+ * each time isolation is required. The data provided by the Chip Data Files is
+ * static. So reinitializing would be a waste of time, unless for some reason
+ * the Chip Data Files themselves are updated, which would require
+ * reinitialization anyway. Of course, leaving the object in memory chews up
+ * resources. So, some users may need to weigh performance vs. memory usage.
+ */
+class Isolator
+{
+  private: // This class cannot be instantiated. Use getSingleton() instead.
+
+    /** @brief Default constructor. */
+    Isolator() = default;
+
+    /** @brief Destructor. */
+    ~Isolator()
+    {
+        // Clear out all of the internal isolation objects.
+        uninitialize();
+    }
+
+    /** @brief Copy constructor. */
+    Isolator( const Isolator & ) = delete;
+
+    /** @brief Assignment operator. */
+    Isolator & operator=( const Isolator & ) = delete;
+
+  public:
+
+    /** @brief Provides access to a singleton instance of this object. */
+    static Isolator & getSingleton()
+    {
+        static Isolator theIsolator;
+        return theIsolator;
+    }
+
+    /** @brief See API wrapper description in hei_main.hpp. */
+    ReturnCode initialize( void * i_buffer, size_t i_bufferSize,
+                           bool i_forceInit = false );
+
+    /**
+     * @brief See API wrapper description in hei_main.hpp.
+     *
+     * This function is called in the destructor. Therefore, it should never
+     * throw an exception.
+     */
+    void uninitialize();
+
+    /** @brief See API wrapper description in hei_main.hpp. */
+    ReturnCode isolate( IsolationData & o_isoData ) const;
+
+  private:
+
+}; // end class Isolator
+
+} // end namespace libhei