124 lines
3.7 KiB
C++
124 lines
3.7 KiB
C++
// Copyright 2016 Etix Labs
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "cachemanager.h" // for cache_manager
|
|
#include <dlfcn.h> // for dlerror, dlclose, dlopen, dlsym, etc
|
|
#include <logger.h> // for LOG_ERR_
|
|
#include <stdbool.h> // for bool, false, true
|
|
#include <algorithm> // for move
|
|
|
|
#include <errno.h>
|
|
|
|
namespace etix {
|
|
|
|
namespace cameradar {
|
|
|
|
#ifdef __APPLE__
|
|
const std::string cache_manager::PLUGIN_EXT = ".dylib";
|
|
#elif __linux__
|
|
const std::string cache_manager::PLUGIN_EXT = ".so";
|
|
#endif
|
|
|
|
const std::string cache_manager::default_symbol = "cache_manager_instance_new";
|
|
|
|
cache_manager::cache_manager(const std::string& path,
|
|
const std::string& name,
|
|
const std::string& symbol)
|
|
: name(name), path(path), symbol(symbol), handle(nullptr), ptr(nullptr) {}
|
|
|
|
cache_manager::cache_manager(cache_manager&& old)
|
|
: path(std::move(old.path)), symbol(std::move(old.symbol)) {
|
|
this->handle = old.handle;
|
|
old.handle = nullptr;
|
|
this->ptr = old.ptr;
|
|
old.ptr = nullptr;
|
|
}
|
|
|
|
cache_manager::~cache_manager() {
|
|
if (this->ptr) {
|
|
delete this->ptr;
|
|
this->ptr = nullptr;
|
|
}
|
|
if (this->handle) { dlclose(handle); }
|
|
}
|
|
|
|
bool
|
|
cache_manager::make_instance() {
|
|
cache_manager_iface* (*new_fn)() = nullptr;
|
|
|
|
// Gets the path to the dynamic library
|
|
auto real_path = this->make_full_path();
|
|
|
|
// Opens it to get the handle
|
|
this->handle = dlopen(real_path.c_str(), RTLD_LAZY);
|
|
if (this->handle == nullptr) {
|
|
std::cout << "error: " << dlerror() << std::endl;
|
|
LOG_ERR_("Failed to load cache manager: " + this->name + ", invalid path",
|
|
"cache manager loader");
|
|
return false;
|
|
} else {
|
|
// Gets the symbol and checks if the library is valid
|
|
*(void**)(&new_fn) = dlsym(this->handle, symbol.c_str());
|
|
if (dlerror() != nullptr) {
|
|
LOG_ERR_("Invalid cache manager package: " + this->name, "cache manager loader");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Returns a string containing the most recent dl* error
|
|
dlerror();
|
|
|
|
// Instantiates the cache manager
|
|
this->ptr = (*new_fn)();
|
|
if (this->ptr == nullptr) {
|
|
LOG_ERR_("Invalid cache manager format: " + this->name, "cache manager loader");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Generates a path as such : /libdumb_cache_manager.so
|
|
std::string
|
|
cache_manager::make_full_path() {
|
|
std::string full_path = this->path;
|
|
full_path += "/lib";
|
|
full_path += this->name;
|
|
full_path += "_cache_manager";
|
|
full_path += PLUGIN_EXT;
|
|
|
|
return full_path;
|
|
}
|
|
|
|
cache_manager_iface* cache_manager::operator->() { return this->ptr; }
|
|
|
|
const cache_manager_iface* cache_manager::operator->() const { return this->ptr; }
|
|
|
|
bool operator==(std::nullptr_t nullp, const cache_manager& p) { return p.ptr == nullp; }
|
|
|
|
bool operator==(const cache_manager& p, std::nullptr_t nullp) { return p.ptr == nullp; }
|
|
|
|
bool operator!=(std::nullptr_t nullp, const cache_manager& p) { return p.ptr != nullp; }
|
|
|
|
bool operator!=(const cache_manager& p, std::nullptr_t nullp) { return p.ptr != nullp; }
|
|
|
|
cache_manager_base&
|
|
cache_manager_base::get_instance() {
|
|
return *this;
|
|
}
|
|
|
|
} // cameradar
|
|
|
|
} // etix
|