blob: 25efc4583abd9e5488ba5a34a86feac7677d3fa2 [file] [log] [blame]
// 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"
namespace xapp {
// ------------------------------------------------------------------------
// ----------- 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.
*/
xapp::Jhash::Jhash( const char* jbuf ) :
st( jw_new( jbuf ) )
{ /* empty body */ }
/*
Move constructor.
*/
Jhash::Jhash( Jhash&& soi ) :
master_st( soi.master_st ),
st( soi.st )
{
soi.st = NULL; // prevent closing of RMR stuff on soi destroy
soi.master_st = NULL;
}
/*
Move Operator.
*/
Jhash& Jhash::operator=( Jhash&& soi ) {
if( this != &soi ) { // cannot do self assignment
master_st = soi.master_st;
st = soi.st;
soi.st = NULL; // prevent closing of RMR stuff on soi destroy
soi.master_st = NULL;
}
return *this;
}
/*
Blow it away.
*/
xapp::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 xapp::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 xapp::Jhash::Unset_blob( ) {
if( master_st != NULL ) {
st = master_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.
*/
const bool xapp::Jhash::Parse_errors( ) {
return st == NULL;
}
/*
Dump the selected blob as much as we can.
*/
void xapp::Jhash::Dump() {
jw_dump( st );
}
// ---------------- type testing -----------------------------------------
/*
These funcitons return true if the named object in the current blob
is the indicated type
*/
bool xapp::Jhash::Is_value( const char* name ) {
return jw_is_value( st, name ) == 1;
}
bool xapp::Jhash::Is_bool( const char* name ) {
return jw_is_bool( st, name ) == 1;
}
bool xapp::Jhash::Is_null( const char* name ) {
return jw_is_null( st, name ) == 1;
}
bool xapp::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 xapp::Jhash::Is_string_ele( const char* name, int eidx ) {
return jw_is_string_ele( st, name, eidx ) == 1;
}
bool xapp::Jhash::Is_value_ele( const char* name, int eidx ) {
return jw_is_value_ele( st, name, eidx ) == 1;
}
bool xapp::Jhash::Is_bool_ele( const char* name, int eidx ) {
return jw_is_bool_ele( st, name, eidx ) == 1;
}
bool xapp::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 xapp::Jhash::Exists( const char* name ) {
return jw_exists( st, name ) == 1;
}
/*
Returns true if the named element is not in the hash.
*/
bool xapp::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 xapp::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 xapp::Jhash::String( const char* name ) {
std::string rv = "";
const 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 xapp::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 xapp::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 xapp::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 xapp::Jhash::String_ele( const char* name, int eidx ) {
std::string rv = "";
const 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 xapp::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 xapp::Jhash::Bool_ele( const char* name, int eidx ) {
return jw_bool_ele( st, name, eidx ) == 1;
}
} // namespace