2019-12-19 03:24:12 +00:00
|
|
|
#ifndef cwObject_H
|
|
|
|
#define cwObject_H
|
|
|
|
|
|
|
|
|
|
|
|
namespace cw
|
|
|
|
{
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
kInvalidTId = 0x00000000,
|
|
|
|
kNullTId = 0x00000001,
|
|
|
|
kErrorTId = 0x00000002,
|
|
|
|
kCharTId = 0x00000004,
|
|
|
|
kInt8TId = 0x00000008,
|
|
|
|
kUInt8TId = 0x00000010,
|
|
|
|
kInt16TId = 0x00000020,
|
|
|
|
kUInt16TId = 0x00000040,
|
|
|
|
kInt32TId = 0x00000080,
|
|
|
|
kUInt32TId = 0x00000100,
|
|
|
|
kInt64TId = 0x00000200,
|
|
|
|
kUInt64TId = 0x00000400,
|
|
|
|
kFloatTId = 0x00000800,
|
|
|
|
kDoubleTId = 0x00001000,
|
|
|
|
kBoolTId = 0x00002000,
|
|
|
|
kStringTId = 0x00004000,
|
2020-04-06 23:15:03 +00:00
|
|
|
kCStringTId = 0x00008000, // static string (don't delete)
|
|
|
|
kVectTId = 0x00010000,
|
|
|
|
kPairTId = 0x00020000,
|
|
|
|
kListTId = 0x00040000,
|
|
|
|
kDictTId = 0x00080000,
|
|
|
|
kRootTId = 0x00100000,
|
2019-12-19 03:24:12 +00:00
|
|
|
|
|
|
|
kHexFl = 0x10000000,
|
|
|
|
kIdentFl = 0x20000000
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef unsigned objTypeId_t;
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
kValueContainerFl = 0x01, // root,pair, or list are the only legal value containers
|
2020-03-31 16:51:17 +00:00
|
|
|
kContainerFl = 0x02,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
kNoRecurseFl = 0x01,
|
|
|
|
kOptionalFl = 0x02
|
2019-12-19 03:24:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct object_str;
|
|
|
|
struct vect_str;
|
|
|
|
|
|
|
|
typedef struct print_ctx_str
|
|
|
|
{
|
|
|
|
unsigned indent = 0;
|
|
|
|
bool listOnOneLineFl = true;
|
|
|
|
} print_ctx_t;
|
|
|
|
|
|
|
|
typedef struct type_str
|
|
|
|
{
|
|
|
|
objTypeId_t id;
|
|
|
|
const char* label;
|
|
|
|
unsigned flags;
|
|
|
|
|
|
|
|
void (*free)( struct object_str* o );
|
|
|
|
rc_t (*value)( const struct object_str* o, unsigned tid, void* dst );
|
|
|
|
void (*print)( const struct object_str* o, print_ctx_t& c );
|
2020-03-24 12:53:00 +00:00
|
|
|
unsigned( *to_string)( const struct object_str* o, char* buf, unsigned bufByteN );
|
2020-04-21 18:53:33 +00:00
|
|
|
struct object_str* (*duplicate)( const struct object_str* src, struct object_str* parent );
|
|
|
|
|
2019-12-19 03:24:12 +00:00
|
|
|
} objType_t;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct object_str
|
|
|
|
{
|
|
|
|
objType_t* type = nullptr;
|
|
|
|
struct object_str* parent = nullptr;
|
|
|
|
struct object_str* sibling = nullptr;
|
|
|
|
union
|
|
|
|
{
|
|
|
|
char c;
|
|
|
|
|
|
|
|
std::int8_t i8;
|
|
|
|
std::uint8_t u8;
|
|
|
|
std::int16_t i16;
|
|
|
|
std::uint16_t u16;
|
|
|
|
std::int32_t i32;
|
|
|
|
std::uint32_t u32;
|
|
|
|
std::int64_t i64;
|
|
|
|
std::uint64_t u64;
|
|
|
|
|
|
|
|
bool b;
|
|
|
|
|
|
|
|
float f;
|
|
|
|
double d;
|
|
|
|
|
|
|
|
char* str;
|
|
|
|
struct vect_str* vect;
|
|
|
|
|
|
|
|
struct object_str* children; // 'children' is valid when is_container()==true
|
|
|
|
} u;
|
|
|
|
|
|
|
|
|
2020-03-25 15:34:28 +00:00
|
|
|
void unlink();
|
2019-12-19 03:24:12 +00:00
|
|
|
void free();
|
|
|
|
unsigned child_count() const;
|
|
|
|
|
|
|
|
// Value containers are parents of leaf nodes. (A dictionary is not a value container because it's children are pairs with are not leaf nodes.)
|
|
|
|
inline bool is_value_container() const { return type != nullptr && cwIsFlag(type->flags,kValueContainerFl); }
|
|
|
|
|
|
|
|
// Containers have children and use the object.u.children pointer.
|
2020-01-27 22:48:17 +00:00
|
|
|
inline bool is_container() const { return type != nullptr && cwIsFlag(type->flags,kContainerFl); }
|
|
|
|
inline bool is_pair() const { return type != nullptr && type->id == kPairTId; }
|
|
|
|
inline bool is_dict() const { return type != nullptr && type->id == kDictTId; }
|
|
|
|
inline bool is_list() const { return type != nullptr && type->id == kListTId; }
|
2021-01-31 16:04:49 +00:00
|
|
|
inline bool is_type( unsigned tid ) const { return type != nullptr && type->id == tid; }
|
2019-12-19 03:24:12 +00:00
|
|
|
|
|
|
|
rc_t value( void* dst, unsigned dstTypeId );
|
|
|
|
rc_t value( char& v ) const;
|
|
|
|
rc_t value( int8_t& v ) const;
|
|
|
|
rc_t value( uint8_t& v ) const;
|
|
|
|
rc_t value( int16_t& v ) const;
|
|
|
|
rc_t value( uint16_t& v ) const;
|
|
|
|
rc_t value( int32_t& v ) const;
|
|
|
|
rc_t value( uint32_t& v ) const;
|
|
|
|
rc_t value( int64_t& v ) const;
|
|
|
|
rc_t value( uint64_t& v ) const;
|
|
|
|
rc_t value( float& v ) const;
|
|
|
|
rc_t value( double& v ) const;
|
2020-04-16 15:05:38 +00:00
|
|
|
rc_t value( bool& v ) const;
|
2019-12-19 03:24:12 +00:00
|
|
|
rc_t value( char*& v ) const;
|
2020-03-31 16:51:17 +00:00
|
|
|
rc_t value( const char*& v ) const;
|
2020-09-01 19:46:21 +00:00
|
|
|
rc_t value( const struct object_str*& v) const {v=this; return kOkRC; }
|
|
|
|
|
2019-12-19 03:24:12 +00:00
|
|
|
const char* pair_label() const;
|
2020-03-25 15:34:28 +00:00
|
|
|
|
2019-12-19 03:24:12 +00:00
|
|
|
const struct object_str* pair_value() const;
|
2020-03-25 15:34:28 +00:00
|
|
|
struct object_str* pair_value();
|
|
|
|
|
|
|
|
// Search for the pair label 'label'.
|
2020-03-31 16:51:17 +00:00
|
|
|
// 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 );
|
2020-03-25 15:34:28 +00:00
|
|
|
|
2020-09-01 19:46:21 +00:00
|
|
|
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); }
|
|
|
|
|
|
|
|
|
2020-04-06 23:15:03 +00:00
|
|
|
const struct object_str* child_ele( unsigned idx ) const;
|
|
|
|
struct object_str* child_ele( unsigned idx );
|
2019-12-19 03:24:12 +00:00
|
|
|
|
2020-09-22 15:37:19 +00:00
|
|
|
// Set flag 'kNoRecurseFl' to not recurse into the object in search of the value.
|
|
|
|
// Set flag 'kOptionalFl' if the label is optional and may not exist.
|
2019-12-19 03:24:12 +00:00
|
|
|
template< typename T >
|
2020-03-31 16:51:17 +00:00
|
|
|
rc_t get( const char* label, T& v, unsigned flags=0 ) const
|
2019-12-19 03:24:12 +00:00
|
|
|
{
|
|
|
|
const struct object_str* o;
|
2020-03-31 16:51:17 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
2019-12-19 03:24:12 +00:00
|
|
|
return o->value(v);
|
|
|
|
}
|
|
|
|
|
2020-09-22 15:37:19 +00:00
|
|
|
rc_t _getv(unsigned flags) const { return kOkRC; }
|
2020-04-10 01:06:06 +00:00
|
|
|
|
|
|
|
// getv("label0",v0,"label1",v1, ... )
|
2019-12-19 03:24:12 +00:00
|
|
|
template< typename T0, typename T1, typename... ARGS >
|
2020-09-22 15:37:19 +00:00
|
|
|
rc_t _getv( unsigned flags, T0 label, T1& valRef, ARGS&&... args ) const
|
2019-12-19 03:24:12 +00:00
|
|
|
{
|
2020-09-22 15:37:19 +00:00
|
|
|
rc_t rc = get(label,valRef,flags);
|
|
|
|
|
|
|
|
// if no error occurred ....
|
|
|
|
if( rc == kOkRC || (rc == kLabelNotFoundRC && cwIsFlag(flags,kOptionalFl)))
|
|
|
|
rc = _getv(flags, std::forward<ARGS>(args)...); // ... recurse
|
|
|
|
else
|
|
|
|
rc = cwLogError(rc,"object parse failed for the pair label:'%s'.",cwStringNullGuard(label));
|
2019-12-19 03:24:12 +00:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
2020-04-06 23:15:03 +00:00
|
|
|
|
2020-09-22 15:37:19 +00:00
|
|
|
// getv("label0",v0,"label1",v1, ... )
|
|
|
|
template< typename T0, typename T1, typename... ARGS >
|
|
|
|
rc_t getv( T0 label, T1& valRef, ARGS&&... args ) const
|
|
|
|
{ return _getv(0,label,valRef,args...); }
|
|
|
|
|
|
|
|
// getv("label0",v0,"label1",v1, ... ) where all values are optional
|
|
|
|
template< typename T0, typename T1, typename... ARGS >
|
|
|
|
rc_t getv_opt( T0 label, T1& valRef, ARGS&&... args ) const
|
|
|
|
{ return _getv(kOptionalFl,label,valRef,args...); }
|
|
|
|
|
2020-04-06 23:15:03 +00:00
|
|
|
template< typename T >
|
|
|
|
struct object_str* insertPair( const char* label, const T& v )
|
|
|
|
{ return newPairObject(label, v, this); }
|
|
|
|
|
2020-03-24 12:53:00 +00:00
|
|
|
unsigned to_string( char* buf, unsigned bufByteN ) const;
|
2019-12-19 03:24:12 +00:00
|
|
|
void print(const print_ctx_t* c=NULL) const;
|
2020-04-21 18:53:33 +00:00
|
|
|
struct object_str* duplicate() const;
|
2020-09-01 19:46:21 +00:00
|
|
|
|
2019-12-19 03:24:12 +00:00
|
|
|
} object_t;
|
|
|
|
|
2020-03-31 16:51:17 +00:00
|
|
|
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);
|
2020-04-06 23:15:03 +00:00
|
|
|
object_t* newObject( char* v, object_t* parent=nullptr);
|
2020-03-31 16:51:17 +00:00
|
|
|
object_t* newObject( const char* v, object_t* parent=nullptr);
|
2020-04-06 23:15:03 +00:00
|
|
|
|
|
|
|
// Return a pointer to the value node.
|
|
|
|
object_t* newPairObject( const char* label, std::uint8_t v, object_t* parent=nullptr);
|
|
|
|
object_t* newPairObject( const char* label, std::int8_t v, object_t* parent=nullptr);
|
|
|
|
object_t* newPairObject( const char* label, std::int16_t v, object_t* parent=nullptr);
|
|
|
|
object_t* newPairObject( const char* label, std::uint16_t v, object_t* parent=nullptr);
|
|
|
|
object_t* newPairObject( const char* label, std::int32_t v, object_t* parent=nullptr);
|
|
|
|
object_t* newPairObject( const char* label, std::uint32_t v, object_t* parent=nullptr);
|
|
|
|
object_t* newPairObject( const char* label, std::int64_t v, object_t* parent=nullptr);
|
|
|
|
object_t* newPairObject( const char* label, std::uint64_t v, object_t* parent=nullptr);
|
|
|
|
object_t* newPairObject( const char* label, bool v, object_t* parent=nullptr);
|
|
|
|
object_t* newPairObject( const char* label, float v, object_t* parent=nullptr);
|
|
|
|
object_t* newPairObject( const char* label, double v, object_t* parent=nullptr);
|
|
|
|
object_t* newPairObject( const char* label, char* v, object_t* parent=nullptr);
|
|
|
|
object_t* newPairObject( const char* label, const char* v, object_t* parent=nullptr);
|
2020-03-31 16:51:17 +00:00
|
|
|
|
2019-12-19 03:24:12 +00:00
|
|
|
rc_t objectFromString( const char* s, object_t*& objRef );
|
|
|
|
rc_t objectFromFile( const char* fn, object_t*& objRef );
|
|
|
|
void objectPrintTypes( object_t* o );
|
|
|
|
|
2020-09-01 19:46:21 +00:00
|
|
|
|
2019-12-19 03:24:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|