diff --git a/cwObject.cpp b/cwObject.cpp index 6ab908d..40d5f1b 100644 --- a/cwObject.cpp +++ b/cwObject.cpp @@ -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, "", 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, "", 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; } diff --git a/cwObject.h b/cwObject.h index 4fd2ffa..ac81967 100644 --- a/cwObject.h +++ b/cwObject.h @@ -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)...); // ... recurse + rc = _getv(flags, std::forward(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; diff --git a/cwObjectTemplate.h b/cwObjectTemplate.h index 9d4f8bb..b78ccd9 100644 --- a/cwObjectTemplate.h +++ b/cwObjectTemplate.h @@ -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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( object_t* obj, const char* value ) @@ -136,7 +101,23 @@ namespace cw // cast 'const char*' to 'char*' return _objSetLeafValue(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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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 >