Add API allowing xAPPs to send alarm messages
[ric-plt/xapp-frame-cpp.git] / doc / src / user / jhash.im
1 .** vim: sw=4 ts=4 et :
2 .if false
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 .fi
20
21
22 .if false
23         This imbed file contains the portion of the document that describes the
24         json support that is provided by the framework.
25 .fi
26
27
28 &h1(Json Support)
29 The C++ xAPP framework provides a  very lightweight json parser and data
30 hash facility.
31 Briefly, a json hash (Jhash) can be established by creating an instance of
32 the Jhash object with a string of valid json.
33 The resulting object's functions can then be used to read values from the
34 resulting hash.
35
36
37 &h2(Creating The Jhash Object)
38 The Jhash object is created simply by passing a json string to the constructor.
39
40 .cc 10l
41 &ex_start
42     #include <ricxfcpp/Jhash>
43
44     std::string jstring = "{ \"tag\": \"Hello World\" }";
45     Jhash*  jh;
46
47     jh =  new Jhash( jstring.c_str() );
48 &ex_end
49 &fig_cen(The creation of the Jhash object.)
50 &space
51
52
53 Once the Jhash object has been created any of the methods described in the following
54 paragraphs can be used to retrieve the data:
55
56 &h2(Json Blobs)
57 Json objects can be nested, and the nesting is supported by this  representation.
58 The approach taken by Jhash is a "directory view" approach, where the "current directory,"
59 or current &ital(blob,) limits the scope of visible fields.
60
61 &space
62 As an example, the json contained in figure &jblob_fig, contains a "root" blob and
63 two &ital(sub-blobs) (address and lease_info).
64 &half_space
65
66 .ca start blob_ex.ca
67 &ex_start
68     {
69         "lodge_name": "Water Buffalo Lodge 714",
70         "member_count": 41,
71         "grand_poobah": "Larry K. Slate",
72         "attendance":   [ 23, 14, 41, 38, 24 ],
73         "address": {
74             "street":    "16801 Stonway Lane",
75             "suite":     null,
76             "city":      "Bedrock",
77             "post_code": "45701"
78         },
79         "lease_info": {
80             "owner":    "Stonegate Properties",
81             "amount":   216.49,
82             "due":      "monthly",
83             "contact:"  "Kyle Limestone"
84         }
85     }
86 &ex_end
87 &export_fig( jblob_fig )
88 &fig_cen(Sample json with a root and two blobs.)
89 &space
90 .ca end
91 &ifroom( 3i : blob_ex.ca )
92
93
94 Upon creation of the Jhash object, the &ital(root) fields, &cw(lodge_name,) &cw(member_count,) and
95 &cw(grand_poobah) are immediately available.
96 The fields in the &ital(sub-blobs) are available only when the correct blob is selected.
97 The code sample in figure &fig_blob_sample illustrates how  a &ital(sub-blob) is selected.
98
99 &ex_start
100     jh->Set_blob( (char *) "address" );     // select address
101     jh->Unset_blob();                       // return to root
102     jh->Set_blob( (char *) "lease_info" );  // select the lease blob
103 &ex_end
104 .sv export_fig
105 &export_fig( fig_blob_sample )
106 &fig_cen(Blob selection example.)
107 &space
108
109 Currently, the selected blob must be unset in order to select a blob at the root
110 level; unset always sets the root blob.
111 Attempting to use the &cw(Set_blob)  function will attempt to select the named blob
112 from the current blob, and not the root.
113
114 &h2(Simple Value Extraction)
115 Simple values are the expected data types &ital(string, value,) and &ital(boolean.)
116 This lightweight json parser treats all values as floating point numbers and does not
117 attempt to maintain a separate integer type.
118 A fourth type, &ital(null,) is supported to allow the user to expressly check for
119 a field which is defined but has no value; as opposed to a field that was completely
120 missing from the data.
121 The following are the prototypes for the functions which allow values to be extracted:
122
123 &half_space
124 &ex_start
125     std::string String( const char* name );
126     float Value( const char* name );
127     bool Bool( const char* name );
128 &ex_end
129 &space
130
131 Each of these functions returns the value associated with the field with the given &ital(name.)
132 If the value is missing, the following default values are returned:
133
134 &half_space
135 &indent
136 &beg_dlist( 1i Helvetica-bold : : 15,80 )
137     &di(String:) An empty string (.e.g "").
138     &di(Value:) Zero (e.g 0.0)
139     &di(bool:) false
140 &end_dlist
141 &uindent
142 &space
143
144 If the user needs to disambiguate between a missing value and the default value either the
145 &cw(Missing) or &cw(Exists) function should be used first.
146
147 &h2(Testing For Existing and Missing Fields)
148 Two functions allow the developer to determine whether or not a field is included in the
149 json.
150 Both of these functions work on the current &ital(blob,) therefore it is important to ensure
151 that the correct blob is selected before using either of these functions.
152 The prototypes for the &cw(Exists) and &cw(Missing) functions are below:
153
154 &ex_start
155     bool Exists( const char* name );
156     bool Is_missing( const char* name );
157 &ex_end
158
159 The &cw(Exists) function returns &ital(true) if the field name exists in the json and &ital(false) otherwise.
160 Conversely, the &cw(Missing) function returns &ital(true) when the field name does not exist in the json.
161
162
163 &h2(Testing Field Type)
164 The &cw(Exists) and &cw(Missing) functions might not be enough for the user code to validate
165 the data that it has.
166 To assist with this, several functions allow direct type testing on a field in the current
167 blob.
168 The following are the prototypes for these functions:
169
170 &ex_start
171     bool Is_bool( const char* name );
172     bool Is_null( const char* name );
173     bool Is_string( const char* name );
174     bool Is_value( const char* name );
175 &ex_end
176
177 &space
178 Each of these functions return &ital(true) if the field with the given name is of the type
179 being tested for.
180
181
182 &h2(Arrays)
183 Arrays are supported in the same manner as simple field values with the addition of the need
184 to supply an array index when fetching values from the object.
185 In addition, there is a &ital(length) function which can be used to determine the number
186 of elements in the named array.
187 The prototypes for the array based functions are below:
188
189 &ex_start
190     int Array_len( const char* name );
191
192     bool Is_bool_ele( const char* name, int eidx );
193     bool Is_null_ele( const char* name, int eidx );
194     bool Is_string_ele( const char* name, int eidx );
195     bool Is_value_ele( const char* name, int eidx );
196
197     bool Bool_ele( const char* name, int eidx );
198     std::string String_ele( const char* name, int eidx );
199     float Value_ele( const char* name, int eidx );
200 &ex_end
201 &space
202
203 For each of these functions the &cw(eidx) is the zero based element index which is to
204 be tested or selected.
205
206 &h3(Arrays of Blobs)
207 An array containing blobs, rather than simple field value pairs, the blob must
208 be selected prior to using it, just as a sub-blob needed to be selected.
209 The &cw(Set_blob_ele) function is used to do this and has the following prototype:
210
211 &ex_start
212     bool Set_blob_ele( const char* name, int eidx );
213 &ex_end
214 &space
215
216 As with selecting a sub-blob, an unset must be performed before selecting the next blob.
217 Figure &array_blob_code_fig illustrates how these functions can be used to read and print
218 values from the json in figure &array_blob_json_fig.
219
220
221 .cc 8l
222 &ex_start
223     "members": [
224         { "name": "Fred Flinstone", "member_num": 42 },
225         { "name": "Barney Rubble", "member_num": 48 },
226         { "name": "Larry K Slate", "member_num": 22 },
227         { "name": "Kyle Limestone", "member_num": 49 }
228     ]
229 &ex_end
230 &export_fig(array_blob_code_fig)
231 &fig_cen(Json array containing blobs.)
232 &space
233
234
235 .cc 18l
236 &ex_start
237     std::string mname;
238     float mnum;
239     int len;
240
241     len = jh->Array_len( (char *) "members" );
242     for( i = 0; i < len; i++ ) {
243         jh->Set_blob_ele( (char *) "members", i );  // select blob
244
245         mname = jh->String( (char *) "name" );      // read values
246         mnum = jh->Value( (char *) "member_num" );
247         fprintf( stdout, "%s is member %d\n", mname.c_str(), (int) mnum );
248
249         jh->Unset_blob();                           // back to root
250     }
251 &ex_end
252 &export_fig(array_blob_json_fig )
253 &fig_cen(Code to process the array of blobs.)
254 &space
255