Add API allowing xAPPs to send alarm messages
[ric-plt/xapp-frame-cpp.git] / src / json / jhash.cpp
1 // vi: ts=4 sw=4 noet:
2 /*
3 ==================================================================================
4         Copyright (c) 2020 Nokia
5         Copyright (c) 2020 AT&T Intellectual Property.
6
7    Licensed under the Apache License, Version 2.0 (the "License");
8    you may not use this file except in compliance with the License.
9    You may obtain a copy of the License at
10
11        http://www.apache.org/licenses/LICENSE-2.0
12
13    Unless required by applicable law or agreed to in writing, software
14    distributed under the License is distributed on an "AS IS" BASIS,
15    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16    See the License for the specific language governing permissions and
17    limitations under the License.
18 ==================================================================================
19 */
20
21 /*
22         Mnemonic:       jhash.cpp
23         Abstract:       This class provides the ability to parse a json string into
24                                 a hashtable, and exposes various functions that can be used
25                                 to read the data from the hash.
26
27         Date:           26 June 2020
28         Author:         E. Scott Daniels
29 */
30
31
32 #include <string>
33
34 #include "jwrapper.h"
35 #include "jhash.hpp"
36
37
38 namespace xapp {
39
40
41 // ------------------------------------------------------------------------
42
43
44
45 // ----------- construction/destruction housekeeping things -------------------
46 /*
47         Accept a string that contains valid json. Causes it to be parsed
48         after which the functions provided by the class can be used to
49         suss out the values.
50 */
51 xapp::Jhash::Jhash( const char* jbuf ) :
52         master_st( NULL ),
53         st( jw_new( jbuf ) )
54 { /* empty body */ }
55
56
57 /*
58         Move constructor.
59 */
60 Jhash::Jhash( Jhash&& soi ) {
61         master_st = soi.master_st;
62         st = soi.st;
63
64         soi.st = NULL;                                          // prevent closing of RMR stuff on soi destroy
65         soi.master_st = NULL;
66 }
67
68 /*
69         Move Operator.
70 */
71 Jhash& Jhash::operator=( Jhash&& soi ) {
72         if( this != &soi ) {                                            // cannot do self assignment
73                 master_st = soi.master_st;
74                 st = soi.st;
75
76                 soi.st = NULL;                                          // prevent closing of RMR stuff on soi destroy
77                 soi.master_st = NULL;
78         }
79
80         return *this;
81 }
82
83 /*
84         Blow it away.
85 */
86 xapp::Jhash::~Jhash() {
87         if( master_st != NULL ) {               // revert blob set if needed
88                 st = master_st;
89         }
90
91         jw_nuke( st );
92         st = NULL;
93         master_st = NULL;
94 }
95
96
97 // ------------ public API ---------------------------------------------------
98
99 // IMPORTANT: all underlying jwrapper functions check for nil st and name pointers
100 //                              so that is NOT needed in this code.
101
102
103 // --- root control ----------------------------------------------------------
104 /*
105         Sets the "root" to the named blob. Until unset, all subsequent
106         calls to Jhash functions (e.g. Is_missing()) will use this for the
107         look up. Returns true if name exists and was indeed a blob.
108
109         It is legit to call set multiple times without unsetting; set
110         overlays with the named root; unset needs only to be called to
111         return to the top level.
112 */
113 bool xapp::Jhash::Set_blob( const char* name ) {
114         void*   bst;                                            // blob symbol table
115
116         if( master_st == NULL ) {                       // must capture master
117                 master_st = st;
118         }
119
120         if( (bst = jw_blob( st, name )) != NULL ) {
121                 st = bst;
122                 return true;
123         }
124
125         return false;
126 }
127
128 /*
129         Return the suss root (blob root) to the root of the symtab.
130 */
131 void xapp::Jhash::Unset_blob( ) {
132         if( master_st != NULL ) {
133                 st = master_st;
134         }
135 }
136
137 // ---------------- debugging and sanity checks ---------------------------------------
138 /*
139         Returns true if there were parse errors which resulted in an empty
140         or non-existant hash.
141
142         Right now we don't have much to work with other than checking for a
143         nil table.
144 */
145 bool xapp::Jhash::Parse_errors( ) {
146         return st == NULL;
147 }
148
149 /*
150         Dump the selected blob as much as we can.
151 */
152 void xapp::Jhash::Dump() {
153         jw_dump( st );
154 }
155
156 // ---------------- type testing -----------------------------------------
157
158 /*
159         These funcitons return true if the named object in the current blob
160         is the indicated type
161 */
162 bool xapp::Jhash::Is_value( const char* name ) {
163         return jw_is_value( st, name ) == 1;
164 }
165
166 bool xapp::Jhash::Is_bool( const char* name ) {
167         return jw_is_bool( st, name ) == 1;
168 }
169
170 bool xapp::Jhash::Is_null( const char* name ) {
171         return jw_is_null( st, name ) == 1;
172 }
173
174 bool xapp::Jhash::Is_string( const char* name ) {
175         return jw_is_string( st, name ) == 1;
176 }
177
178 /*
179         These functions return true if the indicated element in the array
180         <name> is the indicated type.
181 */
182 bool xapp::Jhash::Is_string_ele( const char* name, int eidx ) {
183         return jw_is_string_ele( st, name, eidx ) == 1;
184 }
185
186 bool xapp::Jhash::Is_value_ele( const char* name, int eidx ) {
187         return jw_is_value_ele( st, name, eidx ) == 1;
188 }
189
190 bool xapp::Jhash::Is_bool_ele( const char* name, int eidx ) {
191         return jw_is_bool_ele( st, name, eidx ) == 1;
192 }
193
194 bool xapp::Jhash::Is_null_ele( const char* name, int eidx ) {
195         return jw_is_null_ele( st, name, eidx ) == 1;
196 }
197
198
199 // ---------------- presence ------------------------------------------------
200 /*
201         Returns true if the named element is in the hash.
202 */
203 bool xapp::Jhash::Exists( const char* name ) {
204         return jw_exists( st, name ) == 1;
205 }
206
207 /*
208         Returns true if the named element is not in the hash.
209 */
210 bool xapp::Jhash::Is_missing( const char* name ) {
211         return jw_missing( st, name ) == 1;
212 }
213
214 // ---------------- value sussing ----------------------------------------
215
216 /*
217         Returns the boolean value for the object if it is a bool; false otherwise.
218
219         Symtab saves bool values as 1 for true and doesn't provide a bool fetch
220         function. So, fetch the value and return true if it is 1.
221 */
222 bool xapp::Jhash::Bool( const char* name ) {
223         int v;
224         v = (int) jw_value( st, name );
225         return v == 1;
226 }
227
228 /*
229         Returns a C++ string to the named object; If the element is not
230         in the hash an empty string is returned.
231 */
232 std::string xapp::Jhash::String( const char* name ) {
233         std::string rv = "";
234         char*   hashv;
235
236         if( (hashv = jw_string( st, name )) != NULL ) {
237                 rv = std::string( hashv );
238         }
239
240         return rv;
241 }
242
243
244 /*
245         Returns the value assocated with the named object; If the element is not
246         in the hash 0 is returned.
247 */
248 double xapp::Jhash::Value( const char* name ) {
249         return jw_value( st, name );
250 }
251
252 // ------ array related things --------------------------------------------
253
254 /*
255         Return the length of the named array, or -1 if it doesn't exist.
256 */
257 int xapp::Jhash::Array_len( const char* name ) {
258         return jw_array_len( st, name );
259 }
260
261
262 /*
263         Sets the blob in the array <name>[eidx] to the current reference blob.
264 */
265 bool xapp::Jhash::Set_blob_ele( const char* name, int eidx ) {
266         void*   bst;
267
268         if( (bst = jw_obj_ele( st, name, eidx )) != NULL ) {
269                 if( master_st == NULL ) {                       // must capture master
270                         master_st = st;
271                 }
272
273                 st = bst;
274                 return true;
275         }
276
277         return false;
278 }
279 /*
280         Return the string at index eidx in the array <name>.
281 */
282 std::string xapp::Jhash::String_ele( const char* name, int eidx ) {
283         std::string rv = "";
284         char*   hashv;
285
286         if( (hashv = jw_string_ele( st, name, eidx )) != NULL ) {
287                 rv = std::string( hashv );
288         }
289
290         return rv;
291 }
292
293 /*
294         Return the value at index eidx in the array <name>.
295 */
296 double xapp::Jhash::Value_ele( const char* name, int eidx ) {
297         return jw_value_ele( st, name, eidx );
298 }
299
300 /*
301         Return the bool value at index eidx in the array <name>.
302 */
303 bool xapp::Jhash::Bool_ele( const char* name, int eidx ) {
304         return jw_bool_ele( st, name, eidx ) == 1;
305 }
306
307
308
309 } // namespace