From eed564954a4171ca12ec903382c92afac58ebb5f Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 11 Dec 2020 15:58:06 -0500 Subject: [PATCH] cwVariant.h/cpp, Makefile.am : Initial commit. --- Makefile.am | 4 +- cwVariant.cpp | 386 ++++++++++++++++++++++++++++++++++++++++++++++++++ cwVariant.h | 137 ++++++++++++++++++ 3 files changed, 525 insertions(+), 2 deletions(-) create mode 100644 cwVariant.cpp create mode 100644 cwVariant.h diff --git a/Makefile.am b/Makefile.am index cd98df8..b4c8576 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,8 +4,8 @@ libcwSRC = libcwHDR += src/libcw/cwCommon.h src/libcw/cwCommonImpl.h src/libcw/cwMem.h src/libcw/cwLog.h src/libcw/cwUtility.h libcwSRC += src/libcw/cwCommonImpl.cpp src/libcw/cwMem.cpp src/libcw/cwLog.cpp src/libcw/cwUtility.cpp -libcwHDR += src/libcw/cwString.h src/libcw/cwVectOps.h src/libcw/cwMtx.h -libcwSRC += src/libcw/cwString.cpp src/libcw/cwMtx.cpp +libcwHDR += src/libcw/cwString.h src/libcw/cwVectOps.h src/libcw/cwMtx.h src/libcw/cwVariant.h +libcwSRC += src/libcw/cwString.cpp src/libcw/cwMtx.cpp src/libcw/cwVariant.cpp libcwHDR += src/libcw/cwFileSys.h src/libcw/cwText.h src/libcw/cwFile.h src/libcw/cwTime.h src/libcw/cwLex.h src/libcw/cwNumericConvert.h libcwSRC += src/libcw/cwFileSys.cpp src/libcw/cwText.cpp src/libcw/cwFile.cpp src/libcw/cwTime.cpp src/libcw/cwLex.cpp diff --git a/cwVariant.cpp b/cwVariant.cpp new file mode 100644 index 0000000..7c9f763 --- /dev/null +++ b/cwVariant.cpp @@ -0,0 +1,386 @@ +#include "cwCommon.h" +#include "cwLog.h" +#include "cwCommonImpl.h" +#include "cwFile.h" +#include "cwVariant.h" + +namespace cw +{ + namespace variant + { + typedef struct _variantDesc_str + { + unsigned flags; + const char* label; + const char* fmt; + unsigned byteN; + } variantDesc_t; + + variantDesc_t _variantDescArray[] = { + + { kCharVFl, "char", "c", sizeof(char) }, + { kUCharVFl, "uchar", "c", sizeof(unsigned char) }, + { kInt8VFl, "uint8", "i", sizeof(std::uint8_t) }, + { kUInt8VFl, "int8", "i", sizeof(std::int8_t) }, + { kInt16VFl, "uint16", "i", sizeof(std::uint16_t) }, + { kUInt16VFl,"int16", "i", sizeof(std::int16_t) }, + { kInt32VFl, "uint32", "i", sizeof(std::uint32_t) }, + { kUInt32VFl,"int32", "i", sizeof(std::int32_t) }, + { kInt64VFl, "uint64", "li", sizeof(std::uint64_t) }, + { kUInt64VFl,"int64", "li", sizeof(std::int64_t) }, + { kBoolVFl, "bool", "i", sizeof(bool) }, + { kFloatVFl, "float", "f", sizeof(float) }, + { kDoubleVFl,"double", "f", sizeof(double) }, + + { kPtrVFl | kCharVFl, "char_ptr", "p", sizeof(char) }, + { kPtrVFl | kUCharVFl, "uchar_ptr", "p", sizeof(unsigned char) }, + { kPtrVFl | kInt8VFl, "uint8_ptr", "p", sizeof(std::uint8_t) }, + { kPtrVFl | kUInt8VFl, "int8_ptr", "p", sizeof(std::int8_t) }, + { kPtrVFl | kInt16VFl, "uint16_ptr", "p", sizeof(std::uint16_t) }, + { kPtrVFl | kUInt16VFl, "int16_ptr", "p", sizeof(std::int16_t) }, + { kPtrVFl | kInt32VFl, "uint32_ptr", "p", sizeof(std::uint32_t) }, + { kPtrVFl | kUInt32VFl, "int32_ptr", "p", sizeof(std::int32_t) }, + { kPtrVFl | kInt64VFl, "uint64_ptr", "p", sizeof(std::uint64_t) }, + { kPtrVFl | kUInt64VFl, "int64_ptr", "p", sizeof(std::int64_t) }, + { kPtrVFl | kBoolVFl, "bool_ptr", "p", sizeof(bool) }, + { kPtrVFl | kFloatVFl, "float_ptr", "p", sizeof(float) }, + { kPtrVFl | kDoubleVFl, "double_ptr", "p", sizeof(double) }, + + { 0, nullptr, 0 } + + }; + + const variantDesc_t* _flagsToDesc( unsigned flags, bool reportErrorFl=true ) + { + variantDesc_t* v = _variantDescArray; + + for(; v->flags!=0; ++v) + if( v->flags == flags ) + return v; + + if( reportErrorFl ) + cwLogError(kInvalidArgRC,"The variant flags 0x%x is invalid."); + return nullptr; + } + + const char* safeFlagsToLabel( unsigned flags ) + { + const variantDesc_t* d = _flagsToDesc(flags,false); + return d == nullptr ? "" : d->label; + } + + rc_t _get_uint8( const value_t& v, std::uint8_t& r ) + { + switch( v.flags ) + { + case kCharVFl: r = v.u.c; break; + case kUCharVFl: r = v.u.uc; break; + case kInt8VFl: r = v.u.i8; break; + case kUInt8VFl: r = v.u.u8; break; + case kBoolVFl: r = v.u.b; break; + default: + return cwLogError(kInvalidArgRC,"Invalid type conversion. Cannot convert '%s' to 'double'.", safeFlagsToLabel(v.flags) ); + } + return kOkRC; + } + + rc_t _get_int8( const value_t& v, std::int8_t& r ) + { + switch( v.flags ) + { + case kCharVFl: r = v.u.c; break; + case kUCharVFl: r = v.u.uc; break; + case kInt8VFl: r = v.u.i8; break; + case kUInt8VFl: r = v.u.u8; break; + case kBoolVFl: r = v.u.b; break; + default: + return cwLogError(kInvalidArgRC,"Invalid type conversion. Cannot convert '%s' to 'double'.", safeFlagsToLabel(v.flags) ); + } + return kOkRC; + } + + + rc_t _get_uint16( const value_t& v, std::uint16_t& r ) + { + switch( v.flags ) + { + case kCharVFl: r = v.u.c; break; + case kUCharVFl: r = v.u.uc; break; + case kInt8VFl: r = v.u.i8; break; + case kUInt8VFl: r = v.u.u8; break; + case kInt16VFl: r = v.u.i16; break; + case kUInt16VFl: r = v.u.u16; break; + case kBoolVFl: r = v.u.b; break; + default: + return cwLogError(kInvalidArgRC,"Invalid type conversion. Cannot convert '%s' to 'double'.", safeFlagsToLabel(v.flags) ); + } + return kOkRC; + } + + rc_t _get_int16( const value_t& v, std::int16_t& r ) + { + switch( v.flags ) + { + case kCharVFl: r = v.u.c; break; + case kUCharVFl: r = v.u.uc; break; + case kInt8VFl: r = v.u.i8; break; + case kUInt8VFl: r = v.u.u8; break; + case kInt16VFl: r = v.u.i16; break; + case kUInt16VFl: r = v.u.u16; break; + case kBoolVFl: r = v.u.b; break; + default: + return cwLogError(kInvalidArgRC,"Invalid type conversion. Cannot convert '%s' to 'double'.", safeFlagsToLabel(v.flags) ); + } + return kOkRC; + } + + rc_t _get_uint32( const value_t& v, std::uint32_t& r ) + { + switch( v.flags ) + { + case kCharVFl: r = v.u.c; break; + case kUCharVFl: r = v.u.uc; break; + case kInt8VFl: r = v.u.i8; break; + case kUInt8VFl: r = v.u.u8; break; + case kInt16VFl: r = v.u.i16; break; + case kUInt16VFl: r = v.u.u16; break; + case kInt32VFl: r = v.u.i32; break; + case kUInt32VFl: r = v.u.u32; break; + case kBoolVFl: r = v.u.b; break; + default: + return cwLogError(kInvalidArgRC,"Invalid type conversion. Cannot convert '%s' to 'double'.", safeFlagsToLabel(v.flags) ); + } + return kOkRC; + } + + + rc_t _get_int32( const value_t& v, std::int32_t& r ) + { + switch( v.flags ) + { + case kCharVFl: r = v.u.c; break; + case kUCharVFl: r = v.u.uc; break; + case kInt8VFl: r = v.u.i8; break; + case kUInt8VFl: r = v.u.u8; break; + case kInt16VFl: r = v.u.i16; break; + case kUInt16VFl: r = v.u.u16; break; + case kInt32VFl: r = v.u.i32; break; + case kUInt32VFl: r = v.u.u32; break; + case kBoolVFl: r = v.u.b; break; + default: + return cwLogError(kInvalidArgRC,"Invalid type conversion. Cannot convert '%s' to 'double'.", safeFlagsToLabel(v.flags) ); + } + return kOkRC; + } + + rc_t _get_uint64( const value_t& v, std::uint64_t& r ) + { + switch( v.flags ) + { + case kCharVFl: r = v.u.c; break; + case kUCharVFl: r = v.u.uc; break; + case kInt8VFl: r = v.u.i8; break; + case kUInt8VFl: r = v.u.u8; break; + case kInt16VFl: r = v.u.i16; break; + case kUInt16VFl: r = v.u.u16; break; + case kInt32VFl: r = v.u.i32; break; + case kUInt32VFl: r = v.u.u32; break; + case kInt64VFl: r = v.u.i64; break; + case kUInt64VFl: r = v.u.u64; break; + case kBoolVFl: r = v.u.b; break; + case kFloatVFl: r = v.u.f; break; + case kDoubleVFl: r = v.u.d; break; + default: + return cwLogError(kInvalidArgRC,"Invalid type conversion. Cannot convert '%s' to 'double'.", safeFlagsToLabel(v.flags) ); + } + return kOkRC; + } + + rc_t _get_int64( const value_t& v, std::int64_t& r ) + { + switch( v.flags ) + { + case kCharVFl: r = v.u.c; break; + case kUCharVFl: r = v.u.uc; break; + case kInt8VFl: r = v.u.i8; break; + case kUInt8VFl: r = v.u.u8; break; + case kInt16VFl: r = v.u.i16; break; + case kUInt16VFl: r = v.u.u16; break; + case kInt32VFl: r = v.u.i32; break; + case kUInt32VFl: r = v.u.u32; break; + case kInt64VFl: r = v.u.i64; break; + case kUInt64VFl: r = v.u.u64; break; + case kBoolVFl: r = v.u.b; break; + case kFloatVFl: r = v.u.f; break; + case kDoubleVFl: r = v.u.d; break; + default: + return cwLogError(kInvalidArgRC,"Invalid type conversion. Cannot convert '%s' to 'double'.", safeFlagsToLabel(v.flags) ); + } + return kOkRC; + } + + rc_t _get_bool( const value_t& v, bool& r ) + { + switch( v.flags ) + { + case kCharVFl: r = v.u.c!=0; break; + case kUCharVFl: r = v.u.uc!=0; break; + case kInt8VFl: r = v.u.i8!=0; break; + case kUInt8VFl: r = v.u.u8!=0; break; + case kInt16VFl: r = v.u.i16!=0; break; + case kUInt16VFl: r = v.u.u16!=0; break; + case kInt32VFl: r = v.u.i32!=0; break; + case kUInt32VFl: r = v.u.u32!=0; break; + case kInt64VFl: r = v.u.i64!=0; break; + case kUInt64VFl: r = v.u.u64!=0; break; + case kBoolVFl: r = v.u.b; break; + case kFloatVFl: r = v.u.f!=0.0; break; + case kDoubleVFl: r = v.u.d!=0.0; break; + default: + return cwLogError(kInvalidArgRC,"Invalid type conversion. Cannot convert '%s' to 'double'.", safeFlagsToLabel(v.flags) ); + } + return kOkRC; + } + + rc_t _get_float( const value_t& v, float& r ) + { + switch( v.flags ) + { + case kCharVFl: r = v.u.c; break; + case kUCharVFl: r = v.u.uc; break; + case kInt8VFl: r = v.u.i8; break; + case kUInt8VFl: r = v.u.u8; break; + case kInt16VFl: r = v.u.i16; break; + case kUInt16VFl: r = v.u.u16; break; + case kInt32VFl: r = v.u.i32; break; + case kUInt32VFl: r = v.u.u32; break; + case kInt64VFl: r = v.u.i64; break; + case kUInt64VFl: r = v.u.u64; break; + case kBoolVFl: r = v.u.b; break; + case kFloatVFl: r = v.u.f; break; + default: + return cwLogError(kInvalidArgRC,"Invalid type conversion. Cannot convert '%s' to 'double'.", safeFlagsToLabel(v.flags) ); + } + return kOkRC; + } + + rc_t _get_double( const value_t& v, double& r ) + { + switch( v.flags ) + { + case kCharVFl: r = v.u.c; break; + case kUCharVFl: r = v.u.uc; break; + case kInt8VFl: r = v.u.i8; break; + case kUInt8VFl: r = v.u.u8; break; + case kInt16VFl: r = v.u.i16; break; + case kUInt16VFl: r = v.u.u16; break; + case kInt32VFl: r = v.u.i32; break; + case kUInt32VFl: r = v.u.u32; break; + case kInt64VFl: r = v.u.i64; break; + case kUInt64VFl: r = v.u.u64; break; + case kBoolVFl: r = v.u.b; break; + case kFloatVFl: r = v.u.f; break; + case kDoubleVFl: r = v.u.d; break; + default: + return cwLogError(kInvalidArgRC,"Invalid type conversion. Cannot convert '%s' to 'double'.", safeFlagsToLabel(v.flags) ); + } + return kOkRC; + } + + + rc_t get( const value_t& v, std::int8_t& r ) { return _get_int8(v,r); } + rc_t get( const value_t& v, std::uint8_t& r ) { return _get_uint8(v,r); } + rc_t get( const value_t& v, std::int16_t& r ) { return _get_int16(v,r); } + rc_t get( const value_t& v, std::uint16_t& r ) { return _get_uint16(v,r); } + rc_t get( const value_t& v, std::int32_t& r ) { return _get_int32(v,r); } + rc_t get( const value_t& v, std::uint32_t& r ) { return _get_uint32(v,r); } + rc_t get( const value_t& v, std::int64_t& r ) { return _get_int64(v,r); } + rc_t get( const value_t& v, std::uint64_t& r ) { return _get_uint64(v,r); } + rc_t get( const value_t& v, bool& r ) { return _get_bool(v,r); } + rc_t get( const value_t& v, float& r ) { return _get_float(v,r); } + rc_t get( const value_t& v, double& r ) { return _get_double(v,r); } + + + + } +} + +const char* cw::variant::flagsToLabel( unsigned flags ) +{ + const variantDesc_t* v; + if((v = _flagsToDesc(flags)) != nullptr ) + return v->label; + + return nullptr; +} + +unsigned cw::variant::flagsToBytes( unsigned flags ) +{ + const variantDesc_t* v; + if((v = _flagsToDesc(flags)) != nullptr ) + return v->byteN; + + return 0; +} + + +cw::rc_t cw::variant::print( const value_t& v, const char* fmt) +{ + rc_t rc = kOkRC; + const variantDesc_t* d; + + if((d = _flagsToDesc(v.flags)) != nullptr ) + { + char f[32+1]; + snprintf(f,32,"%s%s%s", "%", fmt==nullptr ? "":fmt, d->fmt); + + if( v.flags & kPtrVFl ) + printf(fmt,v.u.vp); + else + { + switch( v.flags ) + { + case kCharVFl: printf(f,v.u.c); break; + case kUCharVFl: printf(f,v.u.uc); break; + case kInt8VFl: printf(f,v.u.i8); break; + case kUInt8VFl: printf(f,v.u.u8); break; + case kInt16VFl: printf(f,v.u.i16); break; + case kUInt16VFl: printf(f,v.u.u16); break; + case kInt32VFl: + printf(f,v.u.i32); + break; + + case kUInt32VFl: printf(f,v.u.u32); break; + case kInt64VFl: printf(f,v.u.i64); break; + case kUInt64VFl: printf(f,v.u.u64); break; + case kBoolVFl: printf(f,v.u.b); break; + case kFloatVFl: printf(f,v.u.f); break; + case kDoubleVFl: printf(f,v.u.d); break; + default: + assert(0); + + } + } + } + + return rc; +} + + +cw::rc_t cw::variant::write( file::handle_t fH, const value_t& v ) +{ + rc_t rc; + if((rc = file::writeUInt( fH, &v.flags)) == kOkRC ) + rc = file::write( fH, &v.u, sizeof(v.u)); + return rc; +} + +cw::rc_t cw::variant::read( file::handle_t fH, value_t& v ) +{ + rc_t rc; + if((rc = file::readUInt( fH, &v.flags)) == kOkRC ) + rc = file::read( fH, &v.u, sizeof(v.u)); + return rc; +} + + diff --git a/cwVariant.h b/cwVariant.h new file mode 100644 index 0000000..2e4ce59 --- /dev/null +++ b/cwVariant.h @@ -0,0 +1,137 @@ +#ifndef cwVariant_h +#define cwVariant_h + +namespace cw +{ + namespace variant + { + enum { + kCharVFl = 0x00000001, + kUCharVFl = 0x00000002, + kInt8VFl = 0x00000004, + kUInt8VFl = 0x00000008, + kInt16VFl = 0x00000010, + kUInt16VFl = 0x00000020, + kInt32VFl = 0x00000040, + kUInt32VFl = 0x00000080, + kInt64VFl = 0x00000100, + kUInt64VFl = 0x00000200, + kBoolVFl = 0x00000400, + kIntVMask = 0x000007ff, + + kFloatVFl = 0x00000800, + kDoubleVFl = 0x00001000, + kRealVMask = 0x00001800, + + kNumberMask= kRealVMask | kIntVMask, + + kPtrVFl = 0x80000000 + }; + + const char* flagsToLabel( unsigned flags ); + unsigned flagsToBytes( unsigned flags ); + + typedef struct value_str + { + unsigned flags; + union { + char c; + unsigned char uc; + 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* cp; + unsigned char* ucp; + std::int8_t* i8p; + std::uint8_t* u8p; + std::int16_t* i16p; + std::uint16_t* u16p; + std::int32_t* i32p; + std::uint32_t* u32p; + std::int64_t* i64p; + std::uint64_t* u64p; + bool* bp; + float* fp; + double* dp; + void* vp; + + } u; + } value_t; + + + + inline void set( value_t& v, char x ) { v.u.c=x; v.flags=kCharVFl; } + //inline void set( value_t& v, unsigned char x ) { v.u.uc=x; v.flags=kUCharVFl; } + + inline void set( value_t& v, std::int8_t x ) { v.u.i8=x; v.flags=kInt8VFl; } + inline void set( value_t& v, std::uint8_t x ) { v.u.u8=x; v.flags=kUInt8VFl; } + + inline void set( value_t& v, std::int16_t x ) { v.u.i16=x; v.flags=kInt16VFl; } + inline void set( value_t& v, std::uint16_t x ) { v.u.u16=x; v.flags=kUInt16VFl; } + + inline void set( value_t& v, std::int32_t x ) { v.u.i32=x; v.flags=kInt32VFl; } + inline void set( value_t& v, std::uint32_t x ) { v.u.u32=x; v.flags=kUInt32VFl; } + + inline void set( value_t& v, std::int64_t x ) { v.u.i64=x; v.flags=kInt64VFl; } + inline void set( value_t& v, std::uint64_t x ) { v.u.u64=x; v.flags=kUInt64VFl; } + + inline void set( value_t& v, bool x ) { v.u.b=x; v.flags=kBoolVFl; } + inline void set( value_t& v, float x ) { v.u.f=x; v.flags=kFloatVFl; } + inline void set( value_t& v, double x ) { v.u.d=x; v.flags=kDoubleVFl; } + + + inline void set( value_t& v, char* x ) { v.u.cp=x; v.flags=kPtrVFl | kCharVFl; } + //inline void set( value_t& v, unsigned char* x ) { v.u.ucp=x; v.flags=kPtrVFl | kUCharVFl; } + + inline void set( value_t& v, std::int8_t* x ) { v.u.i8p=x; v.flags=kPtrVFl | kInt8VFl; } + inline void set( value_t& v, std::uint8_t* x ) { v.u.u8p=x; v.flags=kPtrVFl | kUInt8VFl; } + + inline void set( value_t& v, std::int16_t* x ) { v.u.i16p=x; v.flags=kPtrVFl | kInt16VFl; } + inline void set( value_t& v, std::uint16_t* x ) { v.u.u16p=x; v.flags=kPtrVFl | kUInt16VFl; } + + inline void set( value_t& v, std::int32_t* x ) { v.u.i32p=x; v.flags=kPtrVFl | kInt32VFl; } + inline void set( value_t& v, std::uint32_t* x ) { v.u.u32p=x; v.flags=kPtrVFl | kUInt32VFl; } + + inline void set( value_t& v, std::int64_t* x ) { v.u.i64p=x; v.flags=kPtrVFl | kInt64VFl; } + inline void set( value_t& v, std::uint64_t* x ) { v.u.u64p=x; v.flags=kPtrVFl | kUInt64VFl; } + + inline void set( value_t& v, bool* x ) { v.u.bp=x; v.flags=kPtrVFl | kBoolVFl; } + inline void set( value_t& v, float* x ) { v.u.fp=x; v.flags=kPtrVFl | kFloatVFl; } + inline void set( value_t& v, double* x ) { v.u.dp=x; v.flags=kPtrVFl | kDoubleVFl; } + + + rc_t get( const value_t& v, std::int8_t& r ); + rc_t get( const value_t& v, std::uint8_t& r ); + rc_t get( const value_t& v, std::int16_t& r ); + rc_t get( const value_t& v, std::uint16_t& r ); + rc_t get( const value_t& v, std::int32_t& r ); + rc_t get( const value_t& v, std::uint32_t& r ); + rc_t get( const value_t& v, std::int64_t& r ); + rc_t get( const value_t& v, std::uint64_t& r ); + rc_t get( const value_t& v, bool& r ); + rc_t get( const value_t& v, float& r ); + rc_t get( const value_t& v, double& r ); + + + inline bool isInt( const value_t& v ) { return v.flags & kIntVMask; } + inline bool isReal(const value_t& v ) { return v.flags & kRealVMask; } + inline bool isPtr( const value_t& v ) { return v.flags & kPtrVFl; } + + rc_t print( const value_t& v, const char* fmt=nullptr ); + rc_t write( file::handle_t fH, const value_t& v ); + rc_t read( file::handle_t fH, value_t& v ); + } + +} + + +#endif