cwObject.h/cpp,cwObjectTemplate.h : Added set(),set_value(), objType_t.free_value(), and _objCallSetLeafValue().

Changed default behavior of get() functions to be non-recursive.
This commit is contained in:
kevin 2021-11-03 10:57:00 -04:00
parent 3d56bb70c8
commit 5ab42df103
3 changed files with 168 additions and 107 deletions

View File

@ -57,13 +57,21 @@ namespace cw
void _objTypeFree( object_t* o )
{ mem::release(o); }
{
o->type->free_value(o);
mem::release(o);
}
void _objTypeFreeString( object_t* o )
void _objTypeFreeValue( object_t* o )
{}
void _objTypeFreeValueString( object_t* o )
{
mem::release( o->u.str );
_objTypeFree(o);
}
const char* _objTypeIdToLabel( objTypeId_t tid );
@ -346,28 +354,28 @@ namespace cw
objType_t _objTypeArray[] =
{
{ kNullTId, "null", 0, _objTypeFree, _objTypeValueFromNonValue, _objTypePrintNull, _objTypeToStringNull, _objTypeDuplNull },
{ kErrorTId, "error", 0, _objTypeFree, _objTypeValueFromNonValue, _objTypePrintError, _objTypeToStringError, _objTypeDuplError },
{ kCharTId, "char", 0, _objTypeFree, _objTypeValueFromChar, _objTypePrintChar, _objTypeToStringChar, _objTypeDuplChar },
{ kInt8TId, "int8", 0, _objTypeFree, _objTypeValueFromInt8, _objTypePrintInt8, _objTypeToStringInt8, _objTypeDuplInt8 },
{ kUInt8TId, "uint8", 0, _objTypeFree, _objTypeValueFromUInt8, _objTypePrintUInt8, _objTypeToStringUInt8, _objTypeDuplUInt8 },
{ kInt16TId, "int16", 0, _objTypeFree, _objTypeValueFromInt16, _objTypePrintInt16, _objTypeToStringInt16, _objTypeDuplInt16 },
{ kUInt16TId, "uint16", 0, _objTypeFree, _objTypeValueFromUInt16, _objTypePrintUInt16, _objTypeToStringUInt16, _objTypeDuplUInt16 },
{ kInt32TId, "int32", 0, _objTypeFree, _objTypeValueFromInt32, _objTypePrintInt32, _objTypeToStringInt32, _objTypeDuplInt32 },
{ kUInt32TId, "uint32", 0, _objTypeFree, _objTypeValueFromUInt32, _objTypePrintUInt32, _objTypeToStringUInt32, _objTypeDuplUInt32 },
{ kInt64TId, "int64", 0, _objTypeFree, _objTypeValueFromInt64, _objTypePrintInt64, _objTypeToStringInt64, _objTypeDuplInt64 },
{ kUInt64TId, "uint64", 0, _objTypeFree, _objTypeValueFromUInt64, _objTypePrintUInt64, _objTypeToStringUInt64, _objTypeDuplUInt64 },
{ kBoolTId, "bool", 0, _objTypeFree, _objTypeValueFromBool, _objTypePrintBool, _objTypeToStringBool, _objTypeDuplBool },
{ kFloatTId, "float", 0, _objTypeFree, _objTypeValueFromFloat, _objTypePrintFloat, _objTypeToStringFloat, _objTypeDuplFloat },
{ kDoubleTId, "double", 0, _objTypeFree, _objTypeValueFromDouble, _objTypePrintDouble, _objTypeToStringDouble, _objTypeDuplDouble },
{ kStringTId, "string", 0, _objTypeFreeString, _objTypeValueFromString, _objTypePrintString, _objTypeToStringString, _objTypeDuplString },
{ kCStringTId, "cstring", 0, _objTypeFreeString, _objTypeValueFromCString, _objTypePrintString, _objTypeToStringString, _objTypeDuplCString },
{ kVectTId, "vect", 0, _objTypeFree, _objTypeValueFromVect, _objTypePrintVect, _objTypeToStringVect, _objTypeDuplVect },
{ kPairTId, "pair", kContainerFl | kValueContainerFl, _objTypeFree, _objTypeValueFromNonValue, _objTypePrintPair, _objTypeToStringPair, _objTypeDuplPair },
{ kListTId, "list", kContainerFl | kValueContainerFl, _objTypeFree, _objTypeValueFromNonValue, _objTypePrintList, _objTypeToStringList, _objTypeDuplList },
{ kDictTId, "dict", kContainerFl, _objTypeFree, _objTypeValueFromNonValue, _objTypePrintDict, _objTypeToStringDict, _objTypeDuplDict },
{ kRootTId, "root", kContainerFl | kValueContainerFl, _objTypeFree, _objTypeValueFromNonValue, _objTypePrintRoot, _objTypeToStringRoot, _objTypeDuplRoot },
{ kInvalidTId, "<invalid>", 0, nullptr, nullptr, nullptr, nullptr, nullptr }
{ kNullTId, "null", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromNonValue, _objTypePrintNull, _objTypeToStringNull, _objTypeDuplNull },
{ kErrorTId, "error", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromNonValue, _objTypePrintError, _objTypeToStringError, _objTypeDuplError },
{ kCharTId, "char", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromChar, _objTypePrintChar, _objTypeToStringChar, _objTypeDuplChar },
{ kInt8TId, "int8", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromInt8, _objTypePrintInt8, _objTypeToStringInt8, _objTypeDuplInt8 },
{ kUInt8TId, "uint8", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromUInt8, _objTypePrintUInt8, _objTypeToStringUInt8, _objTypeDuplUInt8 },
{ kInt16TId, "int16", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromInt16, _objTypePrintInt16, _objTypeToStringInt16, _objTypeDuplInt16 },
{ kUInt16TId, "uint16", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromUInt16, _objTypePrintUInt16, _objTypeToStringUInt16, _objTypeDuplUInt16 },
{ kInt32TId, "int32", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromInt32, _objTypePrintInt32, _objTypeToStringInt32, _objTypeDuplInt32 },
{ kUInt32TId, "uint32", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromUInt32, _objTypePrintUInt32, _objTypeToStringUInt32, _objTypeDuplUInt32 },
{ kInt64TId, "int64", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromInt64, _objTypePrintInt64, _objTypeToStringInt64, _objTypeDuplInt64 },
{ kUInt64TId, "uint64", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromUInt64, _objTypePrintUInt64, _objTypeToStringUInt64, _objTypeDuplUInt64 },
{ kBoolTId, "bool", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromBool, _objTypePrintBool, _objTypeToStringBool, _objTypeDuplBool },
{ kFloatTId, "float", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromFloat, _objTypePrintFloat, _objTypeToStringFloat, _objTypeDuplFloat },
{ kDoubleTId, "double", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromDouble, _objTypePrintDouble, _objTypeToStringDouble, _objTypeDuplDouble },
{ kStringTId, "string", 0, _objTypeFree, _objTypeFreeValueString, _objTypeValueFromString, _objTypePrintString, _objTypeToStringString, _objTypeDuplString },
{ kCStringTId, "cstring", 0, _objTypeFree, _objTypeFreeValueString, _objTypeValueFromCString, _objTypePrintString, _objTypeToStringString, _objTypeDuplCString },
{ kVectTId, "vect", 0, _objTypeFree, _objTypeFreeValue, _objTypeValueFromVect, _objTypePrintVect, _objTypeToStringVect, _objTypeDuplVect },
{ kPairTId, "pair", kContainerFl | kValueContainerFl, _objTypeFree, _objTypeFreeValue, _objTypeValueFromNonValue, _objTypePrintPair, _objTypeToStringPair, _objTypeDuplPair },
{ kListTId, "list", kContainerFl | kValueContainerFl, _objTypeFree, _objTypeFreeValue, _objTypeValueFromNonValue, _objTypePrintList, _objTypeToStringList, _objTypeDuplList },
{ kDictTId, "dict", kContainerFl, _objTypeFree, _objTypeFreeValue, _objTypeValueFromNonValue, _objTypePrintDict, _objTypeToStringDict, _objTypeDuplDict },
{ kRootTId, "root", kContainerFl | kValueContainerFl, _objTypeFree, _objTypeFreeValue, _objTypeValueFromNonValue, _objTypePrintRoot, _objTypeToStringRoot, _objTypeDuplRoot },
{ kInvalidTId, "<invalid>", 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }
};
@ -470,6 +478,15 @@ namespace cw
return nullptr;
}
template< typename T >
rc_t _objSetValue( object_t* obj, const T& v )
{
cw::rc_t rc = kOkRC;
if(_objCallSetLeafValue( obj, v ) == nullptr)
rc = cwLogError(kOpFailRC,"Object value assignment failed.");
return rc;
}
}
@ -558,6 +575,25 @@ cw::rc_t cw::object_t::value( bool& v ) const { return type->value(this,kBoo
cw::rc_t cw::object_t::value( char*& v ) const { return type->value(this,kStringTId,&v); }
cw::rc_t cw::object_t::value( const char*& v ) const { return type->value(this,kCStringTId,&v); }
cw::rc_t cw::object_t::set_value( char v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( int8_t v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( uint8_t v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( int16_t v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( uint16_t v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( int32_t v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( uint32_t v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( int64_t v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( uint64_t v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( float v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( double v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( bool v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( char* v ) { return _objSetValue(this,v); }
cw::rc_t cw::object_t::set_value( const char* v ) { return _objSetValue(this,v); }
const char* cw::object_t::pair_label() const
{
cwAssert( is_pair() );
@ -593,7 +629,7 @@ const struct cw::object_str* cw::object_t::find( const char* label, unsigned fla
return o->pair_value();
const object_t* ch;
if( cwIsNotFlag(flags,kNoRecurseFl) )
if( cwIsFlag(flags,kRecurseFl) )
if((ch = o->find(label)) != nullptr )
return ch;
}

View File

@ -39,13 +39,17 @@ namespace cw
enum
{
kValueContainerFl = 0x01, // root,pair, or list are the only legal value containers
kContainerFl = 0x02,
// Value containers children are leaf-nodes: root,pair, or list are the only legal value containers.
// Nnote that a dictionary is not a value container because it's children are pairs.
kValueContainerFl = 0x01,
// This node contains other nodes
kContainerFl = 0x02,
};
enum
{
kNoRecurseFl = 0x01,
kRecurseFl = 0x01,
kOptionalFl = 0x02
};
@ -64,10 +68,21 @@ namespace cw
const char* label;
unsigned flags;
// Deallocate the the object body and value.
void (*free)( struct object_str* o );
// Deallocate the object value but not the object body
void (*free_value)( struct object_str* o );
rc_t (*value)( const struct object_str* o, unsigned tid, void* dst );
// Print the object.
void (*print)( const struct object_str* o, print_ctx_t& c );
// Convert the object to a string and return the length of the string.
unsigned( *to_string)( const struct object_str* o, char* buf, unsigned bufByteN );
// Duplicate 'src'.
struct object_str* (*duplicate)( const struct object_str* src, struct object_str* parent );
} objType_t;
@ -141,7 +156,25 @@ namespace cw
rc_t value( char*& v ) const;
rc_t value( const char*& v ) const;
rc_t value( const struct object_str*& v) const {v=this; return kOkRC; }
// Note that these setters will change the type of the object to match the value 'v'.
// They do not convert 'v' to the current type of the object.
rc_t set_value( char v );
rc_t set_value( int8_t v );
rc_t set_value( uint8_t v );
rc_t set_value( int16_t v );
rc_t set_value( uint16_t v );
rc_t set_value( int32_t v );
rc_t set_value( uint32_t v );
rc_t set_value( int64_t v );
rc_t set_value( uint64_t v );
rc_t set_value( float v );
rc_t set_value( double v );
rc_t set_value( bool v );
rc_t set_value( char* v );
rc_t set_value( const char* v );
const char* pair_label() const;
const struct object_str* pair_value() const;
@ -149,17 +182,17 @@ namespace cw
// Search for the pair label 'label'.
// Return a pointer to the pair value associated with a given pair label.
// Set flags to kNoRecurseFl to not recurse into the object in search of the label.
// Set flags to kRecurseFl to recurse into the object in search of the label.
const struct object_str* find( const char* label, unsigned flags=0 ) const;
struct object_str* find( const char* label, unsigned flags=0 );
const struct object_str* find_child( const char* label ) const { return find(label,kNoRecurseFl); }
struct object_str* find_child( const char* label ) { return find(label,kNoRecurseFl); }
const struct object_str* find_child( const char* label ) const { return find(label); }
struct object_str* find_child( const char* label ) { return find(label); }
const struct object_str* child_ele( unsigned idx ) const;
struct object_str* child_ele( unsigned idx );
// Set flag 'kNoRecurseFl' to not recurse into the object in search of the value.
// Set flag 'kRecurseFl' to recurse into the object in search of the value.
// Set flag 'kOptionalFl' if the label is optional and may not exist.
template< typename T >
rc_t get( const char* label, T& v, unsigned flags=0 ) const
@ -186,7 +219,7 @@ namespace cw
// if no error occurred ....
if( rc == kOkRC || (rc == kLabelNotFoundRC && cwIsFlag(flags,kOptionalFl)))
rc = _getv(flags, std::forward<ARGS>(args)...); // ... recurse
rc = _getv(flags, std::forward<ARGS>(args)...); // ... recurse to find next label/value pair
else
rc = cwLogError(rc,"Object parse failed for the pair label:'%s'.",cwStringNullGuard(label));
@ -208,6 +241,17 @@ namespace cw
{ return newPairObject(label, v, this); }
template< typename T>
rc_t set( const char* label, const T& value )
{
struct object_str* pair_value;
if((pair_value = find_child(label)) == nullptr )
return cwLogError(kInvalidIdRC,"Set failed the object dictionary label '%s' could not be found.",label);
return pair_value->set_value( value );
}
// convert this object to a string
unsigned to_string( char* buf, unsigned bufByteN ) const;

View File

@ -12,123 +12,88 @@ namespace cw
template< typename T >
object_t* _objSetLeafValue( object_t* obj, T value )
{
cwLogError(kObjAllocFailRC,"Unhandled object type at leaf node.");
return NULL;
cwLogError(kAssertFailRC,"Unhandled object type at leaf node.");
return nullptr;
}
template<> object_t* _objSetLeafValue<int8_t>( object_t* obj, int8_t value )
{
if( obj != NULL )
{
obj->u.i8 = value;
obj->type = _objIdToType(kInt8TId);
}
obj->u.i8 = value;
obj->type = _objIdToType(kInt8TId);
return obj;
}
template<> object_t* _objSetLeafValue<uint8_t>( object_t* obj, uint8_t value )
{
if( obj != NULL )
{
obj->u.u8 = value;
obj->type = _objIdToType(kUInt8TId);
}
obj->u.u8 = value;
obj->type = _objIdToType(kUInt8TId);
return obj;
}
template<> object_t* _objSetLeafValue<int16_t>( object_t* obj, int16_t value )
{
if( obj != NULL )
{
obj->u.i16 = value;
obj->type = _objIdToType(kInt16TId);
}
obj->u.i16 = value;
obj->type = _objIdToType(kInt16TId);
return obj;
}
template<> object_t* _objSetLeafValue<uint16_t>( object_t* obj, uint16_t value )
{
if( obj != NULL )
{
obj->u.u16 = value;
obj->type = _objIdToType(kUInt16TId);
}
obj->u.u16 = value;
obj->type = _objIdToType(kUInt16TId);
return obj;
}
template<> object_t* _objSetLeafValue<int32_t>( object_t* obj, int32_t value )
{
if( obj != NULL )
{
obj->u.i32 = value;
obj->type = _objIdToType(kInt32TId);
}
obj->u.i32 = value;
obj->type = _objIdToType(kInt32TId);
return obj;
}
template<> object_t* _objSetLeafValue<uint32_t>( object_t* obj, uint32_t value )
{
if( obj != NULL )
{
obj->u.u32 = value;
obj->type = _objIdToType(kUInt32TId);
}
obj->u.u32 = value;
obj->type = _objIdToType(kUInt32TId);
return obj;
}
template<> object_t* _objSetLeafValue<int64_t>( object_t* obj, int64_t value )
{
if( obj != NULL )
{
obj->u.i64 = value;
obj->type = _objIdToType(kInt64TId);
}
obj->u.i64 = value;
obj->type = _objIdToType(kInt64TId);
return obj;
}
template<> object_t* _objSetLeafValue<uint64_t>( object_t* obj, uint64_t value )
{
if( obj != NULL )
{
obj->u.u64 = value;
obj->type = _objIdToType(kUInt64TId);
}
obj->u.u64 = value;
obj->type = _objIdToType(kUInt64TId);
return obj;
}
template<> object_t* _objSetLeafValue<double>( object_t* obj, double value )
{
if( obj != NULL )
{
obj->u.d = value;
obj->type = _objIdToType(kDoubleTId);
}
obj->u.d = value;
obj->type = _objIdToType(kDoubleTId);
return obj;
}
template<> object_t* _objSetLeafValue<bool>( object_t* obj, bool value )
{
if( obj != NULL )
{
obj->u.b = value;
obj->type = _objIdToType(kBoolTId);
}
obj->u.b = value;
obj->type = _objIdToType(kBoolTId);
return obj;
}
template<> object_t* _objSetLeafValue< char*>( object_t* obj, char* value )
{
if( obj != NULL )
{
//mem::release(obj->u.str);
obj->u.str = value == nullptr ? nullptr : mem::duplStr(value);
//obj->u.str = value;
obj->type = _objIdToType(kStringTId);
}
return obj;
return obj;
}
template<> object_t* _objSetLeafValue<const char*>( object_t* obj, const char* value )
@ -136,7 +101,23 @@ namespace cw
// cast 'const char*' to 'char*'
return _objSetLeafValue<char*>(obj,(char*)value);
}
template< typename T >
object_t* _objCallSetLeafValue( object_t* obj, const T& v )
{
if( obj != nullptr )
{
// The object value is about to be overwritten so be sure it is deallocated first.
obj->type->free_value(obj);
// Set the object value and type id.
obj = _objSetLeafValue(obj,v);
}
return obj;
}
template< typename T >
object_t*_objCreateValueNode( object_t* obj, T value, const char* msg=nullptr, unsigned flags=0 )
{
@ -145,43 +126,43 @@ namespace cw
}
template<> object_t* _objCreateValueNode<uint8_t>( object_t* parent, uint8_t value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template<> object_t* _objCreateValueNode<int8_t>( object_t* parent, int8_t value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template<> object_t* _objCreateValueNode<uint16_t>( object_t* parent, uint16_t value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template<> object_t* _objCreateValueNode<int16_t>( object_t* parent, int16_t value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template<> object_t* _objCreateValueNode<uint32_t>( object_t* parent, uint32_t value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template<> object_t* _objCreateValueNode<int32_t>( object_t* parent, int32_t value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template<> object_t* _objCreateValueNode<uint64_t>( object_t* parent, uint64_t value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template<> object_t* _objCreateValueNode<int64_t>( object_t* parent, int64_t value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template<> object_t* _objCreateValueNode<float>( object_t* parent, float value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template<> object_t* _objCreateValueNode<double>( object_t* parent, double value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template<> object_t* _objCreateValueNode< char*>( object_t* parent, char* value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template<> object_t* _objCreateValueNode<const char*>( object_t* parent, const char* value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template<> object_t* _objCreateValueNode<bool>( object_t* parent, bool value, const char* msg, unsigned flags )
{ return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }
{ return _objAppendLeftMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); }
template< typename T >