/*
- * Copyright (C) 2016-2019 "IoT.bzh"
+ * Copyright (C) 2015-2020 "IoT.bzh"
* Author: José Bollo <jose.bollo@iot.bzh>
*
* Licensed under the Apache License, Version 2.0 (the "License");
#include <cstdlib>
#include <cstdarg>
#include <functional>
+#include <string>
/* ensure version */
#ifndef AFB_BINDING_VERSION
void failf(const char *error, const char *info, ...) const;
void failv(const char *error, const char *info, va_list args) const;
- template < class T > T *context() const;
-
void addref() const;
void unref() const;
int get_uid() const;
json_object *get_client_info() const;
+
+ template < class T = void >
+ class contextclass {
+
+ friend class req;
+ afb_req_t req_;
+ contextclass(afb_req_t r) : req_(r) {}
+ static void default_destroyer(T*t) { delete t; }
+
+ public:
+ inline operator T *() const { return get(); }
+ inline operator T &() const { return *get(); }
+ inline T* get() const {
+ return reinterpret_cast<T*>(
+ afb_req_context(req_, 0,
+ nullptr,
+ nullptr,
+ nullptr));
+ }
+
+ inline void set(T *value, void (*destroyer)(T*) = default_destroyer) const {
+ afb_req_context(req_, 1,
+ nullptr,
+ reinterpret_cast<void(*)(void*)>(destroyer),
+ reinterpret_cast<void*>(value));
+ }
+
+ inline void unset() { set(nullptr); }
+ inline void clear() { set(nullptr); }
+
+ inline T *lazy(T *(*allocator)() = []()->T*{return new T();}, void (*destroyer)(T*) = [](T*t){delete t;}) const {
+ return reinterpret_cast<T*>(
+ afb_req_context(req_, 0,
+ [allocator](void*)->T*{return allocator();},
+ reinterpret_cast<void(*)(void*)>(destroyer),
+ nullptr));
+ }
+
+ template <class I>
+ inline T *lazy(I *i, T *(*allocator)(I*) = [](I*i)->T*{return new T(i);}, void (*destroyer)(T*) = [](T*t){delete t;}) const {
+ return reinterpret_cast<T*>(
+ afb_req_context(req_, 0,
+ [allocator](void*i)->T*{return allocator(reinterpret_cast<I*>(i));},
+ reinterpret_cast<void(*)(void*)>(destroyer),
+ reinterpret_cast<void*>(i)));
+ }
+ };
+
+ template < class T > contextclass<T> context() const { return contextclass<T>(req_); }
};
/*************************************************************************/
va_end(args);
}
-template < class T >
-inline T *req::context() const
-{
- T* (*creater)(void*) = [](){return new T();};
- void (*freer)(T*) = [](T*t){delete t;};
- return reinterpret_cast<T*>(afb_req_context(req_, 0,
- reinterpret_cast<void *(*)(void*)>(creater),
- reinterpret_cast<void (*)(void*)>(freer), nullptr));
-}
-
inline void req::addref() const { afb_req_addref(req_); }
inline void req::unref() const { afb_req_unref(req_); }
constexpr afb_auth auth_no()
{
- afb_auth r = { afb_auth_No, 0, 0};
+ afb_auth r = { afb_auth_No, {0}, nullptr};
r.type = afb_auth_No;
return r;
}
constexpr afb_auth auth_yes()
{
- afb_auth r = { afb_auth_No, 0, 0};
+ afb_auth r = { afb_auth_No, {0}, nullptr};
r.type = afb_auth_Yes;
return r;
}
constexpr afb_auth auth_token()
{
- afb_auth r = { afb_auth_No, 0, 0};
+ afb_auth r = { afb_auth_No, {0}, nullptr};
r.type = afb_auth_Token;
return r;
}
constexpr afb_auth auth_LOA(unsigned loa)
{
- afb_auth r = { afb_auth_No, 0, 0};
+ afb_auth r = { afb_auth_No, {0}, nullptr};
r.type = afb_auth_LOA;
r.loa = loa;
return r;
constexpr afb_auth auth_permission(const char *permission)
{
- afb_auth r = { afb_auth_No, 0, 0};
+ afb_auth r = { afb_auth_No, {0}, nullptr};
r.type = afb_auth_Permission;
r.text = permission;
return r;
constexpr afb_auth auth_not(const afb_auth *other)
{
- afb_auth r = { afb_auth_No, 0, 0};
+ afb_auth r = { afb_auth_No, {0}, nullptr};
r.type = afb_auth_Not;
r.first = other;
return r;
constexpr afb_auth auth_or(const afb_auth *first, const afb_auth *next)
{
- afb_auth r = { afb_auth_No, 0, 0};
+ afb_auth r = { afb_auth_No, {0}, nullptr};
r.type = afb_auth_Or;
r.first = first;
r.next = next;
constexpr afb_auth auth_and(const afb_auth *first, const afb_auth *next)
{
- afb_auth r = { afb_auth_No, 0, 0};
+ afb_auth r = { afb_auth_No, {0}, nullptr};
r.type = afb_auth_And;
r.first = first;
r.next = next;
void *vcbdata = nullptr
)
{
- afb_verb_t r = { 0, 0, 0, 0, 0, 0, 0 };
- r.verb = name;
- r.callback = callback;
- r.info = info;
- r.session = session;
- r.auth = auth;
- r.glob = (unsigned)glob;
- r.vcbdata = vcbdata;
- return r;
+ return { name, callback, auth, info, vcbdata, session, glob };
}
void __attribute__((weak)) __afb__verb__cb__for__global__(afb_req_t r)
constexpr afb_verb_t verb(
const char *name,
- void (&callback)(req),
+ void (*callback)(req),
const char *info = nullptr,
uint16_t session = 0,
const afb_auth *auth = nullptr,
- bool glob = false,
- void *vcbdata = nullptr
+ bool glob = false
)
{
return verb(
session,
auth,
glob,
- (void*)(&callback)
+ *(void**)(&callback)
);
}
constexpr afb_verb_t verbend()
{
- afb_verb_t r = verb(nullptr, nullptr);
- return r;
+ return { 0, 0, 0, 0, 0, 0, 0 };
}
constexpr afb_binding_t binding(
void *userdata = nullptr
)
{
- afb_binding_t r = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- r.api = name;
- r.specification = specification;
- r.info = info;
- r.verbs = verbs;
- r.preinit = preinit;
- r.init = init;
- r.onevent = onevent;
- r.noconcurrency = noconcurrency ? 1 : 0;
- r.userdata = userdata;
- return r;
+ return {
+ name, specification, info, verbs, preinit, init, onevent, userdata,
+ nullptr, nullptr, nullptr, static_cast<unsigned int>(noconcurrency) };
};
/*************************************************************************/