#ifndef SENSE_API_PROVIDER_DESC_H #define SENSE_API_PROVIDER_DESC_H #include #include #include #include #include #include namespace hk { namespace sense_api { /* C++ version of the C struct above, which Harikoff uses to manage the * lib and connect implexors to it. */ class SenseApiDesc { public: class ExportedImplexorApiDesc { public: ExportedImplexorApiDesc(const CExportedImplexorApiDesc& cDesc) // The caller should sanity check before calling this constructor. : name(cDesc.name) {} const std::string name; }; public: SenseApiDesc() = default; SenseApiDesc(const CSenseApiDesc& cDesc) // The caller should sanity check before calling this constructor. : name(cDesc.name) { for (uint32_t i = 0; i < cDesc.numExportedImplexorApis; ++i) { if (!CExportedImplexorApiDesc_sanityCheck( &cDesc.exportedImplexorApis[i])) { throw std::runtime_error( "Sanity check failed for exported implexor API descriptor"); } exportedImplexorApis.push_back( ExportedImplexorApiDesc(cDesc.exportedImplexorApis[i])); } } std::string name; // These are the implexors whose APIs this lib exports. std::vector exportedImplexorApis; }; class SenseApiLib { public: SenseApiLib( const std::string& path, void *_dlopen_handle, getSenseApiDescFn *descFn) : libraryPath(path), dlopen_handle( _dlopen_handle, reinterpret_cast(&dlclose)), HK_GET_SENSE_API_DESC_FN_NAME(descFn) {} void setSenseApiDesc(const CSenseApiDesc* desc) { if (!CSenseApiDesc_sanityCheck(desc) || !Csal_libMgmtOps_sanityCheck(desc->sal_libMgmtOps)) { throw std::runtime_error( std::string(__func__) + ": Sanity check failed for sense API " "descriptor in library '" + libraryPath + "'"); } for (uint32_t i = 0; i < desc->numExportedImplexorApis; ++i) { if (!CExportedImplexorApiDesc_sanityCheck( &desc->exportedImplexorApis[i])) { throw std::runtime_error( std::string(__func__) + ": Sanity check failed for " "exported implexor API descriptor in library '" + libraryPath + "'"); } } new (&senseApiDesc) SenseApiDesc(*desc); // Placement new } public: std::string libraryPath; std::unique_ptr dlopen_handle; /* UNIMPLEMENTED: API-specific cmdline options. These affect this specific * sense api lib's behaviour globally. */ std::vector options; /** * @brief Every sense API lib is required to provide a function that returns * a CSenseApiDesc struct. This struct states which API the lib uses to * connect Harikoff to the sense provider it supports. * * This getter function should be visible to dlsym() so that Harikoff can * find it in the lib after loading it, and call it. */ std::function HK_GET_SENSE_API_DESC_FN_NAME; /** * @brief Harikoff will call the `HK_GET_SENSE_API_DESC_FN_NAME` getter * function and use the data it provides in order to fill out this * descriptor. */ SenseApiDesc senseApiDesc; }; } // namespace sense_api } // namespace hk #endif // SENSE_API_PROVIDER_DESC_H