RIC:1060: Change in PTL
[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         st( jw_new( jbuf ) )
53 { /* empty body */ }
54
55
56 /*
57         Move constructor.
58 */
59 Jhash::Jhash( Jhash&& soi ) :
60         master_st( soi.master_st ),
61         st( soi.st )
62 {
63         soi.st = NULL;                                          // prevent closing of RMR stuff on soi destroy
64         soi.master_st = NULL;
65 }
66
67 /*
68         Move Operator.
69 */
70 Jhash& Jhash::operator=( Jhash&& soi ) {
71         if( this != &soi ) {                                            // cannot do self assignment
72                 master_st = soi.master_st;
73                 st = soi.st;
74
75                 soi.st = NULL;                                          // prevent closing of RMR stuff on soi destroy
76                 soi.master_st = NULL;
77         }
78
79         return *this;
80 }
81
82 /*
83         Blow it away.
84 */
85 xapp::Jhash::~Jhash() {
86         if( master_st != NULL ) {               // revert blob set if needed
87                 st = master_st;
88         }
89
90         jw_nuke( st );
91         st = NULL;
92         master_st = NULL;
93 }
94
95
96 // ------------ public API ---------------------------------------------------
97
98 // IMPORTANT: all underlying jwrapper functions check for nil st and name pointers
99 //                              so that is NOT needed in this code.
100
101
102 // --- root control ----------------------------------------------------------
103 /*
104         Sets the "root" to the named blob. Until unset, all subsequent
105         calls to Jhash functions (e.g. Is_missing()) will use this for the
106         look up. Returns true if name exists and was indeed a blob.
107
108         It is legit to call set multiple times without unsetting; set
109         overlays with the named root; unset needs only to be called to
110         return to the top level.
111 */
112 bool xapp::Jhash::Set_blob( const char* name ) {
113         void*   bst;                                            // blob symbol table
114
115         if( master_st == NULL ) {                       // must capture master
116                 master_st = st;
117         }
118
119         if( (bst = jw_blob( st, name )) != NULL ) {
120                 st = bst;
121                 return true;
122         }
123
124         return false;
125 }
126
127 /*
128         Return the suss root (blob root) to the root of the symtab.
129 */
130 void xapp::Jhash::Unset_blob( ) {
131         if( master_st != NULL ) {
132                 st = master_st;
133         }
134 }
135
136 // ---------------- debugging and sanity checks ---------------------------------------
137 /*
138         Returns true if there were parse errors which resulted in an empty
139         or non-existant hash.
140
141         Right now we don't have much to work with other than checking for a
142         nil table.
143 */
144 const bool xapp::Jhash::Parse_errors( ) {
145         return st == NULL;
146 }
147
148 /*
149         Dump the selected blob as much as we can.
150 */
151 void xapp::Jhash::Dump() {
152         jw_dump( st );
153 }
154
155 // ---------------- type testing -----------------------------------------
156
157 /*
158         These funcitons return true if the named object in the current blob
159         is the indicated type
160 */
161 bool xapp::Jhash::Is_value( const char* name ) {
162         return jw_is_value( st, name ) == 1;
163 }
164
165 bool xapp::Jhash::Is_bool( const char* name ) {
166         return jw_is_bool( st, name ) == 1;
167 }
168
169 bool xapp::Jhash::Is_null( const char* name ) {
170         return jw_is_null( st, name ) == 1;
171 }
172
173 bool xapp::Jhash::Is_string( const char* name ) {
174         return jw_is_string( st, name ) == 1;
175 }
176
177 /*
178         These functions return true if the indicated element in the array
179         <name> is the indicated type.
180 */
181 bool xapp::Jhash::Is_string_ele( const char* name, int eidx ) {
182         return jw_is_string_ele( st, name, eidx ) == 1;
183 }
184
185 bool xapp::Jhash::Is_value_ele( const char* name, int eidx ) {
186         return jw_is_value_ele( st, name, eidx ) == 1;
187 }
188
189 bool xapp::Jhash::Is_bool_ele( const char* name, int eidx ) {
190         return jw_is_bool_ele( st, name, eidx ) == 1;
191 }
192
193 bool xapp::Jhash::Is_null_ele( const char* name, int eidx ) {
194         return jw_is_null_ele( st, name, eidx ) == 1;
195 }
196
197
198 // ---------------- presence ------------------------------------------------
199 /*
200         Returns true if the named element is in the hash.
201 */
202 bool xapp::Jhash::Exists( const char* name ) {
203         return jw_exists( st, name ) == 1;
204 }
205
206 /*
207         Returns true if the named element is not in the hash.
208 */
209 bool xapp::Jhash::Is_missing( const char* name ) {
210         return jw_missing( st, name ) == 1;
211 }
212
213 // ---------------- value sussing ----------------------------------------
214
215 /*
216         Returns the boolean value for the object if it is a bool; false otherwise.
217
218         Symtab saves bool values as 1 for true and doesn't provide a bool fetch
219         function. So, fetch the value and return true if it is 1.
220 */
221 bool xapp::Jhash::Bool( const char* name ) {
222         int v;
223         v = (int) jw_value( st, name );
224
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         const 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         const 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