Add json support
[ric-plt/xapp-frame-cpp.git] / src / json / jhash.cpp
diff --git a/src/json/jhash.cpp b/src/json/jhash.cpp
new file mode 100644 (file)
index 0000000..14a0486
--- /dev/null
@@ -0,0 +1,283 @@
+// vi: ts=4 sw=4 noet:
+/*
+==================================================================================
+       Copyright (c) 2020 Nokia
+       Copyright (c) 2020 AT&T Intellectual Property.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================================
+*/
+
+/*
+       Mnemonic:       jhash.cpp
+       Abstract:       This class provides the ability to parse a json string into
+                               a hashtable, and exposes various functions that can be used
+                               to read the data from the hash.
+
+       Date:           26 June 2020
+       Author:         E. Scott Daniels
+*/
+
+
+#include <string>
+
+#include "jwrapper.h"
+#include "jhash.hpp"
+
+// ------------------------------------------------------------------------
+
+
+
+// ----------- construction/destruction housekeeping things -------------------
+/*
+       Accept a string that contains valid json. Causes it to be parsed
+       after which the functions provided by the class can be used to
+       suss out the values.
+*/
+Jhash::Jhash( const char* jbuf ) :
+       st( jw_new( jbuf ) ),
+       master_st( NULL )
+{ /* empty body */ }
+
+//Jhash::Jhash( Jhash&& soi );                                         // mover
+//Jhash::Jhash& operator=( Jhash&& soi );                      // move operator
+
+/*
+       Blow it away.
+*/
+Jhash::~Jhash() {
+       if( master_st != NULL ) {               // revert blob set if needed
+               st = master_st;
+       }
+
+       jw_nuke( st );
+       st = NULL;
+       master_st = NULL;
+}
+
+
+// ------------ public API ---------------------------------------------------
+
+// IMPORTANT: all underlying jwrapper functions check for nil st and name pointers
+//                             so that is NOT needed in this code.
+
+
+// --- root control ----------------------------------------------------------
+/*
+       Sets the "root" to the named blob. Until unset, all subsequent
+       calls to Jhash functions (e.g. Is_missing()) will use this for the
+       look up. Returns true if name exists and was indeed a blob.
+
+       It is legit to call set multiple times without unsetting; set
+       overlays with the named root; unset needs only to be called to
+       return to the top level.
+*/
+bool Jhash::Set_blob( const char* name ) {
+       void*   bst;                                            // blob symbol table
+
+       if( master_st == NULL ) {                       // must capture master
+               master_st == st;
+       }
+
+       if( (bst = jw_blob( st, name )) != NULL ) {
+               st = bst;
+               return true;
+       }
+
+       return false;
+}
+
+/*
+       Return the suss root (blob root) to the root of the symtab.
+*/
+void Jhash::Unset_blob( ) {
+       if( master_st != NULL ) {
+               st = master_st;
+       }
+/*
+ else {
+fprintf( stderr, "bad unset pointer%p  %p\n", master_st, st );
+}
+*/
+}
+
+// ---------------- debugging and sanity checks ---------------------------------------
+/*
+       Returns true if there were parse errors which resulted in an empty
+       or non-existant hash.
+
+       Right now we don't have much to work with other than checking for a
+       nil table.
+*/
+bool Jhash::Parse_errors( ) {
+       return st == NULL;
+}
+
+/*
+       Dump the selected blob as much as we can.
+*/
+void Jhash::Dump() {
+       jw_dump( st );
+}
+
+// ---------------- type testing -----------------------------------------
+
+/*
+       These funcitons return true if the named object in the current blob
+       is the indicated type
+*/
+bool Jhash::Is_value( const char* name ) {
+       return jw_is_value( st, name ) == 1;
+}
+
+bool Jhash::Is_bool( const char* name ) {
+       return jw_is_bool( st, name ) == 1;
+}
+
+bool Jhash::Is_null( const char* name ) {
+       return jw_is_null( st, name ) == 1;
+}
+
+bool Jhash::Is_string( const char* name ) {
+       return jw_is_string( st, name ) == 1;
+}
+
+/*
+       These functions return true if the indicated element in the array
+       <name> is the indicated type.
+*/
+bool Jhash::Is_string_ele( const char* name, int eidx ) {
+       return jw_is_string_ele( st, name, eidx ) == 1;
+}
+
+bool Jhash::Is_value_ele( const char* name, int eidx ) {
+       return jw_is_value_ele( st, name, eidx ) == 1;
+}
+
+bool Jhash::Is_bool_ele( const char* name, int eidx ) {
+       return jw_is_bool_ele( st, name, eidx ) == 1;
+}
+
+bool Jhash::Is_null_ele( const char* name, int eidx ) {
+       return jw_is_null_ele( st, name, eidx ) == 1;
+}
+
+
+// ---------------- presence ------------------------------------------------
+/*
+       Returns true if the named element is in the hash.
+*/
+bool Jhash::Exists( const char* name ) {
+       return jw_exists( st, name ) == 1;
+}
+
+/*
+       Returns true if the named element is not in the hash.
+*/
+bool Jhash::Is_missing( const char* name ) {
+       return jw_missing( st, name ) == 1;
+}
+
+// ---------------- value sussing ----------------------------------------
+
+/*
+       Returns the boolean value for the object if it is a bool; false otherwise.
+
+       Symtab saves bool values as 1 for true and doesn't provide a bool fetch
+       function. So, fetch the value and return true if it is 1.
+*/
+bool Jhash::Bool( const char* name ) {
+       int v;
+       v = (int) jw_value( st, name );
+       return v == 1;
+}
+
+/*
+       Returns a C++ string to the named object; If the element is not
+       in the hash an empty string is returned.
+*/
+std::string Jhash::String( const char* name ) {
+       std::string rv = "";
+       char*   hashv;
+
+       if( (hashv = jw_string( st, name )) != NULL ) {
+               rv = std::string( hashv );
+       }
+
+       return rv;
+}
+
+
+/*
+       Returns the value assocated with the named object; If the element is not
+       in the hash 0 is returned.
+*/
+double Jhash::Value( const char* name ) {
+       return jw_value( st, name );
+}
+
+// ------ array related things --------------------------------------------
+
+/*
+       Return the length of the named array, or -1 if it doesn't exist.
+*/
+int Jhash::Array_len( const char* name ) {
+       return jw_array_len( st, name );
+}
+
+
+/*
+       Sets the blob in the array <name>[eidx] to the current reference blob.
+*/
+bool Jhash::Set_blob_ele( const char* name, int eidx ) {
+       void*   bst;
+
+       if( (bst = jw_obj_ele( st, name, eidx )) != NULL ) {
+               if( master_st == NULL ) {                       // must capture master
+                       master_st = st;
+               }
+
+               st = bst;
+               return true;
+       }
+
+       return false;
+}
+/*
+       Return the string at index eidx in the array <name>.
+*/
+std::string Jhash::String_ele( const char* name, int eidx ) {
+       std::string rv = "";
+       char*   hashv;
+
+       if( (hashv = jw_string_ele( st, name, eidx )) != NULL ) {
+               rv = std::string( hashv );
+       }
+
+       return rv;
+}
+
+/*
+       Return the value at index eidx in the array <name>.
+*/
+double Jhash::Value_ele( const char* name, int eidx ) {
+       return jw_value_ele( st, name, eidx );
+}
+
+/*
+       Return the bool value at index eidx in the array <name>.
+*/
+bool Jhash::Bool_ele( const char* name, int eidx ) {
+       return jw_bool_ele( st, name, eidx ) == 1;
+}
+