text: // Copyright @2012 JDSU Xtreme
  
  #ifndef XTREME_REFDATA_RDSTORE_H_
  #define XTREME_REFDATA_RDSTORE_H_
  
  #include <string>
  #include <list>
  #include <vector>
  #include <sstream>
  
  #include "xtreme/common/intrusive_ptr_base.h"
  #include "xtreme/common/refdata/refdata_types.h"
  #include "xtreme/refdata/rdhelper.h"
  
  namespace xtreme {
    namespace refdata {
  
      class RDStore: public xtreme::intrusive_ptr_base<RDStore> {
      public:
        void store(const std::string& csvRecLine);
        virtual void operator<<(iptr_RDRecord_t ipRec)=0;
        virtual void empty()=0;
        virtual void getCSVDataStream(std::stringstream& _csvDataSStream,
            bool useColumnsHeader = false)=0;
        void getOriginalCSVDataStream(std::stringstream& _csvDataSStream,
            bool useColumnsHeader = false);
        uint64_t getTotalRecCount() {
          uint64_t _numOfRecs = m_CSVRecordsAsInFile.size();
          return _numOfRecs;
        }
  
      protected:
        virtual void takeTour(RDStoreVisitor& _visitor);
  
      public:
        bool admit(RDStoreVisitor& _visitor) {
          // Do NOT welcome unknown Visitors !!
          if (nullptr == m_ioHelper.get())
            return false;
          if (m_ioHelper->getRDType() != _visitor.getRDType())
            return false;
  
          _visitor.arrive(m_rdVerInfo, getTotalRecCount());   // Inform Visitor that it has arrived (Check in)
          takeTour(_visitor);                                 // Take the visitor on tour to visit each record.
          _visitor.depart();                                  // Inform Visitor that it has departed(Check out)
          return true;
        }
  
        inline iptr_RDHelper_t getHelperForIO() {
          return m_ioHelper;
        }
  
        inline void setVersionInfo(const RDVer& _rdVerInfo) {
          m_rdVerInfo = _rdVerInfo;
          return;
        }
        inline RDVer getVersionInfo() {
          return m_rdVerInfo;
        }
  
        // Default Lookup implementations are NO-OP ... implement in individual lookup-stores (in utilxtreme)
        // [SARTX-1178] Modifying the lookup signature to return 'RAW' pointer to the RDRecord stored within.
        // RDStore "OWNS" the RDRecord object. Hence the caller,
        //   * Should NOT Free/Delete the RAW pointer
        //   * Should NOT Wrap the RAW pointer any other type of smart pointer [other than 'iptr_RDRecord_t']
        //     >>>>> Re-wrapping the RAW pointer in a new 'iptr_RDRecord_t' is OK.                   <<<<<
        //     >>>>> Because the reference count for that intrusive_pointer is in the object itself. <<<<<
        //     >>>>> The Re-wrapping MUST be done while the original RDStore object is alive/valid.  <<<<<
        virtual PtrRDRecord_t lookup(const RDKey& rKey,
            RD_ERROR::CODE& _ret_err) {
          // throw NotFoundErr("lookup NOT supported");
          _ret_err = RD_ERROR::kNotFound;
          return nullptr;
        }
        virtual void lookup_many(const RDKey& rKey,
            std::vector<iptr_RDRecord_t>& retRecords) {
          throw NotFoundErr("lookup_many NOT supported");
        }
        virtual ~RDStore() {
        }
  
      protected:
        explicit RDStore(const iptr_RDHelper_t& _ioHelper) :
            m_ioHelper(_ioHelper) {
        }
        iptr_RDHelper_t m_ioHelper;
        // std::string m_dataVerLabel;
        RDVer m_rdVerInfo;
        std::vector<iptr_RDRecord_t> m_CSVRecordsAsInFile;
      };
  
      typedef boost::intrusive_ptr<RDStore> iptr_RDStore_t;
  
      class RDStoreFactoryMeth {
      public:
        virtual ~RDStoreFactoryMeth() {
        }
        virtual iptr_RDStore_t getRDStore(const iptr_RDHelper_t& _ioHelper)=0;
      };
  
      class RDStoreFactoryMeth_Default: public RDStoreFactoryMeth {
      public:
        virtual iptr_RDStore_t getRDStore(const iptr_RDHelper_t& _ioHelper);
      };
    }
  }  // end of namespace xtreme
  
  #endif  // XTREME_REFDATA_INTERNAL_RDSTORE_H_
  