Add gitlab issue/merge request templates
[src/app-framework-binder.git] / include / afb / c++ / binding-wrap.hpp
1 /*
2  * Copyright (C) 2015-2020 "IoT.bzh"
3  * Author: José Bollo <jose.bollo@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #pragma once
19
20 #include <cstddef>
21 #include <cstdlib>
22 #include <cstdarg>
23 #include <functional>
24 #include <string>
25
26 /* ensure version */
27 #ifndef AFB_BINDING_VERSION
28 # define AFB_BINDING_VERSION   3
29 #endif
30
31 /* check the version */
32 #if AFB_BINDING_VERSION < 3
33 # error "AFB_BINDING_VERSION must be at least 3"
34 #endif
35
36 /* get C definitions of bindings */
37 extern "C" {
38 #include <afb/afb-binding.h>
39 }
40
41 namespace afb {
42 /*************************************************************************/
43 /* pre-declaration of classes                                            */
44 /*************************************************************************/
45
46 class api;
47 class arg;
48 class event;
49 class req;
50
51 /*************************************************************************/
52 /* declaration of functions                                              */
53 /*************************************************************************/
54
55 int broadcast_event(const char *name, json_object *object = nullptr);
56
57 event make_event(const char *name);
58
59 void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args);
60
61 void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...);
62
63 int rootdir_get_fd();
64
65 int rootdir_open_locale_fd(const char *filename, int flags, const char *locale = nullptr);
66
67 int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout);
68
69 int require_api(const char *apiname, bool initialized = true);
70
71 int add_alias(const char *apiname, const char *aliasname);
72
73 int verbosity();
74
75 bool wants_errors();
76 bool wants_warnings();
77 bool wants_notices();
78 bool wants_infos();
79 bool wants_debugs();
80
81 void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, int iserror, struct json_object *result, afb_api_t api), void *closure);
82
83 template <class T> void call(const char *api, const char *verb, struct json_object *args, void (*callback)(T*closure, int iserror, struct json_object *result, afb_api_t api), T *closure);
84
85 bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result);
86
87 /*************************************************************************/
88 /* effective declaration of classes                                      */
89 /*************************************************************************/
90
91 /* apis */
92 class api
93 {
94 protected:
95         afb_api_t api_;
96 public:
97         using call_cb = void (*)(void *closure, struct json_object *object, const char *error, const char *info, afb_api_t api);
98         using queue_cb = void (*)(int signum, void *arg);
99         using event_cb = void (*)(void *, const char *, struct json_object *, afb_api_t);
100         using preinit_cb = int (*)(void *, afb_api_t);
101         using verb_cb = void (*)(afb_req_t req);
102         using onevent_cb = void (*)(afb_api_t api, const char *event, struct json_object *object);
103         using oninit_cb = int (*)(afb_api_t api);
104
105         api();
106         api(afb_api_t a);
107         api(const api &other) = delete;
108         api(api &&other);
109         ~api();
110         api &operator=(const api &other) = delete;
111         api &operator=(api &&other);
112
113         operator afb_api_t() const;
114         afb_api_t operator->() const;
115
116         /* General functions */
117         const char *name() const;
118         void *get_userdata() const;
119         void set_userdata(void *value) const;
120         int require_api(const char *name, int initialized) const;
121         int require_api(const std::string &name, int initialized) const;
122
123         /* Verbosity functions */
124         int wants_log_level(int level) const;
125         void vverbose(int level, const char *file, int line, const char *func, const char *fmt, va_list args) const;
126         void verbose(int level, const char *file, int line, const char *func, const char *fmt, ...) const;
127
128         /* Data retrieval functions */
129         int rootdir_get_fd() const;
130         int rootdir_open_locale(const char *filename, int flags, const char *locale) const;
131         int rootdir_open_locale(const std::string &filename, int flags, const std::string &locale) const;
132         struct json_object *settings() const;
133
134         /* Calls and job functions */
135         void call(const char *apiname, const char *verb, struct json_object *args, call_cb callback, void *closure) const;
136         void call(const std::string &apiname, const std::string &verb, struct json_object *args, call_cb callback, void *closure) const;
137         int call_sync(const char *apiname, const char *verb, struct json_object *args, struct json_object **object, char **error, char **info) const;
138         int call_sync(const std::string &apiname, const std::string &verb, struct json_object *args, struct json_object **object, std::string &error, std::string &info) const;
139         int queue_job(queue_cb callback, void *argument, void *group, int timeout) const;
140
141         /* Event functions */
142         int broadcast_event(const char *name, struct json_object *object) const;
143         int broadcast_event(const std::string &name, struct json_object *object) const;
144         event make_event(const char *name) const;
145         event make_event(const std::string &name) const;
146         int event_handler_add(const char *pattern, event_cb callback, void *closure) const;
147         int event_handler_add(const std::string &pattern, event_cb callback, void *closure) const;
148         int event_handler_del(const char *pattern, void **closure) const;
149         int event_handler_del(const std::string &pattern, void **closure) const;
150
151         /* Systemd functions */
152         struct sd_event *get_event_loop() const;
153         struct sd_bus *get_user_bus() const;
154         struct sd_bus *get_system_bus() const;
155
156         /* Dynamic api functions */
157         api new_api(const char *apiname, const char *info, int noconcurrency, preinit_cb preinit, void *closure) const;
158         api new_api(const std::string &apiname, const std::string &info, int noconcurrency, preinit_cb preinit, void *closure) const;
159         int set_verbs(const struct afb_verb_v2 *verbs) const;
160         int set_verbs(const struct afb_verb_v3 *verbs) const;
161         int add_verb(const char *verb, const char *info, verb_cb callback, void *vcbdata, const struct afb_auth *auth, uint32_t session, int glob) const;
162         int add_verb(const std::string &verb, const std::string &info, verb_cb callback, void *vcbdata, const struct afb_auth *auth, uint32_t session, int glob) const;
163         int del_verb(const char *verb, void **vcbdata) const;
164         int del_verb(const std::string &verb, void **vcbdata) const;
165         int on_event(onevent_cb onevent) const;
166         int on_init(oninit_cb oninit) const;
167         int provide_class(const char *name) const;
168         int provide_class(const std::string &name) const;
169         int require_class(const char *name) const;
170         int require_class(const std::string &name) const;
171         void seal() const;
172         int delete_api() const;
173         int add_alias(const char *name, const char *as_name) const;
174         int add_alias(const std::string &name, const std::string &as_name) const;
175 };
176
177 /* events */
178 class event
179 {
180         afb_event_t event_;
181 public:
182         event();
183         event(afb_event_t e);
184         event(const event &other);
185         event(event &&other);
186         ~event();
187         event &operator=(const event &other);
188         event &operator=(event &&other);
189
190         operator afb_event_t() const;
191         afb_event_t operator->() const;
192
193         operator bool() const;
194         bool is_valid() const;
195
196         int broadcast(json_object *object) const;
197         int push(json_object *object) const;
198
199         void unref();
200         void addref();
201         const char *name() const;
202 };
203
204 /* args */
205 class arg
206 {
207         struct afb_arg arg_;
208 public:
209         arg() = delete;
210         arg(const struct afb_arg &a);
211         arg(const arg &other);
212         arg &operator=(const arg &other);
213
214         operator const struct afb_arg&() const;
215
216         bool has_name() const;
217         bool has_value() const;
218         bool has_path() const;
219
220         const char *name() const;
221         const char *value() const;
222         const char *path() const;
223 };
224
225 /* req(uest) */
226 class req
227 {
228         afb_req_t req_;
229
230 public:
231         req() = delete;
232         req(afb_req_t r);
233         req(const req &other);
234         req &operator=(const req &other);
235
236         operator afb_req_t() const;
237         afb_req_t operator->() const;
238
239         operator bool() const;
240         bool is_valid() const;
241
242         arg get(const char *name) const;
243
244         const char *value(const char *name) const;
245
246         const char *path(const char *name) const;
247
248         json_object *json() const;
249
250         void reply(json_object *obj = nullptr, const char *error = nullptr, const char *info = nullptr) const;
251         void replyf(json_object *obj, const char *error, const char *info, ...) const;
252         void replyv(json_object *obj, const char *error, const char *info, va_list args) const;
253
254         void success(json_object *obj = nullptr, const char *info = nullptr) const;
255         void successf(json_object *obj, const char *info, ...) const;
256         void successv(json_object *obj, const char *info, va_list args) const;
257
258         void fail(const char *error = "failed", const char *info = nullptr) const;
259         void failf(const char *error, const char *info, ...) const;
260         void failv(const char *error, const char *info, va_list args) const;
261
262         void addref() const;
263
264         void unref() const;
265
266         void session_close() const;
267
268         bool session_set_LOA(unsigned level) const;
269
270         bool subscribe(const event &event) const;
271
272         bool unsubscribe(const event &event) const;
273
274         void subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result, afb_req_t req), void *closure) const;
275         template <class T> void subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result, afb_req_t req), T *closure) const;
276
277         bool subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const;
278
279         void subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(void *closure, json_object *object, const char *error, const char *info, afb_req_t req), void *closure) const;
280
281         template <class T> void subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(T *closure, json_object *object, const char *error, const char *info, afb_req_t req), T *closure) const;
282
283         bool subcallsync(const char *api, const char *verb, json_object *args, int flags, struct json_object *&object, char *&error, char *&info) const;
284
285         void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const;
286
287         void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const;
288
289         bool has_permission(const char *permission) const;
290
291         char *get_application_id() const;
292
293         int get_uid() const;
294
295         json_object *get_client_info() const;
296
297         template < class T = void >
298         class contextclass {
299
300                 friend class req;
301                 afb_req_t req_;
302                 contextclass(afb_req_t r) : req_(r) {}
303                 static void default_destroyer(T*t) { delete t; }
304
305         public:
306                 inline operator T *() const { return get(); }
307                 inline operator T &() const { return *get(); }
308                 inline T* get() const {
309                         return reinterpret_cast<T*>(
310                                 afb_req_context(req_, 0,
311                                         nullptr,
312                                         nullptr,
313                                         nullptr));
314                 }
315
316                 inline void set(T *value, void (*destroyer)(T*) = default_destroyer) const {
317                         afb_req_context(req_, 1,
318                                 nullptr,
319                                 reinterpret_cast<void(*)(void*)>(destroyer),
320                                 reinterpret_cast<void*>(value));
321                 }
322
323                 inline void unset() { set(nullptr); }
324                 inline void clear() { set(nullptr); }
325
326                 inline T *lazy(T *(*allocator)() = []()->T*{return new T();}, void (*destroyer)(T*) = [](T*t){delete t;}) const {
327                         return reinterpret_cast<T*>(
328                                 afb_req_context(req_, 0,
329                                         [allocator](void*)->T*{return allocator();},
330                                         reinterpret_cast<void(*)(void*)>(destroyer),
331                                         nullptr));
332                 }
333
334                 template <class I>
335                 inline T *lazy(I *i, T *(*allocator)(I*) = [](I*i)->T*{return new T(i);}, void (*destroyer)(T*) = [](T*t){delete t;}) const {
336                         return reinterpret_cast<T*>(
337                                 afb_req_context(req_, 0,
338                                         [allocator](void*i)->T*{return allocator(reinterpret_cast<I*>(i));},
339                                         reinterpret_cast<void(*)(void*)>(destroyer),
340                                         reinterpret_cast<void*>(i)));
341                 }
342         };
343
344         template < class T > contextclass<T> context() const { return contextclass<T>(req_); }
345 };
346
347 /*************************************************************************/
348 /* effective declaration of classes                                      */
349 /*************************************************************************/
350 /////////////////////////////////////////////////////////////////////////////////////////////////////
351 /////////////////////////////////////////////////////////////////////////////////////////////////////
352 /////////////////////////////////////////////////////////////////////////////////////////////////////
353 /////////////////////////////////////////////////////////////////////////////////////////////////////
354 /////////////////////////////////////////////////////////////////////////////////////////////////////
355 /////////////////////////////////////////////////////////////////////////////////////////////////////
356 /////////////////////////////////////////////////////////////////////////////////////////////////////
357 /////////////////////////////////////////////////////////////////////////////////////////////////////
358 /////////////////////////////////////////////////////////////////////////////////////////////////////
359 /////////////////////////////////////////////////////////////////////////////////////////////////////
360 /////////////////////////////////////////////////////////////////////////////////////////////////////
361 /////////////////////////////////////////////////////////////////////////////////////////////////////
362 /////////////////////////////////////////////////////////////////////////////////////////////////////
363 /////////////////////////////////////////////////////////////////////////////////////////////////////
364 /////////////////////////////////////////////////////////////////////////////////////////////////////
365 /////////////////////////////////////////////////////////////////////////////////////////////////////
366
367
368 /*************************************************************************/
369 /* effective declaration of classes                                      */
370 /*************************************************************************/
371
372 /* apis */
373 inline api::api() : api_{nullptr} { }
374 inline api::api(afb_api_t a) : api_{a} { }
375 inline api::api(api &&other) : api_{other.api_} { other.api_ = nullptr; }
376 inline api::~api() { api_ = nullptr; }
377 inline api &api::operator=(api &&other) { api_ = other.api_; other.api_ = nullptr; return *this;}
378 inline api::operator afb_api_t() const { return api_; }
379 inline afb_api_t api::operator->() const { return api_; }
380 inline const char *api::name() const { return afb_api_name(api_); }
381 inline void *api::get_userdata() const { return afb_api_get_userdata(api_); }
382 inline void api::set_userdata(void *value) const { afb_api_set_userdata(api_, value); }
383 inline int api::require_api(const char *name, int initialized) const { return afb_api_require_api(api_, name, initialized); }
384 inline int api::require_api(const std::string& name, int initialized) const { return afb_api_require_api(api_, name.c_str(), initialized); }
385 inline int api::wants_log_level(int level) const { return afb_api_wants_log_level(api_, level); }
386 inline void api::vverbose(int level, const char *file, int line, const char *func, const char *fmt, va_list args) const { afb_api_vverbose(api_, level, file, line, func, fmt, args); }
387 inline void api::verbose(int level, const char *file, int line, const char *func, const char *fmt, ...) const
388 {
389         va_list args;
390         va_start(args, fmt);
391         vverbose(level, file, line, func, fmt, args);
392         va_end(args);
393 }
394 inline int api::rootdir_get_fd() const { return afb_api_rootdir_get_fd(api_); }
395 inline int api::rootdir_open_locale(const char *filename, int flags, const char *locale) const { return afb_api_rootdir_open_locale(api_, filename, flags, locale); }
396 inline int api::rootdir_open_locale(const std::string &filename, int flags, const std::string &locale) const { return afb_api_rootdir_open_locale(api_, filename.c_str(), flags, locale.c_str()); }
397 inline struct json_object *api::settings() const { return afb_api_settings(api_); }
398 inline void api::call(const char *apiname, const char *verb, struct json_object *args, call_cb callback, void *closure) const { afb_api_call(api_, apiname, verb, args, callback, closure); }
399 inline void api::call(const std::string &apiname, const std::string &verb, struct json_object *args, call_cb callback, void *closure) const { afb_api_call(api_, apiname.c_str(), verb.c_str(), args, callback, closure); }
400 inline int api::call_sync(const char *apiname, const char *verb, struct json_object *args, struct json_object **object, char **error, char **info) const { return afb_api_call_sync(api_, apiname, verb, args, object, error, info); }
401 inline int api::call_sync(const std::string &apiname, const std::string &verb, struct json_object *args, struct json_object **object, std::string &error, std::string& info) const
402 {
403         char *err, *inf;
404         int ret = afb_api_call_sync(api_, apiname.c_str(), verb.c_str(), args, object, &err, &inf);
405         error = err;
406         info = inf;
407         return ret;
408 }
409 inline int api::queue_job(queue_cb callback, void *argument, void *group, int timeout) const { return afb_api_queue_job(api_, callback, argument, group, timeout); }
410 inline int api::broadcast_event(const char *name, struct json_object *object) const { return afb_api_broadcast_event(api_, name, object); }
411 inline int api::broadcast_event(const std::string &name, struct json_object *object) const { return afb_api_broadcast_event(api_, name.c_str(), object); }
412 inline event api::make_event(const char *name) const { return event(afb_api_make_event(api_, name)); }
413 inline event api::make_event(const std::string &name) const { return event(afb_api_make_event(api_, name.c_str())); }
414 inline int api::event_handler_add(const char *pattern, event_cb callback, void *closure) const { return afb_api_event_handler_add(api_, pattern, callback, closure); }
415 inline int api::event_handler_add(const std::string &pattern, event_cb callback, void *closure) const { return afb_api_event_handler_add(api_, pattern.c_str(), callback, closure); }
416 inline int api::event_handler_del(const char *pattern, void **closure) const { return afb_api_event_handler_del(api_, pattern, closure); }
417 inline int api::event_handler_del(const std::string &pattern, void **closure) const { return afb_api_event_handler_del(api_, pattern.c_str(), closure); }
418 inline struct sd_event *api::get_event_loop() const { return afb_api_get_event_loop(api_); }
419 inline struct sd_bus *api::get_user_bus() const { return afb_api_get_user_bus(api_); }
420 inline struct sd_bus *api::get_system_bus() const { return afb_api_get_system_bus(api_); }
421 inline api api::new_api(const char *apiname, const char *info, int noconcurrency, preinit_cb preinit, void *closure) const { return api(afb_api_new_api(api_, apiname, info, noconcurrency, preinit, closure)); }
422 inline api api::new_api(const std::string &apiname, const std::string &info, int noconcurrency, preinit_cb preinit, void *closure) const { return api(afb_api_new_api(api_, apiname.c_str(), info.c_str(), noconcurrency, preinit, closure)); }
423 inline int api::set_verbs(const struct afb_verb_v2 *verbs) const { return afb_api_set_verbs_v2(api_, verbs); }
424 inline int api::set_verbs(const struct afb_verb_v3 *verbs) const { return afb_api_set_verbs_v3(api_, verbs); }
425 inline int api::add_verb(const char *verb, const char *info, verb_cb callback, void *vcbdata, const struct afb_auth *auth, uint32_t session, int glob) const { return afb_api_add_verb(api_, verb, info, callback, vcbdata, auth, session, glob); }
426 inline int api::add_verb(const std::string &verb, const std::string &info, verb_cb callback, void *vcbdata, const struct afb_auth *auth, uint32_t session, int glob) const { return afb_api_add_verb(api_, verb.c_str(), info.c_str(), callback, vcbdata, auth, session, glob); }
427 inline int api::del_verb(const char *verb, void **vcbdata) const { return afb_api_del_verb(api_, verb, vcbdata); }
428 inline int api::del_verb(const std::string &verb, void **vcbdata) const { return afb_api_del_verb(api_, verb.c_str(), vcbdata); }
429 inline int api::on_event(onevent_cb onevent) const { return afb_api_on_event(api_, onevent); }
430 inline int api::on_init(oninit_cb oninit) const { return afb_api_on_init(api_, oninit); }
431 inline int api::provide_class(const char *name) const { return afb_api_provide_class(api_, name); }
432 inline int api::provide_class(const std::string &name) const { return afb_api_provide_class(api_, name.c_str()); }
433 inline int api::require_class(const char *name) const { return afb_api_require_class(api_, name); }
434 inline int api::require_class(const std::string &name) const { return afb_api_require_class(api_, name.c_str()); }
435 inline void api::seal() const { afb_api_seal(api_); }
436 inline int api::delete_api() const { return afb_api_delete_api(api_); }
437 inline int api::add_alias(const char *name, const char *as_name) const { return afb_api_add_alias(api_, name, as_name); }
438 inline int api::add_alias(const std::string &name, const std::string &as_name) const { return afb_api_add_alias(api_, name.c_str(), as_name.c_str()); }
439
440 /* events */
441 inline event::event() : event_{nullptr} { }
442 inline event::event(afb_event_t e) : event_{e} { }
443 inline event::event(event &&other) : event_{other.event_} { other.event_ = nullptr; }
444 inline event::event(const event &other) : event_{other.event_} { addref(); }
445 inline event::~event() { unref(); }
446 inline event &event::operator=(const event &other) { event_ = other.event_; return *this; }
447 inline event &event::operator=(event &&other) { event_ = other.event_; other.event_ = nullptr; return *this;}
448
449 inline event::operator afb_event_t() const { return event_; }
450 inline afb_event_t event::operator->() const { return event_; }
451
452 inline event::operator bool() const { return is_valid(); }
453 inline bool event::is_valid() const { return afb_event_is_valid(event_); }
454
455 inline int event::broadcast(json_object *object) const { return afb_event_broadcast(event_, object); }
456 inline int event::push(json_object *object) const { return afb_event_push(event_, object); }
457
458 inline void event::unref() { if (event_) { afb_event_unref(event_); } event_ = nullptr; }
459 inline void event::addref() { afb_event_addref(event_); }
460 inline const char *event::name() const { return afb_event_name(event_); }
461
462 /* args */
463 inline arg::arg(const struct afb_arg &a) : arg_(a) {}
464 inline arg::arg(const arg &other) : arg_(other.arg_) {}
465 inline arg &arg::operator=(const arg &other) { arg_ = other.arg_; return *this; }
466
467 inline arg::operator const struct afb_arg&() const { return arg_; }
468
469 inline bool arg::has_name() const { return !!arg_.name; }
470 inline bool arg::has_value() const { return !!arg_.value; }
471 inline bool arg::has_path() const { return !!arg_.path; }
472
473 inline const char *arg::name() const { return arg_.name; }
474 inline const char *arg::value() const { return arg_.value; }
475 inline const char *arg::path() const { return arg_.path; }
476
477 /* req(uests)s */
478
479 inline req::req(afb_req_t r) : req_(r) {}
480 inline req::req(const req &other) : req_(other.req_) {}
481 inline req &req::operator=(const req &other) { req_ = other.req_; return *this; }
482
483 inline req::operator afb_req_t() const { return req_; }
484 inline afb_req_t req::operator->() const { return req_; }
485
486 inline req::operator bool() const { return is_valid(); }
487 inline bool req::is_valid() const { return afb_req_is_valid(req_); }
488
489 inline arg req::get(const char *name) const { return arg(afb_req_get(req_, name)); }
490
491 inline const char *req::value(const char *name) const { return afb_req_value(req_, name); }
492
493 inline const char *req::path(const char *name) const { return afb_req_path(req_, name); }
494
495 inline json_object *req::json() const { return afb_req_json(req_); }
496
497 inline void req::reply(json_object *obj, const char *error, const char *info) const { afb_req_reply(req_, obj, error, info); }
498 inline void req::replyv(json_object *obj, const char *error, const char *info, va_list args) const { afb_req_reply_v(req_, obj, error, info, args); }
499 inline void req::replyf(json_object *obj, const char *error, const char *info, ...) const
500 {
501         va_list args;
502         va_start(args, info);
503         replyv(obj, error, info, args);
504         va_end(args);
505 }
506
507 inline void req::success(json_object *obj, const char *info) const { reply(obj, nullptr, info); }
508 inline void req::successv(json_object *obj, const char *info, va_list args) const { replyv(obj, nullptr, info, args); }
509 inline void req::successf(json_object *obj, const char *info, ...) const
510 {
511         va_list args;
512         va_start(args, info);
513         successv(obj, info, args);
514         va_end(args);
515 }
516
517 inline void req::fail(const char *error, const char *info) const { reply(nullptr, error, info); }
518 inline void req::failv(const char *error, const char *info, va_list args) const { replyv(nullptr, error, info, args); }
519 inline void req::failf(const char *error, const char *info, ...) const
520 {
521         va_list args;
522         va_start(args, info);
523         failv(error, info, args);
524         va_end(args);
525 }
526
527 inline void req::addref() const { afb_req_addref(req_); }
528
529 inline void req::unref() const { afb_req_unref(req_); }
530
531 inline void req::session_close() const { afb_req_session_close(req_); }
532
533 inline bool req::session_set_LOA(unsigned level) const { return !afb_req_session_set_LOA(req_, level); }
534
535 inline bool req::subscribe(const event &event) const { return !afb_req_subscribe(req_, event); }
536
537 inline bool req::unsubscribe(const event &event) const { return !afb_req_unsubscribe(req_, event); }
538
539 inline void req::subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(void *closure, json_object *result, const char *error, const char *info, afb_req_t req), void *closure) const
540 {
541         afb_req_subcall(req_, api, verb, args, flags, callback, closure);
542 }
543
544 template <class T>
545 inline void req::subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(T *closure, json_object *result, const char *error, const char *info, afb_req_t req), T *closure) const
546 {
547         subcall(api, verb, args, flags, reinterpret_cast<void(*)(void*,json_object*,const char*,const char*,afb_req_t)>(callback), reinterpret_cast<void*>(closure));
548 }
549
550 inline bool req::subcallsync(const char *api, const char *verb, json_object *args, int flags, struct json_object *&object, char *&error, char *&info) const
551 {
552         return !afb_req_subcall_sync(req_, api, verb, args, flags, &object, &error, &info);
553 }
554
555 inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result, afb_req_t req), void *closure) const
556 {
557         afb_req_subcall_legacy(req_, api, verb, args, callback, closure);
558 }
559
560 template <class T>
561 inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result, afb_req_t req), T *closure) const
562 {
563         subcall(api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*,afb_req_t)>(callback), reinterpret_cast<void*>(closure));
564 }
565
566 inline bool req::subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const
567 {
568         return !afb_req_subcall_sync_legacy(req_, api, verb, args, &result);
569 }
570
571 inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const
572 {
573         afb_req_verbose(req_, level, file, line, func, fmt, args);
574 }
575
576 inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const
577 {
578         va_list args;
579         va_start(args, fmt);
580         afb_req_verbose(req_, level, file, line, func, fmt, args);
581         va_end(args);
582 }
583
584 inline bool req::has_permission(const char *permission) const
585 {
586         return bool(afb_req_has_permission(req_, permission));
587 }
588
589 inline char *req::get_application_id() const
590 {
591         return afb_req_get_application_id(req_);
592 }
593
594 inline int req::get_uid() const
595 {
596         return afb_req_get_uid(req_);
597 }
598
599 inline json_object *req::get_client_info() const
600 {
601         return afb_req_get_client_info(req_);
602 }
603
604 /* commons */
605 inline int broadcast_event(const char *name, json_object *object)
606         { return afb_daemon_broadcast_event(name, object); }
607
608 inline event make_event(const char *name)
609         { return afb_daemon_make_event(name); }
610
611 inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args)
612         { afb_daemon_verbose(level, file, line, func, fmt, args); }
613
614 inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...)
615         { va_list args; va_start(args, fmt); verbose(level, file, line, func, fmt, args); va_end(args); }
616
617 inline int rootdir_get_fd()
618         { return afb_daemon_rootdir_get_fd(); }
619
620 inline int rootdir_open_locale_fd(const char *filename, int flags, const char *locale)
621         { return afb_daemon_rootdir_open_locale(filename, flags, locale); }
622
623 inline int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout)
624         { return afb_daemon_queue_job(callback, argument, group, timeout); }
625
626 inline int require_api(const char *apiname, bool initialized)
627         { return afb_daemon_require_api(apiname, int(initialized)); }
628
629 inline int add_alias(const char *apiname, const char *aliasname)
630         { return afb_daemon_add_alias(apiname, aliasname); }
631
632 inline int logmask()
633         { return afb_get_logmask(); }
634
635 inline bool wants_errors()
636         { return AFB_SYSLOG_MASK_WANT_ERROR(logmask()); }
637
638 inline bool wants_warnings()
639         { return AFB_SYSLOG_MASK_WANT_WARNING(logmask()); }
640
641 inline bool wants_notices()
642         { return AFB_SYSLOG_MASK_WANT_NOTICE(logmask()); }
643
644 inline bool wants_infos()
645         { return AFB_SYSLOG_MASK_WANT_INFO(logmask()); }
646
647 inline bool wants_debugs()
648         { return AFB_SYSLOG_MASK_WANT_DEBUG(logmask()); }
649
650 inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, struct json_object *result, const char *error, const char *info, afb_api_t api), void *closure)
651 {
652         afb_service_call(api, verb, args, callback, closure);
653 }
654
655 template <class T>
656 inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(T*closure, struct json_object *result, const char *error, const char *info, afb_api_t api), T *closure)
657 {
658         afb_service_call(api, verb, args, reinterpret_cast<void(*)(void*,json_object*,const char*, const char*,afb_api_t)>(callback), reinterpret_cast<void*>(closure));
659 }
660
661 inline bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result, char *&error, char *&info)
662 {
663         return !!afb_service_call_sync(api, verb, args, &result, &error, &info);
664 }
665
666 /*************************************************************************/
667 /* declaration of the binding's authorization s                          */
668 /*************************************************************************/
669
670 constexpr afb_auth auth_no()
671 {
672         afb_auth r = { afb_auth_No, {0}, nullptr};
673         r.type = afb_auth_No;
674         return r;
675 }
676
677 constexpr afb_auth auth_yes()
678 {
679         afb_auth r = { afb_auth_No, {0}, nullptr};
680         r.type = afb_auth_Yes;
681         return r;
682 }
683
684 constexpr afb_auth auth_token()
685 {
686         afb_auth r = { afb_auth_No, {0}, nullptr};
687         r.type = afb_auth_Token;
688         return r;
689 }
690
691 constexpr afb_auth auth_LOA(unsigned loa)
692 {
693         afb_auth r = { afb_auth_No, {0}, nullptr};
694         r.type = afb_auth_LOA;
695         r.loa = loa;
696         return r;
697 }
698
699 constexpr afb_auth auth_permission(const char *permission)
700 {
701         afb_auth r = { afb_auth_No, {0}, nullptr};
702         r.type = afb_auth_Permission;
703         r.text = permission;
704         return r;
705 }
706
707 constexpr afb_auth auth_not(const afb_auth *other)
708 {
709         afb_auth r = { afb_auth_No, {0}, nullptr};
710         r.type = afb_auth_Not;
711         r.first = other;
712         return r;
713 }
714
715 constexpr afb_auth auth_not(const afb_auth &other)
716 {
717         return auth_not(&other);
718 }
719
720 constexpr afb_auth auth_or(const afb_auth *first, const afb_auth *next)
721 {
722         afb_auth r = { afb_auth_No, {0}, nullptr};
723         r.type = afb_auth_Or;
724         r.first = first;
725         r.next = next;
726         return r;
727 }
728
729 constexpr afb_auth auth_or(const afb_auth &first, const afb_auth &next)
730 {
731         return auth_or(&first, &next);
732 }
733
734 constexpr afb_auth auth_and(const afb_auth *first, const afb_auth *next)
735 {
736         afb_auth r = { afb_auth_No, {0}, nullptr};
737         r.type = afb_auth_And;
738         r.first = first;
739         r.next = next;
740         return r;
741 }
742
743 constexpr afb_auth auth_and(const afb_auth &first, const afb_auth &next)
744 {
745         return auth_and(&first, &next);
746 }
747
748 constexpr afb_verb_t verb(
749         const char *name,
750         void (*callback)(afb_req_t),
751         const char *info = nullptr,
752         uint16_t session = 0,
753         const afb_auth *auth = nullptr,
754         bool glob = false,
755         void *vcbdata = nullptr
756 )
757 {
758         return { name, callback, auth, info, vcbdata, session, glob };
759 }
760
761 void __attribute__((weak)) __afb__verb__cb__for__global__(afb_req_t r)
762 {
763         void *vcbdata;
764         void (*callback)(req);
765
766         vcbdata = afb_req_get_vcbdata(r);
767         callback = reinterpret_cast<void(*)(req)>(vcbdata);
768         callback(req(r));
769 }
770
771 constexpr afb_verb_t verb(
772         const char *name,
773         void (*callback)(req),
774         const char *info = nullptr,
775         uint16_t session = 0,
776         const afb_auth *auth = nullptr,
777         bool glob = false
778 )
779 {
780         return verb(
781                 name,
782                 __afb__verb__cb__for__global__,
783                 info,
784                 session,
785                 auth,
786                 glob,
787                 *(void**)(&callback)
788         );
789 }
790
791 constexpr afb_verb_t verbend()
792 {
793         return { 0, 0, 0, 0, 0, 0, 0 };
794 }
795
796 constexpr afb_binding_t binding(
797         const char *name,
798         const afb_verb_t *verbs,
799         const char *info = nullptr,
800         int (*init)(afb_api_t) = nullptr,
801         const char *specification = nullptr,
802         void (*onevent)(afb_api_t, const char*, struct json_object*) = nullptr,
803         bool noconcurrency = false,
804         int (*preinit)(afb_api_t) = nullptr,
805         void *userdata = nullptr
806 )
807 {
808         return {
809                 name, specification, info, verbs, preinit, init, onevent, userdata,
810                 nullptr, nullptr, nullptr, static_cast<unsigned int>(noconcurrency) };
811 };
812
813 /*************************************************************************/
814 /***                         E N D                                     ***/
815 /*************************************************************************/
816 }