diff --git a/cwObject.cpp b/cwObject.cpp index 6c8de5f..adc4a15 100644 --- a/cwObject.cpp +++ b/cwObject.cpp @@ -89,7 +89,14 @@ namespace cw { return cwLogError(kInvalidArgRC, "There is no conversion from '%s' to '%s'.", _objTypeIdToLabel(tid), o->type->label); } rc_t _objTypeValueFromString( const object_t* o, unsigned tid, void* dst ) - { return _objTypeValueFromNonValue(o,tid,dst); } + { + if( tid == kStringTId ) + { + *(char**)dst = o->u.str; + return kOkRC; + } + return _objTypeValueFromNonValue(o,tid,dst); + } rc_t _objTypeValueFromVect( const object_t* o, unsigned tid, void* dst ) { return _objTypeValueFromNonValue(o,tid,dst); } @@ -348,19 +355,22 @@ namespace cw { if( newNode == nullptr ) return nullptr; - - object_t* child = parent->u.children; - if( parent->u.children == nullptr ) - parent->u.children = newNode; - else + if( parent != nullptr ) { - while( child->sibling != nullptr ) - child = child->sibling; + object_t* child = parent->u.children; - child->sibling = newNode; + if( parent->u.children == nullptr ) + parent->u.children = newNode; + else + { + while( child->sibling != nullptr ) + child = child->sibling; + + child->sibling = newNode; + } } - + newNode->parent = parent; return newNode; } @@ -450,6 +460,7 @@ cw::rc_t cw::object_t::value( uint64_t& v ) const { return type->value(this,kUIn cw::rc_t cw::object_t::value( float& v ) const { return type->value(this,kFloatTId,&v); } cw::rc_t cw::object_t::value( double& v ) const { return type->value(this,kDoubleTId,&v); } 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,kStringTId,&v); } const char* cw::object_t::pair_label() const { @@ -476,7 +487,7 @@ struct cw::object_str* cw::object_t::pair_value() } -const struct cw::object_str* cw::object_t::find( const char* label, bool recurseFl ) const +const struct cw::object_str* cw::object_t::find( const char* label, unsigned flags ) const { if( is_container() ) { @@ -486,7 +497,7 @@ const struct cw::object_str* cw::object_t::find( const char* label, bool recurse return o->pair_value(); const object_t* ch; - if( recurseFl ) + if( cwIsNotFlag(flags,kNoRecurseFl) ) if((ch = o->find(label)) != nullptr ) return ch; } @@ -494,9 +505,9 @@ const struct cw::object_str* cw::object_t::find( const char* label, bool recurse return nullptr; } -struct cw::object_str* cw::object_t::find( const char* label, bool recurseFl ) +struct cw::object_str* cw::object_t::find( const char* label, unsigned flags ) { - return const_cast(((const object_t*)this)->find(label,recurseFl)); + return const_cast(((const object_t*)this)->find(label,flags)); } const struct cw::object_str* cw::object_t::list_ele( unsigned idx ) const @@ -530,7 +541,41 @@ void cw::object_t::print(const print_ctx_t* c) const type->print(this,ctx); } +cw::object_t* cw::newObject( std::uint8_t v, object_t* parent) +{ return _objCreateValueNode( parent, v ); } +cw::object_t* cw::newObject( std::int8_t v, object_t* parent) +{ return _objCreateValueNode( parent, v ); } + +cw::object_t* cw::newObject( std::uint16_t v, object_t* parent) +{ return _objCreateValueNode( parent, v ); } + +cw::object_t* cw::newObject( std::int16_t v, object_t* parent) +{ return _objCreateValueNode( parent, v ); } + +cw::object_t* cw::newObject( std::uint32_t v, object_t* parent) +{ return _objCreateValueNode( parent, v ); } + +cw::object_t* cw::newObject( std::int32_t v, object_t* parent) +{ return _objCreateValueNode( parent, v ); } + +cw::object_t* cw::newObject( std::uint64_t v, object_t* parent) +{ return _objCreateValueNode( parent, v ); } + +cw::object_t* cw::newObject( std::int64_t v, object_t* parent) +{ return _objCreateValueNode( parent, v ); } + +cw::object_t* cw::newObject( bool v, object_t* parent) +{ return _objCreateValueNode( parent, v ); } + +cw::object_t* cw::newObject( float v, object_t* parent) +{ return _objCreateValueNode( parent, v ); } + +cw::object_t* cw::newObject( double v, object_t* parent) +{ return _objCreateValueNode( parent, v ); } + +cw::object_t* cw::newObject( const char* v, object_t* parent) +{ return _objCreateValueNode( parent, v ); } cw::rc_t cw::objectFromString( const char* s, object_t*& objRef ) { @@ -557,8 +602,6 @@ cw::rc_t cw::objectFromString( const char* s, object_t*& objRef ) // main parser loop while((lexId = lex::getNextToken(lexH)) != lex::kErrorLexTId && (lexId != lex::kEofLexTId) && (rc == kOkRC)) { - - //printf("Lex:%s\n",lexIdToLabel(lexH,lexId)); switch( lexId ) { @@ -649,6 +692,15 @@ cw::rc_t cw::objectFromString( const char* s, object_t*& objRef ) } + + // if the root has only one child then make the child the root + if( root != nullptr && root->child_count() == 1 ) + { + cnp = root->u.children; + cnp->unlink(); + root->free(); + root = cnp; + } objRef = root; diff --git a/cwObject.h b/cwObject.h index 02fef46..8ba8fe4 100644 --- a/cwObject.h +++ b/cwObject.h @@ -39,7 +39,13 @@ namespace cw enum { kValueContainerFl = 0x01, // root,pair, or list are the only legal value containers - kContainerFl = 0x02 + kContainerFl = 0x02, + }; + + enum + { + kNoRecurseFl = 0x01, + kOptionalFl = 0x02 }; struct object_str; @@ -120,6 +126,7 @@ namespace cw rc_t value( float& v ) const; rc_t value( double& v ) const; rc_t value( char*& v ) const; + rc_t value( const char*& v ) const; const char* pair_label() const; @@ -127,18 +134,28 @@ namespace cw struct object_str* pair_value(); // Search for the pair label 'label'. - const struct object_str* find( const char* label, bool recurseFl=true ) const; - struct object_str* find( const char* label, bool recurseFl=true ); + // 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. + 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* list_ele( unsigned idx ) const; struct object_str* list_ele( unsigned idx ); + // Set flag 'kNoRecurseFl' to no recurse into the object in search of the value. + // Set flag 'kOptional' if the label is optional and may not exist. template< typename T > - rc_t get( const char* label, T& v ) const + rc_t get( const char* label, T& v, unsigned flags=0 ) const { const struct object_str* o; - if((o = find(label)) == NULL ) - return cwLogError(kInvalidIdRC,"The pair label '%s' could not be found.",cwStringNullGuard(label)); + if((o = find(label, flags)) == nullptr ) + { + if( cwIsNotFlag(flags, kOptionalFl) ) + return cwLogError(kInvalidIdRC,"The pair label '%s' could not be found.",cwStringNullGuard(label)); + + return kLabelNotFoundRC; + + } return o->value(v); } @@ -159,9 +176,19 @@ namespace cw } object_t; - - - + object_t* newObject( std::uint8_t v, object_t* parent=nullptr); + object_t* newObject( std::int8_t v, object_t* parent=nullptr); + object_t* newObject( std::int16_t v, object_t* parent=nullptr); + object_t* newObject( std::uint16_t v, object_t* parent=nullptr); + object_t* newObject( std::int32_t v, object_t* parent=nullptr); + object_t* newObject( std::uint32_t v, object_t* parent=nullptr); + object_t* newObject( std::int64_t v, object_t* parent=nullptr); + object_t* newObject( std::uint64_t v, object_t* parent=nullptr); + object_t* newObject( bool v, object_t* parent=nullptr); + object_t* newObject( float v, object_t* parent=nullptr); + object_t* newObject( double v, object_t* parent=nullptr); + object_t* newObject( const char* v, object_t* parent=nullptr); + rc_t objectFromString( const char* s, object_t*& objRef ); rc_t objectFromFile( const char* fn, object_t*& objRef ); void objectPrintTypes( object_t* o ); diff --git a/cwObjectTemplate.h b/cwObjectTemplate.h index 104896f..161a99f 100644 --- a/cwObjectTemplate.h +++ b/cwObjectTemplate.h @@ -4,10 +4,10 @@ namespace cw { - objType_t* _objIdToType( objTypeId_t tid ); - object_t* _objAllocate( objTypeId_t tid=kInvalidTId, object_t* parent=NULL ); - object_t* _objCreateConainerNode( lex::handle_t lexH, object_t* parent, objTypeId_t tid ); - object_t* _objAppendLeftMostNode( object_t* parent, object_t* newNode ); + objType_t* _objIdToType( objTypeId_t tid ); + object_t* _objAllocate( objTypeId_t tid=kInvalidTId, object_t* parent=NULL ); + object_t* _objCreateConainerNode( lex::handle_t lexH, object_t* parent, objTypeId_t tid ); + object_t* _objAppendLeftMostNode( object_t* parent, object_t* newNode ); template< typename T > object_t* _objSetLeafValue( object_t* obj, T value ) @@ -30,7 +30,7 @@ namespace cw if( obj != NULL ) { obj->u.i32 = value; - obj->type = _objIdToType(kInt32TId); + obj->type = _objIdToType(kInt32TId); } return obj; } @@ -39,7 +39,7 @@ namespace cw { if( obj != NULL ) { - obj->u.d = value; + obj->u.d = value; obj->type = _objIdToType(kDoubleTId); } return obj; @@ -49,7 +49,7 @@ namespace cw { if( obj != NULL ) { - obj->u.b = value; + obj->u.b = value; obj->type = _objIdToType(kBoolTId); } return obj; @@ -60,22 +60,43 @@ namespace cw if( obj != NULL ) { obj->u.str = value; - obj->type = _objIdToType(kStringTId); + obj->type = _objIdToType(kStringTId); } return obj; } template< typename T > - object_t*_objCreateValueNode( object_t* obj, T value, const char* msg, unsigned flags=0 ) + object_t*_objCreateValueNode( object_t* obj, T value, const char* msg=nullptr, unsigned flags=0 ) { return NULL; } - + + template<> object_t* _objCreateValueNode( object_t* parent, uint8_t value, const char* msg, unsigned flags ) + { return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); } + template<> object_t* _objCreateValueNode( object_t* parent, int8_t value, const char* msg, unsigned flags ) { return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); } + template<> object_t* _objCreateValueNode( object_t* parent, uint16_t value, const char* msg, unsigned flags ) + { return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); } + + template<> object_t* _objCreateValueNode( object_t* parent, int16_t value, const char* msg, unsigned flags ) + { return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); } + + template<> object_t* _objCreateValueNode( object_t* parent, uint32_t value, const char* msg, unsigned flags ) + { return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); } + template<> object_t* _objCreateValueNode( object_t* parent, int32_t value, const char* msg, unsigned flags ) { return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); } + + template<> object_t* _objCreateValueNode( object_t* parent, uint64_t value, const char* msg, unsigned flags ) + { return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); } + + template<> object_t* _objCreateValueNode( object_t* parent, int64_t value, const char* msg, unsigned flags ) + { return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); } + + template<> object_t* _objCreateValueNode( object_t* parent, float value, const char* msg, unsigned flags ) + { return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode( object_t* parent, double value, const char* msg, unsigned flags ) { return _objAppendLeftMostNode( parent, _objSetLeafValue( _objAllocate(), value ) ); }