--- /dev/null
+// 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;
+}
+