Add json support
[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
39
40
41 // ----------- construction/destruction housekeeping things -------------------
42 /*
43         Accept a string that contains valid json. Causes it to be parsed
44         after which the functions provided by the class can be used to
45         suss out the values.
46 */
47 Jhash::Jhash( const char* jbuf ) :
48         st( jw_new( jbuf ) ),
49         master_st( NULL )
50 { /* empty body */ }
51
52 //Jhash::Jhash( Jhash&& soi );                                          // mover
53 //Jhash::Jhash& operator=( Jhash&& soi );                       // move operator
54
55 /*
56         Blow it away.
57 */
58 Jhash::~Jhash() {
59         if( master_st != NULL ) {               // revert blob set if needed
60                 st = master_st;
61         }
62
63         jw_nuke( st );
64         st = NULL;
65         master_st = NULL;
66 }
67
68
69 // ------------ public API ---------------------------------------------------
70
71 // IMPORTANT: all underlying jwrapper functions check for nil st and name pointers
72 //                              so that is NOT needed in this code.
73
74
75 // --- root control ----------------------------------------------------------
76 /*
77         Sets the "root" to the named blob. Until unset, all subsequent
78         calls to Jhash functions (e.g. Is_missing()) will use this for the
79         look up. Returns true if name exists and was indeed a blob.
80
81         It is legit to call set multiple times without unsetting; set
82         overlays with the named root; unset needs only to be called to
83         return to the top level.
84 */
85 bool Jhash::Set_blob( const char* name ) {
86         void*   bst;                                            // blob symbol table
87
88         if( master_st == NULL ) {                       // must capture master
89                 master_st == st;
90         }
91
92         if( (bst = jw_blob( st, name )) != NULL ) {
93                 st = bst;
94                 return true;
95         }
96
97         return false;
98 }
99
100 /*
101         Return the suss root (blob root) to the root of the symtab.
102 */
103 void Jhash::Unset_blob( ) {
104         if( master_st != NULL ) {
105                 st = master_st;
106         }
107 /*
108  else {
109 fprintf( stderr, "bad unset pointer%p  %p\n", master_st, st );
110 }
111 */
112 }
113
114 // ---------------- debugging and sanity checks ---------------------------------------
115 /*
116         Returns true if there were parse errors which resulted in an empty
117         or non-existant hash.
118
119         Right now we don't have much to work with other than checking for a
120         nil table.
121 */
122 bool Jhash::Parse_errors( ) {
123         return st == NULL;
124 }
125
126 /*
127         Dump the selected blob as much as we can.
128 */
129 void Jhash::Dump() {
130         jw_dump( st );
131 }
132
133 // ---------------- type testing -----------------------------------------
134
135 /*
136         These funcitons return true if the named object in the current blob
137         is the indicated type
138 */
139 bool Jhash::Is_value( const char* name ) {
140         return jw_is_value( st, name ) == 1;
141 }
142
143 bool Jhash::Is_bool( const char* name ) {
144         return jw_is_bool( st, name ) == 1;
145 }
146
147 bool Jhash::Is_null( const char* name ) {
148         return jw_is_null( st, name ) == 1;
149 }
150
151 bool Jhash::Is_string( const char* name ) {
152         return jw_is_string( st, name ) == 1;
153 }
154
155 /*
156         These functions return true if the indicated element in the array
157         <name> is the indicated type.
158 */
159 bool Jhash::Is_string_ele( const char* name, int eidx ) {
160         return jw_is_string_ele( st, name, eidx ) == 1;
161 }
162
163 bool Jhash::Is_value_ele( const char* name, int eidx ) {
164         return jw_is_value_ele( st, name, eidx ) == 1;
165 }
166
167 bool Jhash::Is_bool_ele( const char* name, int eidx ) {
168         return jw_is_bool_ele( st, name, eidx ) == 1;
169 }
170
171 bool Jhash::Is_null_ele( const char* name, int eidx ) {
172         return jw_is_null_ele( st, name, eidx ) == 1;
173 }
174
175
176 // ---------------- presence ------------------------------------------------
177 /*
178         Returns true if the named element is in the hash.
179 */
180 bool Jhash::Exists( const char* name ) {
181         return jw_exists( st, name ) == 1;
182 }
183
184 /*
185         Returns true if the named element is not in the hash.
186 */
187 bool Jhash::Is_missing( const char* name ) {
188         return jw_missing( st, name ) == 1;
189 }
190
191 // ---------------- value sussing ----------------------------------------
192
193 /*
194         Returns the boolean value for the object if it is a bool; false otherwise.
195
196         Symtab saves bool values as 1 for true and doesn't provide a bool fetch
197         function. So, fetch the value and return true if it is 1.
198 */
199 bool Jhash::Bool( const char* name ) {
200         int v;
201         v = (int) jw_value( st, name );
202         return v == 1;
203 }
204
205 /*
206         Returns a C++ string to the named object; If the element is not
207         in the hash an empty string is returned.
208 */
209 std::string Jhash::String( const char* name ) {
210         std::string rv = "";
211         char*   hashv;
212
213         if( (hashv = jw_string( st, name )) != NULL ) {
214                 rv = std::string( hashv );
215         }
216
217         return rv;
218 }
219
220
221 /*
222         Returns the value assocated with the named object; If the element is not
223         in the hash 0 is returned.
224 */
225 double Jhash::Value( const char* name ) {
226         return jw_value( st, name );
227 }
228
229 // ------ array related things --------------------------------------------
230
231 /*
232         Return the length of the named array, or -1 if it doesn't exist.
233 */
234 int Jhash::Array_len( const char* name ) {
235         return jw_array_len( st, name );
236 }
237
238
239 /*
240         Sets the blob in the array <name>[eidx] to the current reference blob.
241 */
242 bool Jhash::Set_blob_ele( const char* name, int eidx ) {
243         void*   bst;
244
245         if( (bst = jw_obj_ele( st, name, eidx )) != NULL ) {
246                 if( master_st == NULL ) {                       // must capture master
247                         master_st = st;
248                 }
249
250                 st = bst;
251                 return true;
252         }
253
254         return false;
255 }
256 /*
257         Return the string at index eidx in the array <name>.
258 */
259 std::string Jhash::String_ele( const char* name, int eidx ) {
260         std::string rv = "";
261         char*   hashv;
262
263         if( (hashv = jw_string_ele( st, name, eidx )) != NULL ) {
264                 rv = std::string( hashv );
265         }
266
267         return rv;
268 }
269
270 /*
271         Return the value at index eidx in the array <name>.
272 */
273 double Jhash::Value_ele( const char* name, int eidx ) {
274         return jw_value_ele( st, name, eidx );
275 }
276
277 /*
278         Return the bool value at index eidx in the array <name>.
279 */
280 bool Jhash::Bool_ele( const char* name, int eidx ) {
281         return jw_bool_ele( st, name, eidx ) == 1;
282 }
283