2019-10-24 06:36:42 -07:00
|
|
|
/*
|
|
|
|
* Copyright 2019 by its authors. See AUTHORS.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
eldbus-cxx: Implementation of eldbus C++ API
Summary:
Applications can:
void method_callback(void* data, const Eldbus_Service_Interface* iface,
const Eldbus_Message* message);
struct { ... } data_struct;
Eldbus_Method methods[] =
{
"method1", ELDBUS_ARGS("b", "bool"), ELDBUS_ARGS("b", "bool"), ELDBUS_METHOD_FLAG_HAS_DATA
, (Eldbus_Method_Cb)&method_callback, &data_struct
};
And method_callback will be called with data parameter pointing to data_struct global object.
Also, Eldbus-cxx supports registering an interface passing a lambda or
function object as method. For example:
edb::service_interface iface = edb::service_interface_register
(c, path, interface
, es::method("SendStringAndBool"
, [expected_string, expected_bool] (std::string const& n, bool b
, bool* out)
{
std::cout << "Running SendStringAndBool" << std::endl;
ck_assert(n == expected_string);
ck_assert(b == expected_bool);
*out = b;
return n;
}
, es::ins<std::string, bool>("string", "bool")
, es::outs<std::string, bool>("string", "bool")
)
);
When a request for "SendStringAndBool" with the proper signature is
called, executes the lambda and replies with the return value and
its bool* out parameter value.
Reviewers: cedric, woohyun, raster
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D1052
2014-07-03 00:28:22 -07:00
|
|
|
#ifndef ELDBUS_CXX_ELDBUS_MESSAGE_HH
|
|
|
|
#define ELDBUS_CXX_ELDBUS_MESSAGE_HH
|
|
|
|
|
|
|
|
#include <Eldbus.h>
|
|
|
|
#include <eldbus_signature_traits.hh>
|
|
|
|
|
|
|
|
namespace efl { namespace eldbus {
|
|
|
|
|
|
|
|
struct message_value
|
|
|
|
{
|
|
|
|
message_value() : _iterator(0) {}
|
|
|
|
message_value( ::Eldbus_Message_Iter* iterator) : _iterator(iterator) {}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T get() const
|
|
|
|
{
|
|
|
|
assert(!!_iterator);
|
|
|
|
std::cout << "trying to read " << _detail::signature_traits<T>::sig
|
|
|
|
<< " has " << eldbus_message_iter_signature_get(_iterator) << std::endl;
|
|
|
|
T object;
|
|
|
|
char* c = eldbus_message_iter_signature_get(_iterator);
|
|
|
|
if(c[0] != _detail::signature_traits<T>::sig)
|
|
|
|
throw std::runtime_error("");
|
|
|
|
eldbus_message_iter_arguments_get(_iterator, c, &object);
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
friend inline bool operator==(message_value const& lhs, message_value const& rhs)
|
|
|
|
{
|
|
|
|
return
|
|
|
|
lhs._iterator == rhs._iterator
|
|
|
|
|| (!lhs._iterator && rhs._iterator && std::strlen(eldbus_message_iter_signature_get(rhs._iterator)) == 0)
|
|
|
|
|| (!rhs._iterator && lhs._iterator && std::strlen(eldbus_message_iter_signature_get(lhs._iterator)) == 0)
|
|
|
|
;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
friend struct message_iterator;
|
|
|
|
::Eldbus_Message_Iter* _iterator;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator!=(message_value const& lhs, message_value const& rhs)
|
|
|
|
{
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct message_iterator
|
|
|
|
{
|
|
|
|
typedef message_value value_type;
|
|
|
|
typedef value_type& reference;
|
|
|
|
typedef value_type const& const_reference;
|
|
|
|
typedef value_type* pointer;
|
|
|
|
typedef value_type const* const_pointer;
|
|
|
|
typedef std::ptrdiff_t difference_type;
|
|
|
|
typedef std::size_t size_type;
|
|
|
|
typedef std::input_iterator_tag iterator_category;
|
|
|
|
|
|
|
|
message_iterator()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
message_iterator(Eldbus_Message_Iter* iterator)
|
|
|
|
: value(iterator)
|
|
|
|
{}
|
|
|
|
|
|
|
|
reference operator*() const
|
|
|
|
{
|
|
|
|
return const_cast<reference>(value);
|
|
|
|
}
|
|
|
|
pointer operator->() const
|
|
|
|
{
|
|
|
|
return const_cast<pointer>(&value);
|
|
|
|
}
|
|
|
|
message_iterator& operator++()
|
|
|
|
{
|
|
|
|
if(!eldbus_message_iter_next(value._iterator))
|
|
|
|
{
|
|
|
|
value._iterator = 0;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
2015-12-29 05:37:27 -08:00
|
|
|
message_iterator operator++(int)
|
eldbus-cxx: Implementation of eldbus C++ API
Summary:
Applications can:
void method_callback(void* data, const Eldbus_Service_Interface* iface,
const Eldbus_Message* message);
struct { ... } data_struct;
Eldbus_Method methods[] =
{
"method1", ELDBUS_ARGS("b", "bool"), ELDBUS_ARGS("b", "bool"), ELDBUS_METHOD_FLAG_HAS_DATA
, (Eldbus_Method_Cb)&method_callback, &data_struct
};
And method_callback will be called with data parameter pointing to data_struct global object.
Also, Eldbus-cxx supports registering an interface passing a lambda or
function object as method. For example:
edb::service_interface iface = edb::service_interface_register
(c, path, interface
, es::method("SendStringAndBool"
, [expected_string, expected_bool] (std::string const& n, bool b
, bool* out)
{
std::cout << "Running SendStringAndBool" << std::endl;
ck_assert(n == expected_string);
ck_assert(b == expected_bool);
*out = b;
return n;
}
, es::ins<std::string, bool>("string", "bool")
, es::outs<std::string, bool>("string", "bool")
)
);
When a request for "SendStringAndBool" with the proper signature is
called, executes the lambda and replies with the return value and
its bool* out parameter value.
Reviewers: cedric, woohyun, raster
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D1052
2014-07-03 00:28:22 -07:00
|
|
|
{
|
|
|
|
message_iterator tmp(*this);
|
|
|
|
++*this;
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
friend inline bool operator==(message_iterator const& lhs, message_iterator const& rhs)
|
|
|
|
{
|
|
|
|
return lhs.value == rhs.value;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
message_value value;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator!=(message_iterator const& lhs, message_iterator const& rhs)
|
|
|
|
{
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct reply_t {};
|
|
|
|
struct error_t {};
|
|
|
|
struct method_call_t {};
|
|
|
|
|
|
|
|
reply_t const reply = {};
|
|
|
|
error_t const error = {};
|
|
|
|
method_call_t const method_call = {};
|
|
|
|
|
|
|
|
struct const_message
|
|
|
|
{
|
|
|
|
explicit const_message(Eldbus_Message const* message) : _message(message)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
const_message(const_message const& other, reply_t)
|
|
|
|
: _message( ::eldbus_message_method_return_new(other.native_handle()))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
const_message(const_message const& other, const char* error_name, const char* error_msg, error_t)
|
|
|
|
: _message( ::eldbus_message_error_new(other.native_handle(), error_name, error_msg))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
const_message(const char* destination, const char* path, const char* iface
|
|
|
|
, const char* method, method_call_t)
|
|
|
|
: _message( ::eldbus_message_method_call_new(destination, path, iface, method))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
const_message(const_message const& other)
|
|
|
|
: _message( ::eldbus_message_ref(const_cast<Eldbus_Message*>(other.native_handle())))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
~const_message()
|
|
|
|
{
|
|
|
|
eldbus_message_unref(const_cast<Eldbus_Message*>(native_handle()));
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* path_get() const
|
|
|
|
{
|
|
|
|
return ::eldbus_message_path_get(_message);
|
|
|
|
}
|
|
|
|
const char* interface_get() const
|
|
|
|
{
|
|
|
|
return ::eldbus_message_interface_get(_message);
|
|
|
|
}
|
|
|
|
const char* member_get() const
|
|
|
|
{
|
|
|
|
return ::eldbus_message_member_get(_message);
|
|
|
|
}
|
|
|
|
const char* destination_get() const
|
|
|
|
{
|
|
|
|
return ::eldbus_message_destination_get(_message);
|
|
|
|
}
|
|
|
|
const char* sender_get() const
|
|
|
|
{
|
|
|
|
return ::eldbus_message_sender_get(_message);
|
|
|
|
}
|
|
|
|
const char* signature_get() const
|
|
|
|
{
|
|
|
|
return ::eldbus_message_signature_get(_message);
|
|
|
|
}
|
|
|
|
bool operator!() const
|
|
|
|
{
|
|
|
|
bool b (*this);
|
|
|
|
return !b;
|
|
|
|
}
|
|
|
|
explicit operator bool() const
|
|
|
|
{
|
|
|
|
const char* name, * text;
|
|
|
|
return !eldbus_message_error_get(_message, &name, &text);
|
|
|
|
}
|
|
|
|
std::pair<const char*, const char*> error_get() const
|
|
|
|
{
|
|
|
|
const char* name, * text;
|
|
|
|
eldbus_message_error_get(_message, &name, &text);
|
|
|
|
return {name, text};
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef message_iterator const_iterator;
|
|
|
|
typedef const_iterator iterator;
|
|
|
|
typedef Eldbus_Message const* native_handle_type;
|
|
|
|
typedef Eldbus_Message const* const_native_handle_type;
|
|
|
|
const_native_handle_type native_handle() const { return _message; }
|
|
|
|
const_native_handle_type const_native_handle() const { return _message; }
|
|
|
|
|
|
|
|
const_iterator begin() const
|
|
|
|
{
|
|
|
|
return const_iterator( ::eldbus_message_iter_get(_message));
|
|
|
|
}
|
|
|
|
const_iterator end() const
|
|
|
|
{
|
|
|
|
return const_iterator();
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
Eldbus_Message const* _message;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct message : const_message
|
|
|
|
{
|
|
|
|
typedef const_message base_type;
|
|
|
|
|
2014-07-03 15:35:40 -07:00
|
|
|
explicit message(Eldbus_Message* message_) : const_message(message_)
|
eldbus-cxx: Implementation of eldbus C++ API
Summary:
Applications can:
void method_callback(void* data, const Eldbus_Service_Interface* iface,
const Eldbus_Message* message);
struct { ... } data_struct;
Eldbus_Method methods[] =
{
"method1", ELDBUS_ARGS("b", "bool"), ELDBUS_ARGS("b", "bool"), ELDBUS_METHOD_FLAG_HAS_DATA
, (Eldbus_Method_Cb)&method_callback, &data_struct
};
And method_callback will be called with data parameter pointing to data_struct global object.
Also, Eldbus-cxx supports registering an interface passing a lambda or
function object as method. For example:
edb::service_interface iface = edb::service_interface_register
(c, path, interface
, es::method("SendStringAndBool"
, [expected_string, expected_bool] (std::string const& n, bool b
, bool* out)
{
std::cout << "Running SendStringAndBool" << std::endl;
ck_assert(n == expected_string);
ck_assert(b == expected_bool);
*out = b;
return n;
}
, es::ins<std::string, bool>("string", "bool")
, es::outs<std::string, bool>("string", "bool")
)
);
When a request for "SendStringAndBool" with the proper signature is
called, executes the lambda and replies with the return value and
its bool* out parameter value.
Reviewers: cedric, woohyun, raster
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D1052
2014-07-03 00:28:22 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
message(const_message const& other, reply_t r)
|
|
|
|
: const_message(other, r)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
message(const_message const& other, const char* error_name, const char* error_msg, error_t e)
|
|
|
|
: const_message(other, error_name, error_msg, e)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
message(const char* destination, const char* path, const char* iface
|
|
|
|
, const char* method, method_call_t m)
|
|
|
|
: const_message(destination, path, iface, method, m)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
message(message const& other)
|
|
|
|
: const_message(static_cast<base_type const&>(other))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
typedef Eldbus_Message* native_handle_type;
|
|
|
|
native_handle_type native_handle() { return const_cast<native_handle_type>(const_message::native_handle()); }
|
|
|
|
};
|
|
|
|
|
|
|
|
struct const_pending
|
|
|
|
{
|
|
|
|
const_pending() : _pending(0) {}
|
|
|
|
const_pending(Eldbus_Pending const* pending) : _pending(pending) {}
|
|
|
|
|
|
|
|
void* data_get(const char* key) const
|
|
|
|
{
|
|
|
|
return ::eldbus_pending_data_get(_pending, key);
|
|
|
|
}
|
|
|
|
const char* destination_get() const
|
|
|
|
{
|
|
|
|
return ::eldbus_pending_destination_get(_pending);
|
|
|
|
}
|
|
|
|
const char* path_get() const
|
|
|
|
{
|
|
|
|
return ::eldbus_pending_path_get(_pending);
|
|
|
|
}
|
|
|
|
const char* interface_get() const
|
|
|
|
{
|
|
|
|
return ::eldbus_pending_interface_get(_pending);
|
|
|
|
}
|
|
|
|
const char* method_get() const
|
|
|
|
{
|
|
|
|
return ::eldbus_pending_method_get(_pending);
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef Eldbus_Pending const* native_handle_type;
|
|
|
|
typedef Eldbus_Pending const* const_native_handle_type;
|
|
|
|
native_handle_type native_handle() const { return _pending; }
|
|
|
|
const_native_handle_type const_native_handle() const { return _pending; }
|
|
|
|
private:
|
|
|
|
const_native_handle_type _pending;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct pending : const_pending
|
|
|
|
{
|
|
|
|
pending() : const_pending(0) {}
|
2014-07-03 15:35:40 -07:00
|
|
|
pending(Eldbus_Pending* pending_) : const_pending(pending_) {}
|
eldbus-cxx: Implementation of eldbus C++ API
Summary:
Applications can:
void method_callback(void* data, const Eldbus_Service_Interface* iface,
const Eldbus_Message* message);
struct { ... } data_struct;
Eldbus_Method methods[] =
{
"method1", ELDBUS_ARGS("b", "bool"), ELDBUS_ARGS("b", "bool"), ELDBUS_METHOD_FLAG_HAS_DATA
, (Eldbus_Method_Cb)&method_callback, &data_struct
};
And method_callback will be called with data parameter pointing to data_struct global object.
Also, Eldbus-cxx supports registering an interface passing a lambda or
function object as method. For example:
edb::service_interface iface = edb::service_interface_register
(c, path, interface
, es::method("SendStringAndBool"
, [expected_string, expected_bool] (std::string const& n, bool b
, bool* out)
{
std::cout << "Running SendStringAndBool" << std::endl;
ck_assert(n == expected_string);
ck_assert(b == expected_bool);
*out = b;
return n;
}
, es::ins<std::string, bool>("string", "bool")
, es::outs<std::string, bool>("string", "bool")
)
);
When a request for "SendStringAndBool" with the proper signature is
called, executes the lambda and replies with the return value and
its bool* out parameter value.
Reviewers: cedric, woohyun, raster
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D1052
2014-07-03 00:28:22 -07:00
|
|
|
|
|
|
|
void data_set(const char* key, const char* data)
|
|
|
|
{
|
|
|
|
::eldbus_pending_data_set(native_handle(), key, data);
|
|
|
|
}
|
|
|
|
void* data_del(const char* key)
|
|
|
|
{
|
|
|
|
return ::eldbus_pending_data_del(native_handle(), key);
|
|
|
|
}
|
|
|
|
void cancel()
|
|
|
|
{
|
|
|
|
::eldbus_pending_cancel(native_handle());
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef Eldbus_Pending* native_handle_type;
|
|
|
|
native_handle_type native_handle()
|
|
|
|
{
|
|
|
|
return const_cast<native_handle_type>(const_pending::native_handle());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} }
|
|
|
|
|
|
|
|
#endif
|