diff --git a/server/function_map.cc b/server/function_map.cc index b7be9ba..cf5f602 100644 --- a/server/function_map.cc +++ b/server/function_map.cc @@ -1,9 +1,13 @@ #include "function_map.hh" +#include "c_string.hh" template<> js::Value Type2String::get() { return "String"; } +template<> +js::Value Type2String::get() { return "String"; } + template<> js::Value Type2String::get() { return "String"; } diff --git a/server/function_map.hh b/server/function_map.hh index 0086027..e2dc6ea 100644 --- a/server/function_map.hh +++ b/server/function_map.hh @@ -1,14 +1,183 @@ #ifndef FUNCTION_MAP_HH #define FUNCTION_MAP_HH +#include "json_spirit/json_spirit_value.h" +#include "json_spirit/json_spirit_writer.h" -#include "inout.hh" -#include "c_string.hh" +#include "context.hh" #include -#include "json_spirit/json_spirit_writer.h" // Just for debugging: #include +#include + + +namespace js = json_spirit; + +template struct In; +template struct Out; + +// "params" and "position" might be used to fetch additional parameters from the array. +template +T from_json(const js::Value& v); + + +template +js::Value to_json(const T& t); + + +// helper classes to specify in- and out-parameters +template +struct In +{ + typedef T c_type; // the according type in C function parameter + enum { is_output = false, need_input = NeedInput }; + + explicit In(const T& t) : value(t) {} + ~In(); + + In(const In& other) = delete; + In(In&& victim) = delete; + In& operator=(const In&) = delete; + + // default implementation: + In(const js::Value& v, Context*) + : In( from_json(v) ) + { } + + js::Value to_json() const + { + return ::to_json(value); + } + + c_type get_value() const { return value; } + + T value; +}; + + +// to call functions that operate directly on the JSON data type +template +struct InRaw +{ + typedef js::Value c_type; // do not unwrap JSON data type + enum { is_output = false, need_input = NeedInput }; + + explicit InRaw(const js::Value& t) : value(t) {} + ~InRaw() = default; + + InRaw(const InRaw& other) = delete; + InRaw(InRaw&& victim) = delete; + InRaw& operator=(const InRaw&) = delete; + + // default implementation: + InRaw(const js::Value& v, Context*) + : InRaw(v) + { } + + js::Value to_json() const + { + throw std::logic_error( std::string(typeid(T).name()) + " is not for output!" ); + } + + c_type get_value() const { return value; } + + js::Value value; +}; + + +// helper classes to specify in- and out-parameters +template +struct InOut : public In +{ + typedef In Base; + enum { is_output = true, need_input = NeedInput }; + + explicit InOut(const T& t) : Base(t) {} + ~InOut() = default; + + InOut& operator=(const InOut&) = delete; + + // default implementation: + InOut(const js::Value& v, Context*) + : Base( from_json(v) ) + { } + + js::Value to_json() const + { + return ::to_json(Base::value); + } +}; + + +template +struct Out +{ + typedef T* c_type; // the according type in C function parameter + enum { is_output = true, need_input = NeedInput }; // if need_input=false it would no longer consume an element in the input parameter array. + + Out() : value{ new T{} } + { + if(typeid(T)==typeid(_message*)) + { + std::cerr << "|$ Out(): this=" << *this << "\n"; + } + } + + ~Out(); + + Out(const Out& other) = delete; + Out(Out&& victim) = delete; + + // just to be sure they are not implicitly defined: + Out& operator=(const Out& other) = delete; + Out& operator=(Out&& victim) = delete; + + Out(const js::Value& v, Context*) + : Out() + { } + + js::Value to_json() const + { + return ::to_json(*value); + } + + c_type get_value() const { return value; } + + T* value = nullptr; + + friend + std::ostream& operator<<(std::ostream& o, const Out& out) + { + o << (const void*)&out; + +// the if() was added to avoid crashes on memory corruptuon. But clang++ warns, that this check is always true on "well-formed" programs, and he is right. In an ideal world there are no memory corruptions. ;-( +// if(&out) + { + o << ", value=" << (const void*)out.value; + if(out.value) + { + o << ", *value=" << *(out.value); + } + } + + return o; + } + +}; + + +template +js::Value to_json(const Out& o) +{ + return ::to_json(*o.value); +} + +template +js::Value to_json(const InOut& o) +{ + return ::to_json(o.value); +} // heloer class for generic calls: diff --git a/server/inout.cc b/server/inout.cc index 3195ed6..ecb4643 100644 --- a/server/inout.cc +++ b/server/inout.cc @@ -1,25 +1,6 @@ #include "inout.hh" #include - -#include // for memcpy() - - -namespace -{ - char* make_c_string(const std::string& src) - { - char* dest = (char*)malloc(src.size() + 1); - memcpy(dest, src.c_str(), src.size() + 1 ); - return dest; - } -} - - -template<> -In::~In() -{ - if(value) free(const_cast(value)); -} +#include #define SIMPLE_TYPE(TYPE) \ @@ -53,7 +34,7 @@ Out::~Out() { if(value) { - free(const_cast(*value)); + pEp_free(const_cast(*value)); } delete value; } @@ -64,7 +45,7 @@ Out::~Out() { if(value) { - free(*value); + pEp_free(*value); *value = nullptr; } delete value; @@ -138,18 +119,6 @@ std::string from_json(const js::Value& v) } -template<> -char* from_json(const js::Value& v) -{ - return make_c_string( v.get_str() ); -} - -template<> -const char* from_json(const js::Value& v) -{ - return make_c_string( v.get_str() ); -} - template js::Value to_json(const T& t) diff --git a/server/json-adapter.cc b/server/json-adapter.cc index 496258a..1fb392e 100644 --- a/server/json-adapter.cc +++ b/server/json-adapter.cc @@ -205,17 +205,17 @@ PEP_STATUS MIME_decrypt_message_ex( const FunctionMap functions = { // from message_api.h FP( "Message API", new Separator ), - FP( "MIME_encrypt_message", new Func, In, In, In, + FP( "MIME_encrypt_message", new Func, In, In, In, Out, In, In>( &MIME_encrypt_message ) ), - FP( "MIME_encrypt_message_for_self", new Func, In, In, In, + FP( "MIME_encrypt_message_for_self", new Func, In, In, In, Out, In, In>( &MIME_encrypt_message_for_self ) ), - FP( "MIME_decrypt_message", new Func, In, In, + FP( "MIME_decrypt_message", new Func, In, In, Out, Out, Out, Out>( &MIME_decrypt_message ) ), // HACK: because "auto sessions" are per TCP connections, add a parameter to set passive_mode each time again - FP( "MIME_encrypt_message_ex", new Func, In, In, In, In, + FP( "MIME_encrypt_message_ex", new Func, In, In, In, In, Out, In, In>( &MIME_encrypt_message_ex ) ), - FP( "MIME_decrypt_message_ex", new Func, In, In, In, + FP( "MIME_decrypt_message_ex", new Func, In, In, In, Out, Out, Out, Out>( &MIME_decrypt_message_ex ) ), FP( "startKeySync", new Func>( &JsonAdapter::startSync) ), @@ -232,7 +232,7 @@ const FunctionMap functions = { FP( "get_gpg_path", new Func>(&get_gpg_path) ), FP( "pEp Engine Core API", new Separator), - FP( "log_event", new Func, In, In, In, In>( &log_event) ), + FP( "log_event", new Func, In, In, In, In>( &log_event) ), FP( "get_trustwords", new Func, In, In, In, Out, Out, In>( &get_trustwords) ), FP( "get_languagelist", new Func, Out>( &get_languagelist) ), FP( "get_phrase" , new Func, In, In, Out> ( &get_phrase) ), @@ -241,9 +241,9 @@ const FunctionMap functions = { FP( "config_unencrypted_subject", new Func, In>( &config_unencrypted_subject) ), FP( "Identity Management API", new Separator), - FP( "get_identity" , new Func, In, In, Out>( &get_identity) ), + FP( "get_identity" , new Func, In, In, Out>( &get_identity) ), FP( "set_identity" , new Func, In> ( &set_identity) ), - FP( "mark_as_comprimized", new Func, In> ( &mark_as_compromized) ), + FP( "mark_as_comprimized", new Func, In> ( &mark_as_compromized) ), FP( "identity_rating" , new Func, In, Out>( &identity_rating) ), FP( "outgoing_message_rating", new Func, In, Out>( &outgoing_message_rating) ), FP( "set_identity_flags" , new Func, InOut, In>( &set_identity_flags) ), @@ -251,12 +251,12 @@ const FunctionMap functions = { FP( "Low level Key Management API", new Separator), FP( "generate_keypair", new Func, InOut> ( &generate_keypair) ), - FP( "delete_keypair", new Func, In> ( &delete_keypair) ), - FP( "import_key" , new Func, In, In, Out> ( &import_key) ), - FP( "export_key" , new Func, In, Out, Out> ( &export_key) ), - FP( "find_keys" , new Func, In, Out> ( &find_keys) ), + FP( "delete_keypair", new Func, In> ( &delete_keypair) ), + FP( "import_key" , new Func, In, In, Out> ( &import_key) ), + FP( "export_key" , new Func, In, Out, Out> ( &export_key) ), + FP( "find_keys" , new Func, In, Out> ( &find_keys) ), FP( "get_trust" , new Func, InOut> ( &get_trust) ), - FP( "own_key_is_listed", new Func, In, Out> ( &own_key_is_listed) ), + FP( "own_key_is_listed", new Func, In, Out> ( &own_key_is_listed) ), FP( "own_identities_retrieve", new Func, Out>( &own_identities_retrieve ) ), FP( "undo_last_mitrust", new Func>( &undo_last_mistrust ) ), @@ -267,18 +267,18 @@ const FunctionMap functions = { FP( "key_mistrusted", new Func, In>( &key_mistrusted) ), FP( "key_reset_trust", new Func, In>( &key_reset_trust) ), - FP( "least_trust" , new Func, In, Out> ( &least_trust) ), - FP( "get_key_rating", new Func, In, Out> ( &get_key_rating) ), - FP( "renew_key" , new Func, In, In> ( &renew_key) ), - FP( "revoke" , new Func, In, In> ( &revoke_key) ), - FP( "key_expired" , new Func, In, In, Out> ( &key_expired) ), + FP( "least_trust" , new Func, In, Out> ( &least_trust) ), + FP( "get_key_rating", new Func, In, Out> ( &get_key_rating) ), + FP( "renew_key" , new Func, In, In> ( &renew_key) ), + FP( "revoke" , new Func, In, In> ( &revoke_key) ), + FP( "key_expired" , new Func, In, In, Out> ( &key_expired) ), FP( "from blacklist.h & OpenPGP_compat.h", new Separator), - FP( "blacklist_add" , new Func, In> ( &blacklist_add) ), - FP( "blacklist_delete", new Func, In> ( &blacklist_delete) ), - FP( "blacklist_is_listed", new Func, In, Out> ( &blacklist_is_listed) ), + FP( "blacklist_add" , new Func, In> ( &blacklist_add) ), + FP( "blacklist_delete", new Func, In> ( &blacklist_delete) ), + FP( "blacklist_is_listed", new Func, In, Out> ( &blacklist_is_listed) ), FP( "blacklist_retrieve" , new Func, Out> ( &blacklist_retrieve) ), - FP( "OpenPGP_list_keyinfo", new Func, In, Out> ( &OpenPGP_list_keyinfo) ), + FP( "OpenPGP_list_keyinfo", new Func, In, Out> ( &OpenPGP_list_keyinfo) ), FP( "Event Listener & Results", new Separator ), FP( "registerEventListener" , new Func, In, In, In> ( ®isterEventListener) ),