deba2c8e8ab8938ed09aec4fddb279f673c99126
[src/app-framework-binder.git] / include / afb / c++ / binding-wrap.hpp
1 /*
2  * Copyright (C) 2016-2019 "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
25 /* ensure version */
26 #ifndef AFB_BINDING_VERSION
27 # define AFB_BINDING_VERSION   3
28 #endif
29
30 /* check the version */
31 #if AFB_BINDING_VERSION < 2
32 # error "AFB_BINDING_VERSION must be at least 2 but 3 is prefered"
33 #endif
34
35 /* get C definitions of bindings */
36 extern "C" {
37 #include <afb/afb-binding.h>
38 }
39
40 namespace afb {
41 /*************************************************************************/
42 /* pre-declaration of classes                                            */
43 /*************************************************************************/
44
45 class arg;
46 class event;
47 class req;
48
49 /*************************************************************************/
50 /* declaration of functions                                              */
51 /*************************************************************************/
52
53 int broadcast_event(const char *name, json_object *object = nullptr);
54
55 event make_event(const char *name);
56
57 void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args);
58
59 void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...);
60
61 int rootdir_get_fd();
62
63 int rootdir_open_locale_fd(const char *filename, int flags, const char *locale = nullptr);
64
65 int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout);
66
67 int require_api(const char *apiname, bool initialized = true);
68
69 int add_alias(const char *apiname, const char *aliasname);
70
71 int verbosity();
72
73 bool wants_errors();
74 bool wants_warnings();
75 bool wants_notices();
76 bool wants_infos();
77 bool wants_debugs();
78
79 #if AFB_BINDING_VERSION >= 3
80 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);
81
82 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);
83
84 bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result);
85 #else
86 void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, int iserror, struct json_object *result), void *closure);
87
88 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), T *closure);
89 #endif
90
91 bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result);
92
93 /*************************************************************************/
94 /* effective declaration of classes                                      */
95 /*************************************************************************/
96
97 /* events */
98 class event
99 {
100         afb_event_t event_;
101 public:
102         event() { invalidate(); }
103         event(afb_event_t e);
104         event(const event &other);
105         event &operator=(const event &other);
106
107         operator afb_event_t() const;
108         afb_event_t operator->() const;
109
110         operator bool() const;
111         bool is_valid() const;
112
113         void invalidate();
114
115         int broadcast(json_object *object) const;
116         int push(json_object *object) const;
117
118         void unref();
119         void addref();
120         const char *name() const;
121 };
122
123 /* args */
124 class arg
125 {
126         struct afb_arg arg_;
127 public:
128         arg() = delete;
129         arg(const struct afb_arg &a);
130         arg(const arg &other);
131         arg &operator=(const arg &other);
132
133         operator const struct afb_arg&() const;
134
135         bool has_name() const;
136         bool has_value() const;
137         bool has_path() const;
138
139         const char *name() const;
140         const char *value() const;
141         const char *path() const;
142 };
143
144 /* req(uest) */
145 class req
146 {
147         afb_req_t req_;
148
149 public:
150         req() = delete;
151         req(afb_req_t r);
152         req(const req &other);
153         req &operator=(const req &other);
154
155         operator afb_req_t() const;
156         afb_req_t operator->() const;
157
158         operator bool() const;
159         bool is_valid() const;
160
161         arg get(const char *name) const;
162
163         const char *value(const char *name) const;
164
165         const char *path(const char *name) const;
166
167         json_object *json() const;
168
169         void reply(json_object *obj = nullptr, const char *error = nullptr, const char *info = nullptr) const;
170         void replyf(json_object *obj, const char *error, const char *info, ...) const;
171         void replyv(json_object *obj, const char *error, const char *info, va_list args) const;
172
173         void success(json_object *obj = nullptr, const char *info = nullptr) const;
174         void successf(json_object *obj, const char *info, ...) const;
175         void successv(json_object *obj, const char *info, va_list args) const;
176
177         void fail(const char *error = "failed", const char *info = nullptr) const;
178         void failf(const char *error, const char *info, ...) const;
179         void failv(const char *error, const char *info, va_list args) const;
180
181         template < class T > T *context() const;
182
183         void addref() const;
184
185         void unref() const;
186
187         void session_close() const;
188
189         bool session_set_LOA(unsigned level) const;
190
191         bool subscribe(const event &event) const;
192
193         bool unsubscribe(const event &event) const;
194
195         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;
196         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;
197
198         bool subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const;
199
200 #if AFB_BINDING_VERSION >= 3
201         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;
202
203         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;
204
205         bool subcallsync(const char *api, const char *verb, json_object *args, int flags, struct json_object *&object, char *&error, char *&info) const;
206 #endif
207
208         void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const;
209
210         void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const;
211
212         bool has_permission(const char *permission) const;
213
214         char *get_application_id() const;
215
216         int get_uid() const;
217
218         json_object *get_client_info() const;
219 };
220
221 /*************************************************************************/
222 /* effective declaration of classes                                      */
223 /*************************************************************************/
224 /////////////////////////////////////////////////////////////////////////////////////////////////////
225 /////////////////////////////////////////////////////////////////////////////////////////////////////
226 /////////////////////////////////////////////////////////////////////////////////////////////////////
227 /////////////////////////////////////////////////////////////////////////////////////////////////////
228 /////////////////////////////////////////////////////////////////////////////////////////////////////
229 /////////////////////////////////////////////////////////////////////////////////////////////////////
230 /////////////////////////////////////////////////////////////////////////////////////////////////////
231 /////////////////////////////////////////////////////////////////////////////////////////////////////
232 /////////////////////////////////////////////////////////////////////////////////////////////////////
233 /////////////////////////////////////////////////////////////////////////////////////////////////////
234 /////////////////////////////////////////////////////////////////////////////////////////////////////
235 /////////////////////////////////////////////////////////////////////////////////////////////////////
236 /////////////////////////////////////////////////////////////////////////////////////////////////////
237 /////////////////////////////////////////////////////////////////////////////////////////////////////
238 /////////////////////////////////////////////////////////////////////////////////////////////////////
239 /////////////////////////////////////////////////////////////////////////////////////////////////////
240
241
242 /*************************************************************************/
243 /* effective declaration of classes                                      */
244 /*************************************************************************/
245
246 /* events */
247 inline event::event(afb_event_t e) : event_(e) { }
248 inline event::event(const event &other) : event_(other.event_) { }
249 inline event &event::operator=(const event &other) { event_ = other.event_; return *this; }
250
251 inline event::operator afb_event_t() const { return event_; }
252 inline afb_event_t event::operator->() const { return event_; }
253
254 inline event::operator bool() const { return is_valid(); }
255 inline bool event::is_valid() const { return afb_event_is_valid(event_); }
256
257 #if AFB_BINDING_VERSION >= 3
258 inline void event::invalidate() { event_ = nullptr; }
259 #else
260 inline void event::invalidate() { event_ = { nullptr, nullptr }; }
261 #endif
262
263 inline int event::broadcast(json_object *object) const { return afb_event_broadcast(event_, object); }
264 inline int event::push(json_object *object) const { return afb_event_push(event_, object); }
265
266 inline void event::unref() { afb_event_unref(event_); invalidate(); }
267 inline void event::addref() { afb_event_addref(event_); }
268 inline const char *event::name() const { return afb_event_name(event_); }
269
270 /* args */
271 inline arg::arg(const struct afb_arg &a) : arg_(a) {}
272 inline arg::arg(const arg &other) : arg_(other.arg_) {}
273 inline arg &arg::operator=(const arg &other) { arg_ = other.arg_; return *this; }
274
275 inline arg::operator const struct afb_arg&() const { return arg_; }
276
277 inline bool arg::has_name() const { return !!arg_.name; }
278 inline bool arg::has_value() const { return !!arg_.value; }
279 inline bool arg::has_path() const { return !!arg_.path; }
280
281 inline const char *arg::name() const { return arg_.name; }
282 inline const char *arg::value() const { return arg_.value; }
283 inline const char *arg::path() const { return arg_.path; }
284
285 /* req(uests)s */
286
287
288 inline req::req(afb_req_t r) : req_(r) {}
289 inline req::req(const req &other) : req_(other.req_) {}
290 inline req &req::operator=(const req &other) { req_ = other.req_; return *this; }
291
292 inline req::operator afb_req_t() const { return req_; }
293 inline afb_req_t req::operator->() const { return req_; }
294
295 inline req::operator bool() const { return is_valid(); }
296 inline bool req::is_valid() const { return afb_req_is_valid(req_); }
297
298 inline arg req::get(const char *name) const { return arg(afb_req_get(req_, name)); }
299
300 inline const char *req::value(const char *name) const { return afb_req_value(req_, name); }
301
302 inline const char *req::path(const char *name) const { return afb_req_path(req_, name); }
303
304 inline json_object *req::json() const { return afb_req_json(req_); }
305
306 inline void req::reply(json_object *obj, const char *error, const char *info) const { afb_req_reply(req_, obj, error, info); }
307 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); }
308 inline void req::replyf(json_object *obj, const char *error, const char *info, ...) const
309 {
310         va_list args;
311         va_start(args, info);
312         replyv(obj, error, info, args);
313         va_end(args);
314 }
315
316 inline void req::success(json_object *obj, const char *info) const { reply(obj, nullptr, info); }
317 inline void req::successv(json_object *obj, const char *info, va_list args) const { replyv(obj, nullptr, info, args); }
318 inline void req::successf(json_object *obj, const char *info, ...) const
319 {
320         va_list args;
321         va_start(args, info);
322         successv(obj, info, args);
323         va_end(args);
324 }
325
326 inline void req::fail(const char *error, const char *info) const { reply(nullptr, error, info); }
327 inline void req::failv(const char *error, const char *info, va_list args) const { replyv(nullptr, error, info, args); }
328 inline void req::failf(const char *error, const char *info, ...) const
329 {
330         va_list args;
331         va_start(args, info);
332         failv(error, info, args);
333         va_end(args);
334 }
335
336 template < class T >
337 inline T *req::context() const
338 {
339 #if AFB_BINDING_VERSION >= 3
340         T* (*creater)(void*) = [](){return new T();};
341         void (*freer)(T*) = [](T*t){delete t;};
342         return reinterpret_cast<T*>(afb_req_context(req_, 0,
343                         reinterpret_cast<void *(*)(void*)>(creater),
344                         reinterpret_cast<void (*)(void*)>(freer), nullptr));
345 #else
346         T* (*creater)() = [](){return new T();};
347         void (*freer)(T*) = [](T*t){delete t;};
348         return reinterpret_cast<T*>(afb_req_context(req_,
349                         reinterpret_cast<void *(*)()>(creater),
350                         reinterpret_cast<void (*)(void*)>(freer)));
351 #endif
352 }
353
354 inline void req::addref() const { afb_req_addref(req_); }
355
356 inline void req::unref() const { afb_req_unref(req_); }
357
358 inline void req::session_close() const { afb_req_session_close(req_); }
359
360 inline bool req::session_set_LOA(unsigned level) const { return !afb_req_session_set_LOA(req_, level); }
361
362 inline bool req::subscribe(const event &event) const { return !afb_req_subscribe(req_, event); }
363
364 inline bool req::unsubscribe(const event &event) const { return !afb_req_unsubscribe(req_, event); }
365
366
367
368
369
370 #if AFB_BINDING_VERSION >= 3
371
372 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
373 {
374         afb_req_subcall(req_, api, verb, args, flags, callback, closure);
375 }
376
377 template <class T>
378 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
379 {
380         subcall(api, verb, args, flags, reinterpret_cast<void(*)(void*,json_object*,const char*,const char*,afb_req_t)>(callback), reinterpret_cast<void*>(closure));
381 }
382
383 inline bool req::subcallsync(const char *api, const char *verb, json_object *args, int flags, struct json_object *&object, char *&error, char *&info) const
384 {
385         return !afb_req_subcall_sync(req_, api, verb, args, flags, &object, &error, &info);
386 }
387
388 #endif
389
390 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
391 {
392 #if AFB_BINDING_VERSION >= 3
393         afb_req_subcall_legacy(req_, api, verb, args, callback, closure);
394 #else
395         afb_req_subcall_req(req_, api, verb, args, callback, closure);
396 #endif
397 }
398
399 template <class T>
400 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
401 {
402         subcall(api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*,afb_req_t)>(callback), reinterpret_cast<void*>(closure));
403 }
404
405 inline bool req::subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const
406 {
407 #if AFB_BINDING_VERSION >= 3
408         return !afb_req_subcall_sync_legacy(req_, api, verb, args, &result);
409 #else
410         return !afb_req_subcall_sync(req_, api, verb, args, &result);
411 #endif
412 }
413
414 inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const
415 {
416         afb_req_verbose(req_, level, file, line, func, fmt, args);
417 }
418
419 inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const
420 {
421         va_list args;
422         va_start(args, fmt);
423         afb_req_verbose(req_, level, file, line, func, fmt, args);
424         va_end(args);
425 }
426
427 inline bool req::has_permission(const char *permission) const
428 {
429         return bool(afb_req_has_permission(req_, permission));
430 }
431
432 inline char *req::get_application_id() const
433 {
434         return afb_req_get_application_id(req_);
435 }
436
437 inline int req::get_uid() const
438 {
439         return afb_req_get_uid(req_);
440 }
441
442 inline json_object *req::get_client_info() const
443 {
444         return afb_req_get_client_info(req_);
445 }
446
447 /* commons */
448 inline int broadcast_event(const char *name, json_object *object)
449         { return afb_daemon_broadcast_event(name, object); }
450
451 inline event make_event(const char *name)
452         { return afb_daemon_make_event(name); }
453
454 inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args)
455         { afb_daemon_verbose(level, file, line, func, fmt, args); }
456
457 inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...)
458         { va_list args; va_start(args, fmt); verbose(level, file, line, func, fmt, args); va_end(args); }
459
460 inline int rootdir_get_fd()
461         { return afb_daemon_rootdir_get_fd(); }
462
463 inline int rootdir_open_locale_fd(const char *filename, int flags, const char *locale)
464         { return afb_daemon_rootdir_open_locale(filename, flags, locale); }
465
466 inline int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout)
467         { return afb_daemon_queue_job(callback, argument, group, timeout); }
468
469 inline int require_api(const char *apiname, bool initialized)
470         { return afb_daemon_require_api(apiname, int(initialized)); }
471
472 inline int add_alias(const char *apiname, const char *aliasname)
473         { return afb_daemon_add_alias(apiname, aliasname); }
474
475 #if AFB_BINDING_VERSION >= 3
476 inline int logmask()
477         { return afb_get_logmask(); }
478 #else
479 inline int logmask()
480         { return (1 << (1 + afb_get_verbosity() + AFB_SYSLOG_LEVEL_ERROR)) - 1; }
481 #endif
482
483 inline bool wants_errors()
484         { return AFB_SYSLOG_MASK_WANT_ERROR(logmask()); }
485
486 inline bool wants_warnings()
487         { return AFB_SYSLOG_MASK_WANT_WARNING(logmask()); }
488
489 inline bool wants_notices()
490         { return AFB_SYSLOG_MASK_WANT_NOTICE(logmask()); }
491
492 inline bool wants_infos()
493         { return AFB_SYSLOG_MASK_WANT_INFO(logmask()); }
494
495 inline bool wants_debugs()
496         { return AFB_SYSLOG_MASK_WANT_DEBUG(logmask()); }
497
498 #if AFB_BINDING_VERSION >= 3
499 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)
500 {
501         afb_service_call(api, verb, args, callback, closure);
502 }
503
504 template <class T>
505 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)
506 {
507         afb_service_call(api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*,afb_api_t)>(callback), reinterpret_cast<void*>(closure));
508 }
509
510 inline bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result, char *&error, char *&info)
511 {
512         return !!afb_service_call_sync(api, verb, args, &result, &error, &info);
513 }
514 #else
515 inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, int iserror, struct json_object *result), void *closure)
516 {
517         afb_service_call(api, verb, args, callback, closure);
518 }
519
520 template <class T>
521 inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(T*closure, int iserror, struct json_object *result), T *closure)
522 {
523         afb_service_call(api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*)>(callback), reinterpret_cast<void*>(closure));
524 }
525
526 inline bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result)
527 {
528         return !!afb_service_call_sync(api, verb, args, &result);
529 }
530 #endif
531
532 /*************************************************************************/
533 /* declaration of the binding's authorization s                          */
534 /*************************************************************************/
535
536 constexpr afb_auth auth_no()
537 {
538         afb_auth r = { afb_auth_No, 0, 0};
539         r.type = afb_auth_No;
540         return r;
541 }
542
543 constexpr afb_auth auth_yes()
544 {
545         afb_auth r = { afb_auth_No, 0, 0};
546         r.type = afb_auth_Yes;
547         return r;
548 }
549
550 constexpr afb_auth auth_token()
551 {
552         afb_auth r = { afb_auth_No, 0, 0};
553         r.type = afb_auth_Token;
554         return r;
555 }
556
557 constexpr afb_auth auth_LOA(unsigned loa)
558 {
559         afb_auth r = { afb_auth_No, 0, 0};
560         r.type = afb_auth_LOA;
561         r.loa = loa;
562         return r;
563 }
564
565 constexpr afb_auth auth_permission(const char *permission)
566 {
567         afb_auth r = { afb_auth_No, 0, 0};
568         r.type = afb_auth_Permission;
569         r.text = permission;
570         return r;
571 }
572
573 constexpr afb_auth auth_not(const afb_auth *other)
574 {
575         afb_auth r = { afb_auth_No, 0, 0};
576         r.type = afb_auth_Not;
577         r.first = other;
578         return r;
579 }
580
581 constexpr afb_auth auth_not(const afb_auth &other)
582 {
583         return auth_not(&other);
584 }
585
586 constexpr afb_auth auth_or(const afb_auth *first, const afb_auth *next)
587 {
588         afb_auth r = { afb_auth_No, 0, 0};
589         r.type = afb_auth_Or;
590         r.first = first;
591         r.next = next;
592         return r;
593 }
594
595 constexpr afb_auth auth_or(const afb_auth &first, const afb_auth &next)
596 {
597         return auth_or(&first, &next);
598 }
599
600 constexpr afb_auth auth_and(const afb_auth *first, const afb_auth *next)
601 {
602         afb_auth r = { afb_auth_No, 0, 0};
603         r.type = afb_auth_And;
604         r.first = first;
605         r.next = next;
606         return r;
607 }
608
609 constexpr afb_auth auth_and(const afb_auth &first, const afb_auth &next)
610 {
611         return auth_and(&first, &next);
612 }
613
614 constexpr afb_verb_t verb(
615         const char *name,
616         void (*callback)(afb_req_t),
617         const char *info = nullptr,
618         uint16_t session = 0,
619         const afb_auth *auth = nullptr
620 #if AFB_BINDING_VERSION >= 3
621         ,
622         bool glob = false,
623         void *vcbdata = nullptr
624 #endif
625 )
626 {
627 #if AFB_BINDING_VERSION >= 3
628         afb_verb_t r = { 0, 0, 0, 0, 0, 0, 0 };
629 #else
630         afb_verb_t r = { 0, 0, 0, 0, 0 };
631 #endif
632         r.verb = name;
633         r.callback = callback;
634         r.info = info;
635         r.session = session;
636         r.auth = auth;
637 #if AFB_BINDING_VERSION >= 3
638         r.glob = (unsigned)glob;
639         r.vcbdata = vcbdata;
640 #endif
641         return r;
642 }
643
644 constexpr afb_verb_t verbend()
645 {
646         afb_verb_t r = verb(nullptr, nullptr);
647         return r;
648 }
649
650 constexpr afb_binding_t binding(
651         const char *name,
652         const afb_verb_t *verbs,
653         const char *info = nullptr,
654 #if AFB_BINDING_VERSION >= 3
655         int (*init)(afb_api_t) = nullptr,
656         const char *specification = nullptr,
657         void (*onevent)(afb_api_t, const char*, struct json_object*) = nullptr,
658         bool noconcurrency = false,
659         int (*preinit)(afb_api_t) = nullptr,
660         void *userdata = nullptr
661 #else
662         int (*init)() = nullptr,
663         const char *specification = nullptr,
664         void (*onevent)(const char*, struct json_object*) = nullptr,
665         bool noconcurrency = false,
666         int (*preinit)() = nullptr
667 #endif
668 )
669 {
670 #if AFB_BINDING_VERSION >= 3
671         afb_binding_t r = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
672 #else
673         afb_binding_t r = { 0, 0, 0, 0, 0, 0, 0, 0 };
674 #endif
675         r.api = name;
676         r.specification = specification;
677         r.info = info;
678         r.verbs = verbs;
679         r.preinit = preinit;
680         r.init = init;
681         r.onevent = onevent;
682         r.noconcurrency = noconcurrency ? 1 : 0;
683 #if AFB_BINDING_VERSION >= 3
684         r.userdata = userdata;
685 #endif
686         return r;
687 };
688
689 /*************************************************************************/
690 /***                         E N D                                     ***/
691 /*************************************************************************/
692 }