|
|
@ -4,6 +4,7 @@ |
|
|
|
#include <pEp/message_api.h> |
|
|
|
#include <pEp/keymanagement.h> |
|
|
|
#include <pEp/identity_list.h> |
|
|
|
#include <utility> |
|
|
|
#include <pEp/utils.hh> |
|
|
|
#include <pEp/pEpLog.hh> |
|
|
|
#include <pEp/inspect.hh> |
|
|
@ -42,7 +43,7 @@ namespace pEp { |
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
|
|
#define EXSTR(msg) std::string(__FUNCTION__) + " - " + msg |
|
|
|
#define EXSTR(msg) std::string(__FUNCTION__) + "() - " + msg |
|
|
|
|
|
|
|
template<class T> |
|
|
|
class POD { |
|
|
@ -431,35 +432,36 @@ void test_assign(char** c_str_p, pEp::String& pstr) |
|
|
|
namespace pEp { |
|
|
|
// TOOD:
|
|
|
|
// ctor not exception safe
|
|
|
|
class TestStruct1 { |
|
|
|
// You can create an instance of a c-struct or you can wrap an already existing c-struct
|
|
|
|
// In both cases, you can define if the wrapper owns the instance, or not.
|
|
|
|
// If if owns it, it will free() it when the wrapper dies, otherwise it doesnt.
|
|
|
|
template<typename T> |
|
|
|
class PODStruct { |
|
|
|
public: |
|
|
|
// Create a new instance
|
|
|
|
TestStruct1(int i, ::Test_enum e, const std::string& str) |
|
|
|
{ |
|
|
|
pEpLogClass("called"); |
|
|
|
_c_struct_p = ::new_test_struct(0, ONE, nullptr); //dont use raw-setters
|
|
|
|
bind(true, &_c_struct_p); |
|
|
|
// need to use these setter because of value conversions
|
|
|
|
this->c_int = i; |
|
|
|
this->c_enum = e; |
|
|
|
this->c_str = str; |
|
|
|
} |
|
|
|
PODStruct() = delete; |
|
|
|
|
|
|
|
// Wrap an existing instance
|
|
|
|
TestStruct1() |
|
|
|
// Creates a new instance or binds an existing one
|
|
|
|
PODStruct( |
|
|
|
bool is_owner, |
|
|
|
std::function<T*()> alloc, |
|
|
|
std::function<void(T*)> free, |
|
|
|
T** c_struct_pp = nullptr) : |
|
|
|
_alloc(std::move(alloc)), |
|
|
|
_free(std::move(free)) |
|
|
|
{ |
|
|
|
pEpLogClass("called"); |
|
|
|
} |
|
|
|
|
|
|
|
// Best to use this constructor, as the object is in a valid state when the wrapped
|
|
|
|
// c_struct_pp is known
|
|
|
|
TestStruct1(bool is_owner, ::Test_struct1** c_struct_pp) |
|
|
|
{ |
|
|
|
pEpLogClass("called"); |
|
|
|
bind(is_owner, c_struct_pp); |
|
|
|
// if no pp is given, alloc new,
|
|
|
|
// otherwise bind to it
|
|
|
|
if (!c_struct_pp) { |
|
|
|
_c_struct_p = _alloc(); |
|
|
|
bind(is_owner, &_c_struct_p); |
|
|
|
} else { |
|
|
|
bind(is_owner, c_struct_pp); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void bind(bool is_owner, ::Test_struct1** c_struct_pp) |
|
|
|
void bind(bool is_owner, T** c_struct_pp) |
|
|
|
{ |
|
|
|
if (c_struct_pp == nullptr) { |
|
|
|
throw Exception{ EXSTR("cant bind on a nullptr") }; |
|
|
@ -474,18 +476,17 @@ namespace pEp { |
|
|
|
_c_struct_p = *_c_struct_pp; |
|
|
|
_is_bound = true; |
|
|
|
pEpLogClass(to_string()); |
|
|
|
_bind_members(); |
|
|
|
set_owner(is_owner); |
|
|
|
} |
|
|
|
|
|
|
|
~TestStruct1() |
|
|
|
~PODStruct() |
|
|
|
{ |
|
|
|
if (_is_owner) { |
|
|
|
_free(); |
|
|
|
_free(_c_struct_p); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
operator ::Test_struct1*() |
|
|
|
operator T*() |
|
|
|
{ |
|
|
|
return _c_struct_p; |
|
|
|
} |
|
|
@ -507,31 +508,18 @@ namespace pEp { |
|
|
|
return _is_owner; |
|
|
|
} |
|
|
|
|
|
|
|
pEp::POD<int> c_int{}; |
|
|
|
pEp::POD<::Test_enum> c_enum{}; |
|
|
|
pEp::String c_str{}; |
|
|
|
|
|
|
|
static bool log_enabled; |
|
|
|
|
|
|
|
private: |
|
|
|
void _bind_members() |
|
|
|
{ |
|
|
|
this->c_int.bind(&_c_struct_p->c_int); |
|
|
|
this->c_enum.bind(&_c_struct_p->c_enum); |
|
|
|
this->c_str.bind(false, &_c_struct_p->c_str); |
|
|
|
} |
|
|
|
protected: |
|
|
|
const std::function<T*()> _alloc; |
|
|
|
const std::function<void(T*)> _free; |
|
|
|
|
|
|
|
void _free() |
|
|
|
{ |
|
|
|
pEpLogClass("called"); |
|
|
|
::free_test_struct(_c_struct_p); |
|
|
|
} |
|
|
|
bool _is_bound{ false }; |
|
|
|
bool _is_owner{ false }; |
|
|
|
::Test_struct1** _c_struct_pp{ nullptr }; |
|
|
|
::Test_struct1* _c_struct_p{ nullptr }; |
|
|
|
T** _c_struct_pp{ nullptr }; |
|
|
|
T* _c_struct_p{ nullptr }; |
|
|
|
|
|
|
|
Adapter::pEpLog::pEpLogger logger{ "TestStruct", log_enabled }; |
|
|
|
Adapter::pEpLog::pEpLogger logger{ "typeid(T).name()", log_enabled }; |
|
|
|
Adapter::pEpLog::pEpLogger& m4gic_logger_n4me = logger; |
|
|
|
|
|
|
|
class Exception : public std::runtime_error { |
|
|
@ -540,8 +528,43 @@ namespace pEp { |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
// TOOD:
|
|
|
|
// ctor not exception safe
|
|
|
|
// You can create an instance of a c-struct or you can wrap an already existing c-struct
|
|
|
|
// In both cases, you can define if the wrapper owns the instance, or not.
|
|
|
|
// If if owns it, it will free() it when the wrapper dies, otherwise it doesnt.
|
|
|
|
//
|
|
|
|
// alloc/free:
|
|
|
|
// the alloc() and free() functions HAVE to use calloc/malloc NOT 'new', because we are interfacing
|
|
|
|
// c99 code, that could possible get ownership of the struct and can only free memory that has
|
|
|
|
// been allocated using malloc/calloc. (malloc/free - new/delete are NOT compatible)
|
|
|
|
class TestStruct1 : public PODStruct<::Test_struct1> { |
|
|
|
public: |
|
|
|
TestStruct1(bool is_owner, ::Test_struct1** test_struct1_p = nullptr) : |
|
|
|
PODStruct<::Test_struct1>(is_owner, _alloc, _free, test_struct1_p) |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
// fields of the struct as 'properties' ;)
|
|
|
|
pEp::POD<int> c_int{ &_c_struct_p->c_int }; |
|
|
|
pEp::POD<::Test_enum> c_enum{ &_c_struct_p->c_enum }; |
|
|
|
pEp::String c_str{ false, &_c_struct_p->c_str,"fd" }; |
|
|
|
|
|
|
|
private: |
|
|
|
static Test_struct1* _alloc() |
|
|
|
{ |
|
|
|
return (Test_struct1*)calloc(1, sizeof(Test_struct1)); |
|
|
|
} |
|
|
|
|
|
|
|
static void _free(Test_struct1* ptr) |
|
|
|
{ |
|
|
|
pEpLog("called"); |
|
|
|
::free_test_struct(ptr); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
bool TestStruct1::log_enabled{ true }; |
|
|
|
template<> |
|
|
|
bool PODStruct<::Test_struct1>::log_enabled{ true }; |
|
|
|
} // namespace pEp
|
|
|
|
|
|
|
|
|
|
|
@ -559,7 +582,7 @@ int main() |
|
|
|
std::is_pod<::Test_struct1>::value && !std::is_pointer<::Test_struct1>::value, |
|
|
|
"not an integral"); |
|
|
|
|
|
|
|
// pEp::Utils::readKey();
|
|
|
|
pEp::Utils::readKey(); |
|
|
|
pEp::Adapter::pEpLog::set_enabled(true); |
|
|
|
|
|
|
|
// POD
|
|
|
@ -590,7 +613,7 @@ int main() |
|
|
|
|
|
|
|
// String
|
|
|
|
// pEp::String::log_enabled = false;
|
|
|
|
if (1) { |
|
|
|
if (0) { |
|
|
|
//TODO: Test non-owning mode
|
|
|
|
|
|
|
|
// INVALID USAGE
|
|
|
@ -657,10 +680,11 @@ int main() |
|
|
|
} |
|
|
|
|
|
|
|
// Struct
|
|
|
|
if (0) { |
|
|
|
// create
|
|
|
|
{ |
|
|
|
pEp::TestStruct1 pstruct1(23, TWO, "pEp"); |
|
|
|
if (1) { |
|
|
|
// create an instance
|
|
|
|
if (0) { |
|
|
|
pEp::TestStruct1 pstruct1{ true }; |
|
|
|
// pEp::TestStruct1 pstruct1(true, 23, TWO, "pEp");
|
|
|
|
pEpLog(pstruct1.c_int); |
|
|
|
pEpLog(pstruct1.c_enum); |
|
|
|
pEpLog(pstruct1.c_str); |
|
|
@ -672,9 +696,9 @@ int main() |
|
|
|
pEpLog("DONE"); |
|
|
|
} |
|
|
|
|
|
|
|
// wrap
|
|
|
|
// wrap already existing instance
|
|
|
|
{ |
|
|
|
::Test_struct1* c_struct1 = new_test_struct(0, ONE, "pEp"); |
|
|
|
::Test_struct1* c_struct1 = ::new_test_struct(0, ONE, "pEp"); |
|
|
|
pEpLog(c_struct1->c_int); |
|
|
|
pEpLog(c_struct1->c_enum); |
|
|
|
pEpLog(c_struct1->c_str); |
|
|
@ -684,6 +708,7 @@ int main() |
|
|
|
pEpLog(pstruct1.c_int); |
|
|
|
pEpLog(pstruct1.c_enum); |
|
|
|
pEpLog(pstruct1.c_str); |
|
|
|
pEpLog("DONE"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|