|
|
@ -6,146 +6,37 @@ |
|
|
|
#include <pEp/identity_list.h> |
|
|
|
#include <pEp/utils.hh> |
|
|
|
#include <pEp/pEpLog.hh> |
|
|
|
#include <sstream> |
|
|
|
#include <pEp/inspect.hh> |
|
|
|
#include <type_traits> |
|
|
|
//using namespace pEp;
|
|
|
|
|
|
|
|
|
|
|
|
namespace pEp { |
|
|
|
|
|
|
|
// type ----------------------------------------
|
|
|
|
// same for pointer and value typee
|
|
|
|
template<class T> |
|
|
|
std::string type_str(const T) |
|
|
|
{ |
|
|
|
std::stringstream ss_type; |
|
|
|
ss_type << typeid(T).name(); |
|
|
|
return ss_type.str(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// addr ----------------------------------------
|
|
|
|
template<class T> |
|
|
|
struct addr_str_helper { |
|
|
|
static std::string str(const T c) |
|
|
|
{ |
|
|
|
std::stringstream ss_addr{}; |
|
|
|
ss_addr << static_cast<const void*>(&c); |
|
|
|
return ss_addr.str(); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
template<class T> |
|
|
|
struct addr_str_helper<T*> { |
|
|
|
static std::string str(const T* c) |
|
|
|
{ |
|
|
|
std::stringstream ss_addr{}; |
|
|
|
ss_addr << static_cast<const void*>(c); |
|
|
|
return ss_addr.str(); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// rertuns the address of c
|
|
|
|
template<class T> |
|
|
|
std::string addr_str(T c) |
|
|
|
{ |
|
|
|
return addr_str_helper<T>::str(c); |
|
|
|
} |
|
|
|
|
|
|
|
// val ----------------------------------------
|
|
|
|
template<class T> |
|
|
|
struct val_str_helper { |
|
|
|
static std::string str(T c, size_t val_len = 30) |
|
|
|
{ |
|
|
|
//value
|
|
|
|
std::stringstream ss_val{}; |
|
|
|
ss_val << c; |
|
|
|
|
|
|
|
return pEp::Utils::clip(ss_val.str(), val_len); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
template<class T> |
|
|
|
struct val_str_helper<T*> { |
|
|
|
static std::string str(T* c, size_t val_len = 30) |
|
|
|
{ |
|
|
|
//value
|
|
|
|
std::stringstream ss_val{}; |
|
|
|
if (c != nullptr) { |
|
|
|
ss_val << &c; |
|
|
|
} else { |
|
|
|
ss_val << "<NULL>"; |
|
|
|
} |
|
|
|
|
|
|
|
return pEp::Utils::clip(ss_val.str(), val_len); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// returns the value of c (if T is pointer type, the address p is pointing to)
|
|
|
|
template<class T> |
|
|
|
std::string val_str(T c, size_t val_len = 30) |
|
|
|
{ |
|
|
|
return val_str_helper<T>::str(c, val_len); |
|
|
|
} |
|
|
|
|
|
|
|
// type_addr_val ----------------------------------------
|
|
|
|
template<class T> |
|
|
|
struct type_addr_val_helper { |
|
|
|
static std::string str(T c, size_t val_len = 30) |
|
|
|
{ |
|
|
|
std::stringstream ret{}; |
|
|
|
ret << "{ " << type_str(c) << " | " << addr_str(c) << " | " << val_str(c, val_len) |
|
|
|
<< " }"; |
|
|
|
return ret.str(); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
template<class T> |
|
|
|
struct type_addr_val_helper<T*> { |
|
|
|
static std::string str(T* c, size_t val_len = 30) |
|
|
|
{ |
|
|
|
std::stringstream ret{}; |
|
|
|
ret << "{ " << type_str(c) << " | " << addr_str(c) << " | " << val_str(c, val_len) |
|
|
|
<< " }"; |
|
|
|
return ret.str(); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
template<class T> |
|
|
|
std::string type_addr_val(T c, size_t val_len = 30) |
|
|
|
{ |
|
|
|
return type_addr_val_helper<T>::str(c, val_len); |
|
|
|
} |
|
|
|
|
|
|
|
} // namespace pEp
|
|
|
|
|
|
|
|
namespace pEp { |
|
|
|
|
|
|
|
char* alloc(const std::string& str) |
|
|
|
char* alloc_str(const std::string& str) |
|
|
|
{ |
|
|
|
char* ret = strdup(str.c_str()); |
|
|
|
pEpLog(type_addr_val(ret)); |
|
|
|
pEpLog(CXX::Inspect::all(ret)); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
template<class T> |
|
|
|
void free(T ptr_type) |
|
|
|
{ |
|
|
|
pEpLog(type_addr_val(ptr_type)); |
|
|
|
pEpLog(CXX::Inspect::all(ptr_type)); |
|
|
|
::pEp_free(ptr_type); |
|
|
|
} |
|
|
|
|
|
|
|
template<> |
|
|
|
void free(char* ptr_type) |
|
|
|
{ |
|
|
|
pEpLog(type_addr_val(ptr_type)); |
|
|
|
pEpLog(CXX::Inspect::all(ptr_type)); |
|
|
|
::pEp_free(ptr_type); |
|
|
|
} |
|
|
|
|
|
|
|
template<> |
|
|
|
void free(::pEp_identity* ptr_type) |
|
|
|
{ |
|
|
|
pEpLog(type_addr_val(ptr_type)); |
|
|
|
pEpLog(CXX::Inspect::all(ptr_type)); |
|
|
|
::pEp_free(ptr_type); |
|
|
|
} |
|
|
|
|
|
|
@ -153,20 +44,9 @@ namespace pEp { |
|
|
|
//---------------------------------------------------------------------------------------------
|
|
|
|
#define EXSTR(msg) std::string(__FUNCTION__) + " - " + msg |
|
|
|
|
|
|
|
class PODBase { |
|
|
|
public: |
|
|
|
static bool log_enabled; |
|
|
|
|
|
|
|
protected: |
|
|
|
bool _is_initialized{ false }; |
|
|
|
|
|
|
|
Adapter::pEpLog::pEpLogger logger{ "pEp::Enum", log_enabled }; |
|
|
|
Adapter::pEpLog::pEpLogger& m4gic_logger_n4me = logger; |
|
|
|
}; |
|
|
|
|
|
|
|
template<class T> |
|
|
|
class POD : public PODBase { |
|
|
|
static_assert(std::is_pod<T>::value, "only POD types are allowed"); |
|
|
|
class POD { |
|
|
|
static_assert(std::is_pod<T>::value && !std::is_pointer<T>::value, "not an integral"); |
|
|
|
|
|
|
|
public: |
|
|
|
POD() = delete; |
|
|
@ -174,10 +54,8 @@ namespace pEp { |
|
|
|
explicit POD(T* pod_p) |
|
|
|
{ |
|
|
|
if (pod_p == nullptr) { |
|
|
|
throw Exception{ EXSTR("cant initialize on a nullptr") }; |
|
|
|
throw Exception{ EXSTR("cant init on a nullptr") }; |
|
|
|
} |
|
|
|
|
|
|
|
// init
|
|
|
|
_pod_p = pod_p; |
|
|
|
pEpLogClass(to_string() + " - taking ownership"); |
|
|
|
} |
|
|
@ -185,8 +63,7 @@ namespace pEp { |
|
|
|
// make a copy
|
|
|
|
POD& operator=(T value) |
|
|
|
{ |
|
|
|
pEpLogClass("Before: " + to_string() + " - new val: '" + val_str(value) + "'"); |
|
|
|
|
|
|
|
pEpLogClass("Before: " + to_string() + " - new val: '" + CXX::Inspect::val(value) + "'"); |
|
|
|
*_pod_p = value; |
|
|
|
pEpLogClass("After: " + to_string()); |
|
|
|
return *this; |
|
|
@ -212,21 +89,26 @@ namespace pEp { |
|
|
|
|
|
|
|
std::string to_string() const |
|
|
|
{ |
|
|
|
std::string ret{ "[" + type_addr_val(_pod_p) + "]" }; |
|
|
|
std::string ret{ "[" + CXX::Inspect::all(_pod_p) + "]" }; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
static bool log_enabled; |
|
|
|
|
|
|
|
private: |
|
|
|
bool _is_initialized{ false }; |
|
|
|
T* _pod_p{ nullptr }; |
|
|
|
|
|
|
|
Adapter::pEpLog::pEpLogger logger{ "pEp::POD", log_enabled }; |
|
|
|
Adapter::pEpLog::pEpLogger& m4gic_logger_n4me = logger; |
|
|
|
|
|
|
|
class Exception : public std::runtime_error { |
|
|
|
public: |
|
|
|
explicit Exception(const std::string& msg) : std::runtime_error(msg) {} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
bool pEp::PODBase::log_enabled{ true }; |
|
|
|
template<class T> |
|
|
|
bool pEp::POD<T>::log_enabled{ true }; |
|
|
|
|
|
|
|
template<class T> |
|
|
|
std::ostream& operator<<(std::ostream& o, pEp::POD<T> pEpEnum) |
|
|
@ -245,28 +127,43 @@ namespace pEp { |
|
|
|
// * dont take ownership, only provide a C++ interface
|
|
|
|
// There must be the option to construct the object before the wrapped c_str (char*)
|
|
|
|
// is known. This leads to a pEp::String object in invalid state, and it must be initialized using
|
|
|
|
// set(). Otherwise all(most) functions will throw.
|
|
|
|
// set() can only be called once, will throw otherwise.
|
|
|
|
// init(). Otherwise all(most) functions will throw.
|
|
|
|
// init() can only be called once, will throw otherwise.
|
|
|
|
// NON-owning mode, just does not free the string when it dies, owning mode does.
|
|
|
|
// Thats the only difference.
|
|
|
|
class String { |
|
|
|
public: |
|
|
|
String() = default; |
|
|
|
|
|
|
|
// Best to use this constructor, as the object is in a valid state when the wrapped
|
|
|
|
// c_str (char*) is known
|
|
|
|
explicit String(char** c_str_pp) |
|
|
|
String(bool take_ownership, char** c_str_pp) |
|
|
|
{ |
|
|
|
initialize(c_str_pp); |
|
|
|
init(take_ownership, c_str_pp); |
|
|
|
} |
|
|
|
|
|
|
|
explicit String(bool take_ownership, char** c_str_pp, const std::string& init_val) |
|
|
|
{ |
|
|
|
init(take_ownership, c_str_pp, init_val); |
|
|
|
} |
|
|
|
|
|
|
|
~String() |
|
|
|
{ |
|
|
|
_free(); |
|
|
|
if (_is_owning_mode) { |
|
|
|
_free(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void init(bool take_ownership, char** c_str_pp, const std::string& init_val) |
|
|
|
{ |
|
|
|
init(take_ownership, c_str_pp); |
|
|
|
this->operator=(init_val); |
|
|
|
} |
|
|
|
|
|
|
|
void initialize(char** c_str_pp) |
|
|
|
void init(bool take_ownership, char** c_str_pp) |
|
|
|
{ |
|
|
|
if (c_str_pp == nullptr) { |
|
|
|
throw Exception{ EXSTR("cant initialize on a nullptr") }; |
|
|
|
throw Exception{ EXSTR("cant init on a nullptr") }; |
|
|
|
} |
|
|
|
|
|
|
|
if (_is_initialized) { |
|
|
@ -277,7 +174,8 @@ namespace pEp { |
|
|
|
_c_str_pp = c_str_pp; |
|
|
|
_c_str_p = *_c_str_pp; |
|
|
|
_is_initialized = true; |
|
|
|
pEpLogClass(to_string() + " - taking ownership"); |
|
|
|
_is_owning_mode = take_ownership; |
|
|
|
pEpLogClass(to_string() + " - init " + (take_ownership ? "/taking ownership" : "")); |
|
|
|
} |
|
|
|
|
|
|
|
// make a copy
|
|
|
@ -297,7 +195,7 @@ namespace pEp { |
|
|
|
*_c_str_pp = nullptr; |
|
|
|
_c_str_p = *_c_str_pp; |
|
|
|
} else { |
|
|
|
*_c_str_pp = pEp::alloc(str); |
|
|
|
*_c_str_pp = pEp::alloc_str(str); |
|
|
|
_c_str_p = *_c_str_pp; |
|
|
|
} |
|
|
|
pEpLogClass("After: " + to_string()); |
|
|
@ -336,14 +234,15 @@ namespace pEp { |
|
|
|
throw Exception{ EXSTR("invalid state") }; |
|
|
|
} |
|
|
|
|
|
|
|
std::string ret{ "[" + type_addr_val(_c_str_pp) + " / " + type_addr_val(*_c_str_pp) + |
|
|
|
"]" }; |
|
|
|
std::string ret{ "[" + CXX::Inspect::all(_c_str_pp) + " / " + |
|
|
|
CXX::Inspect::all(*_c_str_pp) + "]" }; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
static bool log_enabled; |
|
|
|
|
|
|
|
private: |
|
|
|
// TODO: this is dodgy, do we really need _c_str_pp AND _c_str_p???
|
|
|
|
void _free() |
|
|
|
{ |
|
|
|
// if the c_str points to a different address now, than the one we created
|
|
|
@ -352,8 +251,7 @@ namespace pEp { |
|
|
|
pEpLog("raw access string change detected"); |
|
|
|
pEp::free(*_c_str_pp); |
|
|
|
} else { |
|
|
|
// we anyways need to free the one we created
|
|
|
|
// NO: WE ASSUME THAT:
|
|
|
|
// WE ASSUME THAT:
|
|
|
|
// if the char* has been replaced, it has been freed, as well
|
|
|
|
if (_c_str_p != nullptr) { |
|
|
|
pEp::free(_c_str_p); |
|
|
@ -362,6 +260,7 @@ namespace pEp { |
|
|
|
} |
|
|
|
|
|
|
|
bool _is_initialized{ false }; |
|
|
|
bool _is_owning_mode{ false }; |
|
|
|
char** _c_str_pp{ nullptr }; |
|
|
|
char* _c_str_p{ nullptr }; |
|
|
|
|
|
|
@ -397,16 +296,10 @@ namespace pEp { |
|
|
|
_wrappee = ::new_identity(nullptr, nullptr, nullptr, nullptr); |
|
|
|
|
|
|
|
// set the pEp::String wrapper underlying c_str
|
|
|
|
this->address.initialize(&_wrappee->address); |
|
|
|
this->username.initialize(&_wrappee->username); |
|
|
|
this->user_id.initialize(&_wrappee->user_id); |
|
|
|
this->fpr.initialize(&_wrappee->fpr); |
|
|
|
|
|
|
|
// set the values
|
|
|
|
this->address = address; |
|
|
|
this->username = username; |
|
|
|
this->user_id = user_id; |
|
|
|
this->fpr = fpr; |
|
|
|
this->address.init(true, &_wrappee->address, address); |
|
|
|
this->username.init(true, &_wrappee->username, username); |
|
|
|
this->user_id.init(true, &_wrappee->user_id, user_id); |
|
|
|
this->fpr.init(true, &_wrappee->fpr, fpr); |
|
|
|
} |
|
|
|
|
|
|
|
~Identity() |
|
|
@ -445,25 +338,28 @@ namespace pEp { |
|
|
|
|
|
|
|
::PEP_SESSION session; |
|
|
|
|
|
|
|
void test_getters(char const* const* const c_str_p, pEp::String& pstr) |
|
|
|
void test_getters(char** c_str_p, pEp::String& pstr, const std::string& expected) |
|
|
|
{ |
|
|
|
pEpLog("to_string(): " + pstr.to_string()); |
|
|
|
// compare addresses
|
|
|
|
pEpLog("addresses == c_str_p"); |
|
|
|
assert(pstr.c_data() == *c_str_p); |
|
|
|
assert(pstr.data() == c_str_p); |
|
|
|
|
|
|
|
// compare values
|
|
|
|
if (*c_str_p != nullptr) { |
|
|
|
std::string tmp{ pstr }; |
|
|
|
pEpLog("operator std::string(): " + tmp); |
|
|
|
assert(tmp == std::string(*c_str_p)); |
|
|
|
pEpLog("operator std::string(): " + std::string(pstr)); |
|
|
|
assert(std::string(pstr) == std::string(*c_str_p)); |
|
|
|
assert(std::string(pstr) == expected); |
|
|
|
|
|
|
|
// will segfault with nullptr, and this is correct
|
|
|
|
std::string tmp2{ *pstr.data() }; |
|
|
|
pEpLog("data(): " + tmp2); |
|
|
|
assert(tmp2 == std::string(*c_str_p)); |
|
|
|
pEpLog("data(): " + std::string(*pstr.data())); |
|
|
|
assert(std::string(*pstr.data()) == std::string(*c_str_p)); |
|
|
|
assert(std::string(*pstr.data()) == expected); |
|
|
|
|
|
|
|
std::string tmp3{ pstr.c_data() }; |
|
|
|
pEpLog("c_data(): " + tmp2); |
|
|
|
assert(tmp3 == std::string(*c_str_p)); |
|
|
|
pEpLog("c_data(): " + std::string(pstr.c_data())); |
|
|
|
assert(std::string(pstr.c_data()) == std::string(*c_str_p)); |
|
|
|
assert(std::string(pstr.c_data()) == expected); |
|
|
|
} else { |
|
|
|
std::string tmp{ pstr }; |
|
|
|
pEpLog("operator std::string(): " + tmp); |
|
|
@ -471,62 +367,124 @@ void test_getters(char const* const* const c_str_p, pEp::String& pstr) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void test_assign_and_getters(char** c_str_p, pEp::String& pstr) |
|
|
|
void test_assign(char** c_str_p, pEp::String& pstr) |
|
|
|
{ |
|
|
|
test_getters(c_str_p, pstr); |
|
|
|
pEpLogH2("assign operator"); |
|
|
|
pstr = "assign operator"; |
|
|
|
test_getters(c_str_p, pstr); |
|
|
|
|
|
|
|
pEpLogH2("raw c_str assign"); |
|
|
|
*c_str_p = strdup("raw c_str assign"); |
|
|
|
test_getters(c_str_p, pstr); |
|
|
|
{ |
|
|
|
pEpLogH2("assign operator"); |
|
|
|
std::string new_val{ "assign operator" }; |
|
|
|
pstr = new_val; |
|
|
|
test_getters(c_str_p, pstr, new_val); |
|
|
|
} |
|
|
|
{ |
|
|
|
pEpLogH2("raw c_str assign"); |
|
|
|
std::string new_val{ "raw c_str assign" }; |
|
|
|
free(*c_str_p); |
|
|
|
*c_str_p = strdup(new_val.c_str()); |
|
|
|
test_getters(c_str_p, pstr, new_val); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void test_getters(int* c_int_p, pEp::POD<int>& pint, int expected) |
|
|
|
{ |
|
|
|
pEpLog("to_string(): " + pint.to_string()); |
|
|
|
// compare addresses
|
|
|
|
pEpLog("addresses == c_int_p"); |
|
|
|
assert(pint.c_data() == c_int_p); |
|
|
|
assert(pint.data() == c_int_p); |
|
|
|
|
|
|
|
// compare values
|
|
|
|
if (c_int_p != nullptr) { |
|
|
|
pEpLog("operator int(): " + std::to_string(pint)); |
|
|
|
assert(pint == *c_int_p); |
|
|
|
assert(pint == expected); |
|
|
|
|
|
|
|
// will segfault with nullptr, and this is correct
|
|
|
|
pEpLog("data(): " + std::to_string(*pint.data())); |
|
|
|
assert(*pint.data() == *c_int_p); |
|
|
|
assert(*pint.data() == expected); |
|
|
|
|
|
|
|
pEpLog("c_data(): " + std::to_string(*pint.c_data())); |
|
|
|
assert(*pint.c_data() == *c_int_p); |
|
|
|
assert(*pint.c_data() == expected); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void test_assign(int* c_int_p, pEp::POD<int>& pint) |
|
|
|
{ |
|
|
|
{ |
|
|
|
pEpLogH2("assign operator"); |
|
|
|
int new_val = 23; |
|
|
|
pint = new_val; |
|
|
|
test_getters(c_int_p, pint, new_val); |
|
|
|
} |
|
|
|
{ |
|
|
|
pEpLogH2("raw c_str assign"); |
|
|
|
int new_val = 23; |
|
|
|
*c_int_p = new_val; |
|
|
|
test_getters(c_int_p, pint, new_val); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// We are testing wrappers for the c-datatypes:
|
|
|
|
// * integral e.g (int) here
|
|
|
|
// * enum
|
|
|
|
// * c-string
|
|
|
|
// * struct
|
|
|
|
// Those are all considered POD-types
|
|
|
|
extern "C" { |
|
|
|
typedef enum |
|
|
|
{ |
|
|
|
SOBER, |
|
|
|
WHIPPY, |
|
|
|
YIPPIE, |
|
|
|
HOORAY |
|
|
|
} Drunk_level; |
|
|
|
ONE, |
|
|
|
TWO, |
|
|
|
THREE |
|
|
|
} Test_enum; |
|
|
|
|
|
|
|
typedef struct { |
|
|
|
char* name; |
|
|
|
Drunk_level drk; |
|
|
|
int btc_fanlevel; |
|
|
|
} SchlossInsasse; |
|
|
|
int c_int; |
|
|
|
Test_enum c_enum; |
|
|
|
char* c_str; |
|
|
|
} Test_struct; |
|
|
|
} |
|
|
|
|
|
|
|
int main() |
|
|
|
{ |
|
|
|
// c-types are always POD
|
|
|
|
// we need to handle pointer types and value types differently
|
|
|
|
// pointer types need to be memory-managed (heap)
|
|
|
|
// value types are being copied around (stack)
|
|
|
|
static_assert(std::is_pod<int>::value && !std::is_pointer<int>::value, "not an integral"); |
|
|
|
static_assert( |
|
|
|
std::is_pod<Test_enum>::value && !std::is_pointer<Test_enum>::value, |
|
|
|
"not an integral"); |
|
|
|
static_assert( |
|
|
|
std::is_pod<Test_struct>::value && !std::is_pointer<Test_struct>::value, |
|
|
|
"not an integral"); |
|
|
|
|
|
|
|
// static_assert(std::is_pod<char*>::value && !std::is_pointer<char*>::value, "not an integral");
|
|
|
|
|
|
|
|
// pEp::Utils::readKey();
|
|
|
|
pEp::Adapter::pEpLog::set_enabled(true); |
|
|
|
|
|
|
|
// POD
|
|
|
|
if (1) { |
|
|
|
// VALID USAGE
|
|
|
|
int init_val = 0; |
|
|
|
// new pEp::POD on int
|
|
|
|
{ |
|
|
|
pEpLogH1("new pEp::POD on int"); |
|
|
|
int c_int = init_val; |
|
|
|
pEp::POD<int> pint(&c_int); |
|
|
|
test_getters(&c_int, pint, init_val); |
|
|
|
test_assign(&c_int, pint); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
SchlossInsasse tschappy; |
|
|
|
tschappy.name = strdup("tschappy"); |
|
|
|
tschappy.drk = YIPPIE; |
|
|
|
tschappy.btc_fanlevel = 100; |
|
|
|
|
|
|
|
pEp::POD<::Drunk_level> penum(&tschappy.drk); |
|
|
|
pEpLog(tschappy.drk); |
|
|
|
pEpLog(penum); |
|
|
|
penum = HOORAY; |
|
|
|
pEpLog(tschappy.drk); |
|
|
|
pEpLog(penum); |
|
|
|
|
|
|
|
pEp::POD<int> pint(&tschappy.btc_fanlevel); |
|
|
|
pEpLog(tschappy.btc_fanlevel); |
|
|
|
pEpLog(pint); |
|
|
|
pint = 33; |
|
|
|
pEpLog(tschappy.btc_fanlevel); |
|
|
|
pEpLog(pint); |
|
|
|
|
|
|
|
|
|
|
|
// String
|
|
|
|
// pEp::String::log_enabled = false;
|
|
|
|
if (0) { |
|
|
|
//TODO: Test non-owning mode
|
|
|
|
|
|
|
|
// INVALID USAGE
|
|
|
|
// char* c_str_u; // uninitialized == INVALID
|
|
|
|
// undefined behaviour, most likely "pointer being freed was not allocated"
|
|
|
@ -547,29 +505,32 @@ int main() |
|
|
|
pEpLogH1("new pEp::String on char* pointing to NULL"); |
|
|
|
char* c_str = NULL; // nullptr
|
|
|
|
|
|
|
|
pEp::String pstr(&c_str); |
|
|
|
test_assign_and_getters(&c_str, pstr); |
|
|
|
pEp::String pstr(true, &c_str); |
|
|
|
test_getters(&c_str, pstr, ""); |
|
|
|
test_assign(&c_str, pstr); |
|
|
|
} |
|
|
|
|
|
|
|
std::string init_val{ "initialized c string" }; |
|
|
|
// new pEp::String on already initalized char*
|
|
|
|
{ |
|
|
|
pEpLogH1("new pEp::String on already initalized char*"); |
|
|
|
char* c_str = strdup("initialized c string"); |
|
|
|
char* c_str = strdup(init_val.c_str()); |
|
|
|
|
|
|
|
pEp::String pstr(&c_str); |
|
|
|
test_assign_and_getters(&c_str, pstr); |
|
|
|
pEp::String pstr(true, &c_str); |
|
|
|
test_getters(&c_str, pstr, init_val); |
|
|
|
test_assign(&c_str, pstr); |
|
|
|
} |
|
|
|
|
|
|
|
// initialize()
|
|
|
|
{ |
|
|
|
pEpLogH1("initialize()"); |
|
|
|
pEpLogH1("init()"); |
|
|
|
pEp::String pstr{}; |
|
|
|
|
|
|
|
char* c_str = strdup("initialized c string"); |
|
|
|
char* c_str = strdup(init_val.c_str()); |
|
|
|
//TODO: PITYASSERT_THROWS
|
|
|
|
pstr.initialize(&c_str); |
|
|
|
|
|
|
|
test_assign_and_getters(&c_str, pstr); |
|
|
|
pstr.init(true, &c_str); |
|
|
|
test_getters(&c_str, pstr, init_val); |
|
|
|
test_assign(&c_str, pstr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -580,16 +541,17 @@ int main() |
|
|
|
// create identity
|
|
|
|
pEp::Identity id1{ "wrong@entry.lol", "wrong", "23", "INVA_FPR" }; |
|
|
|
|
|
|
|
pEpLog(*id1); |
|
|
|
pEpLog(id1); |
|
|
|
id1.username = "alice"; |
|
|
|
id1.address = "alice@peptest.org"; |
|
|
|
|
|
|
|
pEpLog(id1.address); |
|
|
|
pEpLog(id1.username); |
|
|
|
::myself(session, id1); |
|
|
|
pEpLog(*id1); |
|
|
|
pEpLog(id1); |
|
|
|
|
|
|
|
pEp::Identity id2{ "bob" }; |
|
|
|
::update_identity(session, id2); |
|
|
|
pEpLog(*id2); |
|
|
|
pEpLog(id2); |
|
|
|
} |
|
|
|
} |
|
|
|