MLIB
Loading...
Searching...
No Matches
jbridge.h
Go to the documentation of this file.
1
6#pragma once
7
8#include "httpd.h"
9#include "json.h"
10
11#include <list>
12#include <typeindex>
13
14namespace mlib {
15
16// Errors
17#define ERR_JSON_NOTFOUND -10
18#define ERR_JSON_DICSTRUC -11
19
20class JSONBridge;
21typedef void (*post_action) (JSONBridge&);
22typedef int (*post_fun) (const std::string& uri, JSONBridge& ui);
23
26{
27public:
47
48 class entry;
49 typedef std::list<entry> dictionary;
50 typedef dictionary::iterator dict_ptr;
51 typedef dictionary::const_iterator dict_cptr;
52
54 class entry
55 {
56 public:
57 entry (const std::string& n, void* a, jb_type t, size_t s, size_t c = 1)
58 : name (n)
59 , addr (a)
60 , type (t)
61 , cnt (c)
62 , sz (s)
63 {}
64
65 template <typename T, size_t C>
66 void add_var (T (&var)[C], const std::string& name)
67 {
68 using U = typename std::remove_extent<T>::type;
69 constexpr size_t sz = sizeof (U) * (std::extent_v<T> ? std::extent_v<T> : 1);
70 constexpr jb_type t = std::is_same_v<U, short> ? JT_SHORT
71 : std::is_same_v<U, unsigned short> ? JT_USHORT
72 : std::is_same_v<U, int> ? JT_INT
73 : std::is_same_v<U, unsigned int> ? JT_UINT
74 : std::is_same_v<U, long> ? JT_LONG
75 : std::is_same_v<U, unsigned long> ? JT_ULONG
76 : std::is_same_v<U, float> ? JT_FLT
77 : std::is_same_v<U, double> ? JT_DBL
78 : std::is_same_v<U, bool> ? JT_BOOL
79 : std::is_same_v<U, char> ? JT_CSTR
80 : std::is_same_v<U, std::string> ? JT_STR
81 : std::is_same_v<U, char*> ? JT_PSTR
82 : std::is_same_v<U, const char*> ? JT_PSTR
83 : JT_UNKNOWN;
84 static_assert (t != JT_UNKNOWN, "Invalid array type");
85 if (t == JT_CSTR && sz == 1)
86 children.emplace_back (name, var, t, C); // char var[C]
87 else
88 children.emplace_back (name, var, t, sz, C);
89 }
90
91 template <typename T>
92 std::enable_if_t<std::is_same_v<T, std::string> || std::is_same_v<T, short>
93 || std::is_same_v<T, unsigned short> || std::is_same_v<T, int>
94 || std::is_same_v<T, unsigned int> || std::is_same_v<T, long>
95 || std::is_same_v<T, unsigned long> || std::is_same_v<T, float>
96 || std::is_same_v<T, double> || std::is_same_v<T, bool>>
97 add_var (T& var, const std::string& name)
98 {
99 constexpr jb_type t = std::is_same_v<T, short> ? JT_SHORT
100 : std::is_same_v<T, unsigned short> ? JT_USHORT
101 : std::is_same_v<T, int> ? JT_INT
102 : std::is_same_v<T, unsigned int> ? JT_UINT
103 : std::is_same_v<T, long> ? JT_LONG
104 : std::is_same_v<T, unsigned long> ? JT_ULONG
105 : std::is_same_v<T, float> ? JT_FLT
106 : std::is_same_v<T, double> ? JT_DBL
107 : std::is_same_v<T, bool> ? JT_BOOL
108 : std::is_same_v<T, char> ? JT_CSTR
109 : std::is_same_v<T, std::string> ? JT_STR
110 : std::is_same_v<T, char*> ? JT_PSTR
111 : std::is_same_v<T, const char*> ? JT_PSTR
112 : JT_UNKNOWN;
113 static_assert (t != JT_UNKNOWN, "Invalid array type");
114 children.emplace_back (name, &var, t, sizeof (T));
115 }
116
117 entry& add_object (const std::string& name)
118 {
119 children.emplace_back (name, nullptr, JT_OBJECT, 0, 1);
120 return *(--children.end ());
121 }
122
123 private:
124 std::string name;
125 void* addr;
126 jb_type type;
127 size_t sz;
128 size_t cnt;
129 dictionary children;
130 friend class JSONBridge;
131 };
132
133 JSONBridge (const char* path);
134 ~JSONBridge ();
135
136 void attach_to (httpd& server);
137 void lock ();
138 void unlock ();
139 const std::string& path () const;
140 void set_action (post_action pfn);
142
143 bool parse_urlencoded () const;
144 bool parse_jsonencoded () const;
145
147 template <typename T, size_t C>
148 void add_var (T (&var)[C], const std::string& name)
149 {
150 using U = typename std::remove_extent<T>::type;
151 constexpr size_t sz = sizeof (U) * (std::extent_v<T> ? std::extent_v<T> : 1);
152 constexpr jb_type t = std::is_same_v<U, short> ? JT_SHORT
153 : std::is_same_v<U, unsigned short> ? JT_USHORT
154 : std::is_same_v<U, int> ? JT_INT
155 : std::is_same_v<U, unsigned int> ? JT_UINT
156 : std::is_same_v<U, long> ? JT_LONG
157 : std::is_same_v<U, unsigned long> ? JT_ULONG
158 : std::is_same_v<U, float> ? JT_FLT
159 : std::is_same_v<U, double> ? JT_DBL
160 : std::is_same_v<U, bool> ? JT_BOOL
161 : std::is_same_v<U, char> ? JT_CSTR
162 : std::is_same_v<U, char*> ? JT_PSTR
163 : std::is_same_v<U, const char*> ? JT_PSTR
164 : JT_UNKNOWN;
165 static_assert (t != JT_UNKNOWN, "Invalid array type");
166 if (t == JT_CSTR && sz == 1)
167 dict_.emplace_back (name, var, t, C, 1); // char var[C]
168 else
169 dict_.emplace_back (name, var, t, sz, C);
170 }
171
173 template <typename T>
174 std::enable_if_t<std::is_same_v<T, std::string> || std::is_same_v<T, short>
175 || std::is_same_v<T, unsigned short> || std::is_same_v<T, int>
176 || std::is_same_v<T, unsigned int> || std::is_same_v<T, long>
177 || std::is_same_v<T, unsigned long> || std::is_same_v<T, float>
178 || std::is_same_v<T, double> || std::is_same_v<T, bool>>
179 add_var (T& var, const std::string& name)
180 {
181 constexpr jb_type t = std::is_same_v<T, short> ? JT_SHORT
182 : std::is_same_v<T, unsigned short> ? JT_USHORT
183 : std::is_same_v<T, int> ? JT_INT
184 : std::is_same_v<T, unsigned int> ? JT_UINT
185 : std::is_same_v<T, long> ? JT_LONG
186 : std::is_same_v<T, unsigned long> ? JT_ULONG
187 : std::is_same_v<T, float> ? JT_FLT
188 : std::is_same_v<T, double> ? JT_DBL
189 : std::is_same_v<T, bool> ? JT_BOOL
190 : std::is_same_v<T, char> ? JT_CSTR
191 : std::is_same_v<T, std::string> ? JT_STR
192 : std::is_same_v<T, char*> ? JT_PSTR
193 : std::is_same_v<T, const char*> ? JT_PSTR
194 : JT_UNKNOWN;
195 static_assert (t != JT_UNKNOWN, "Invalid array type");
196 dict_.emplace_back (name, &var, t, sizeof (T));
197 }
198
199 entry& add_object (const std::string& name);
200 void add_postfun (const std::string& name, post_fun pfn);
201
202protected:
203 erc jsonify (json::node& n, dict_cptr entry);
204 void not_found (const char* varname);
205 bool find (const std::string& name, dict_cptr& found, size_t* idx = 0) const;
206 bool deep_find (const std::string& name, dict_cptr& found, size_t* idx = 0) const;
207
208private:
209 erc json_begin (json::node& obj);
210 erc json_end (json::node& obj);
211 erc serialize_node (json::node& n, dict_cptr v, size_t index = 0);
212 erc deserialize_node (const json::node& n, dict_cptr v, size_t index = 0) const;
213 std::string path_;
214 dictionary dict_;
215 http_connection* client_;
216 criticalsection in_use;
217 post_action action;
218 std::map<std::string, post_fun> post_handlers;
219
220 static int callback (const char* uri, http_connection& client, JSONBridge* ctx);
221 static bool deep_search (const std::string& var, const dictionary& dict, dict_cptr& found);
222};
223
224/*==================== INLINE FUNCTIONS ===========================*/
225
227inline void JSONBridge::lock ()
228{
229 in_use.enter ();
230}
231
233inline void JSONBridge::unlock ()
234{
235 in_use.leave ();
236}
237
239inline const std::string& JSONBridge::path () const
240{
241 return path_;
242}
243
246{
247 return client_;
248};
249
250inline void JSONBridge::set_action (post_action pfn)
251{
252 action = pfn;
253}
254
255inline JSONBridge::entry& JSONBridge::add_object (const std::string& name)
256{
257 dict_.emplace_back (name, nullptr, JT_OBJECT, 0, 1);
258 return *(--dict_.end ());
259}
260
261inline void JSONBridge::add_postfun (const std::string& name, post_fun pfn)
262{
263 post_handlers[name] = pfn;
264}
265
266} // end namespace mlib
Representation of a JSON node.
Definition json.h:59
JSON objects support.
Definition jbridge.h:26
http_connection * client()
Return currently connected client (if any)
Definition jbridge.h:245
bool find(const std::string &name, dict_cptr &found, size_t *idx=0) const
Search a variable in JSON dictionary.
Definition jbridge.cpp:266
std::enable_if_t< std::is_same_v< T, std::string >||std::is_same_v< T, short >||std::is_same_v< T, unsigned short >||std::is_same_v< T, int >||std::is_same_v< T, unsigned int >||std::is_same_v< T, long >||std::is_same_v< T, unsigned long >||std::is_same_v< T, float >||std::is_same_v< T, double >||std::is_same_v< T, bool > > add_var(T &var, const std::string &name)
add variable of one of basic types
Definition jbridge.h:179
JSONBridge(const char *path)
Creates a JSONBridge object for the given path.
Definition jbridge.cpp:53
void unlock()
Leave the critical section associated with this context.
Definition jbridge.h:233
void attach_to(httpd &server)
Attach JSONBridge object to a HTTP server.
Definition jbridge.cpp:63
erc jsonify(json::node &n, dict_cptr entry)
Serializes a variable to JSON format.
Definition jbridge.cpp:113
const std::string & path() const
Return the context path.
Definition jbridge.h:239
jb_type
Dictionary entry types.
Definition jbridge.h:30
@ JT_STR
std::string
Definition jbridge.h:42
@ JT_OBJECT
composite object
Definition jbridge.h:44
@ JT_PSTR
char*
Definition jbridge.h:40
@ JT_USHORT
unsigned short int
Definition jbridge.h:33
@ JT_LONG
long
Definition jbridge.h:36
@ JT_FLT
float
Definition jbridge.h:38
@ JT_POSTFUN
POST function call.
Definition jbridge.h:45
@ JT_CSTR
char[]
Definition jbridge.h:41
@ JT_BOOL
bool
Definition jbridge.h:43
@ JT_UINT
unsigned int
Definition jbridge.h:35
@ JT_ULONG
unsigned long
Definition jbridge.h:37
@ JT_INT
int
Definition jbridge.h:34
@ JT_DBL
double
Definition jbridge.h:39
@ JT_SHORT
short int
Definition jbridge.h:32
void add_var(T(&var)[C], const std::string &name)
add array
Definition jbridge.h:148
void lock()
Enter the critical section associated with this context.
Definition jbridge.h:227
bool parse_urlencoded() const
Parse the URL-encoded body of a POST request assigning new values to all variables.
Definition jbridge.cpp:338
Lightweight inter-thread synchronization.
Definition critsect.h:25
objects returned as a function result or thrown directly.
Definition errorcode.h:68
Representation of a HTTP client connection request.
Definition httpd.h:46
Small multi-threaded HTTP server.
Definition httpd.h:120
Implementation of httpd and http_connection classes.
Definition of json::node class.