Changeset 325 for cpp/frams/util
- Timestamp:
- 02/05/15 00:26:20 (10 years ago)
- Location:
- cpp/frams/util
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/util/extvalue.cpp
r286 r325 12 12 #include <common/nonstd_math.h> 13 13 #include <common/Convert.h> 14 #include <climits> 14 15 15 16 #ifndef NO_BARRIER … … 609 610 } 610 611 611 paInt ExtValue::getInt(const char* s) 612 { 613 if ((s[0]=='0')&&(s[1]=='x')) 614 { 615 paInt val; 616 sscanf(s+2,PA_INT_SCANF_X,&val); 617 return val; 618 } 619 else 620 { 621 if (strchr(s,'e')||(strchr(s,'E'))) 622 return (paInt)atof(s); 623 else 624 return atoi(s); 625 } 612 bool ExtValue::parseInt(const char* s, paInt &result, bool strict) 613 { 614 ExtValue tmp; 615 const char* after = tmp.parseNumber(s, strict ? TInt : TUnknown); 616 if (after == NULL) return false; 617 if (after[0] != 0) return false; 618 result = tmp.getInt(); 619 return true; 620 } 621 622 bool ExtValue::parseDouble(const char* s, double &result) 623 { 624 ExtValue tmp; 625 const char* after = tmp.parseNumber(s, TDouble); 626 if (after == NULL) return false; 627 if (after[0] != 0) return false; 628 result = tmp.getDouble(); 629 return true; 630 } 631 632 paInt ExtValue::getInt(const char* s,bool strict) 633 { 634 paInt result; 635 if (parseInt(s, result, strict)) 636 return result; 637 FMprintf("ExtValue", "getInt", FMLV_ERROR, "Could not parse '%s'%s", s, strict?" (strict)":""); 638 return 0; 626 639 } 627 640 628 641 double ExtValue::getDouble(const char* s) 629 642 { 630 if ((s[0]=='0')&&(s[1]=='x')) 631 { 632 paInt val; 633 sscanf(s+2,PA_INT_SCANF_X,&val); 634 return val; 635 } 636 else 637 return atof(s); 643 double result; 644 if (parseDouble(s, result)) 645 return result; 646 FMprintf("ExtValue", "getDouble", FMLV_ERROR, "Could not parse '%s'", s); 647 return 0; 638 648 } 639 649 640 650 paInt ExtValue::getInt() const 641 651 { 642 switch(type)652 switch (type) 643 653 { 644 654 case TInt: return idata(); … … 646 656 case TString: return getInt((const char*)sdata()); 647 657 case TObj: 648 FMprintf("ExtValue", "getInt",FMLV_WARN,"Getting integer value from object reference (%s)",(const char*)getString());658 FMprintf("ExtValue", "getInt", FMLV_WARN, "Getting integer value from object reference (%s)", (const char*)getString()); 649 659 return (paInt)(intptr_t)odata().param; 650 660 default:; 651 661 } 652 return 0;662 return 0; 653 663 } 654 664 655 665 double ExtValue::getDouble() const 656 666 { 657 switch(type)667 switch (type) 658 668 { 659 669 case TDouble: return ddata(); … … 661 671 case TString: return getDouble((const char*)sdata()); 662 672 case TObj: 663 FMprintf("ExtValue", "getDouble",FMLV_WARN,"Getting floating point value from object reference (%s)",(const char*)getString());673 FMprintf("ExtValue", "getDouble", FMLV_WARN, "Getting floating point value from object reference (%s)", (const char*)getString()); 664 674 return (double)(intptr_t)odata().param; 665 675 default:; 666 676 } 667 return 0.0; 668 } 677 return 0.0; 678 } 679 669 680 SString ExtValue::getString() const 670 681 { 671 switch(type)682 switch (type) 672 683 { 673 684 case TString: return sdata(); … … 682 693 const SString* ExtValue::getStringPtr() const 683 694 { 684 if (type==TString)685 return &sdata();686 return NULL;695 if (type == TString) 696 return &sdata(); 697 return NULL; 687 698 } 688 699 … … 710 721 } 711 722 712 //returns the first character after the parsed number or NULL if not a number 713 const char* ExtValue::parseNumber(const char* in) 714 { 715 if (isdigit(*in)||((*in=='-')&&(isdigit(in[1])))) 716 { 717 const char* p=in; 718 if (*p=='-') p++; 719 while(isdigit(*p)) p++; 720 bool fp=false; 721 if ((*p=='.') && isdigit(p[1])) 722 { 723 p++; 724 while(isdigit(*p)) p++; 725 fp=true; 726 } 727 if (((*p=='e')||(*p=='E')) && (isdigit(p[1]) || (((p[1]=='-') || (p[1]=='+')) && isdigit(p[2])))) 728 { 729 p++; 730 if ((*p=='-')||(*p=='+')) p++; 731 while(isdigit(*p)) p++; 732 fp=true; 733 } 734 735 if (fp) 736 { 737 setDouble(atof(in)); 738 return p; 739 } 740 else 741 { 742 setInt(atoi(in)); 743 return p; 744 } 745 } 746 return NULL; 723 /// returns the first character after the parsed number, or NULL if not a number 724 /// @param strict_type = restrict the allowed return value (TUnknown = unrestricted) 725 const char* ExtValue::parseNumber(const char* in, ExtPType strict_type) 726 { 727 char* after; 728 if (in == NULL) return NULL; 729 if (in[0] == 0) return NULL; 730 while (isspace(*in)) in++; 731 bool minus = false; 732 if (((in[0] == '0') && (in[1] == 'x')) 733 || (((minus = (in[0] == '-')) && (in[1] == '0') && (in[2] == 'x')))) 734 { 735 in += minus ? 3 : 2; 736 if (isspace(*in)) return NULL; 737 errno = 0; 738 unsigned long intvalue = strtoul(in, &after, 16); 739 if ((after > in) && (errno == 0) && (intvalue <= 0xffffffff)) 740 { 741 if (strict_type == TDouble) 742 setDouble(minus ? -(double)intvalue : (double)intvalue); 743 else 744 setInt(minus ? -intvalue : intvalue); 745 return after; 746 } 747 else 748 return NULL; 749 } 750 751 errno = 0; 752 double fpvalue = strtod(in, &after); 753 if ((after > in) && (errno == 0)) 754 { 755 if (strict_type != TDouble) 756 { 757 if ((memchr(in, '.', after - in) == NULL) && (memchr(in, 'e', after - in) == NULL) && (memchr(in, 'E', after - in) == NULL) // no "special" characters 758 && (fpvalue == floor(fpvalue)) // value is integer 759 && (fpvalue >= INT_MIN) && (fpvalue <= INT_MAX)) // within limits 760 { 761 setInt(fpvalue); 762 return after; 763 } 764 else if (strict_type == TInt) 765 return NULL; 766 } 767 setDouble(fpvalue); 768 return after; 769 } 770 return NULL; 747 771 } 748 772 … … 858 882 in++; 859 883 ExtValue ref; 860 ret=ref.parseNumber(in );884 ret=ref.parseNumber(in,TInt); 861 885 if (ret && (ref.getType()==TInt)) 862 886 { -
cpp/frams/util/extvalue.h
r286 r325 12 12 13 13 #define EXTVALUEUNION 14 template <int A, int B> struct CompileTimeMax {enum {val=A>B?A:B}; };14 template <int A, int B> struct CompileTimeMax { enum { val = A > B ? A : B }; }; 15 15 #define EXTVALUEUNIONSIZE CompileTimeMax<sizeof(ExtObject),sizeof(SString)>::val 16 16 17 17 enum ExtPType 18 {TUnknown=0,TInt,TDouble,TString,TObj,TInvalid}; 18 { 19 TUnknown = 0, TInt, TDouble, TString, TObj, TInvalid 20 }; 19 21 20 22 /** 21 23 destructable object 22 */24 */ 23 25 class DestrBase 24 26 { 25 27 public: 26 int refcount;27 DestrBase():refcount(0) {}28 void incref() {refcount++;}29 void decref() {refcount--; if (refcount==0) delete this;}30 virtual ~DestrBase() {}28 int refcount; 29 DestrBase() :refcount(0) {} 30 void incref() { refcount++; } 31 void decref() { refcount--; if (refcount == 0) delete this; } 32 virtual ~DestrBase() {} 31 33 }; 32 34 33 35 /** 34 36 object reference. 35 */37 */ 36 38 class ExtObject 37 39 { 38 int subtype; //< 0/1=Generic/DPC Object, 0/2=Standalone/Shared Param 39 void incref() const; 40 void decref() const; 41 public: 42 union { void* object; //< generic object, will use param 43 DestrBase *dbobject;}; //< object with refcounting, will be deleted if refcount goes to 0 44 union { Param* param; //< if object!=0 45 ParamInterface *paraminterface;}; //< if object==0 46 47 void copyFrom(const ExtObject& src) {subtype=src.subtype;object=src.object;param=src.param;} 48 49 void* operator new(size_t s, void* mem) {return mem;} 40 int subtype; //< 0/1=Generic/DPC Object, 0/2=Standalone/Shared Param 41 void incref() const; 42 void decref() const; 43 public: 44 union { 45 void* object; //< generic object, will use param 46 DestrBase *dbobject; //< object with refcounting, will be deleted if refcount goes to 0 47 }; 48 union { 49 Param* param; //< if object!=0 50 ParamInterface *paraminterface; //< if object==0 51 }; 52 53 void copyFrom(const ExtObject& src) { subtype = src.subtype; object = src.object; param = src.param; } 54 55 void* operator new(size_t s, void* mem){ return mem; } 50 56 #ifdef _MSC_VER 51 void operator delete(void* mem,void* t) {}52 #endif 53 void* operator new(size_t s) {return malloc(sizeof(ExtObject));}54 void operator delete(void* mem) {free(mem);}55 ///@param tmp_param can be used for temporary storage, the result ParamInterface* is only valid for as long as tmp_param is valid56 ParamInterface *getParamInterface(Param &tmp_param) const {if(subtype&2){tmp_param.setParamTab(param->getParamTab());tmp_param.select(object);return &tmp_param;} return paraminterface;}57 const char* interfaceName() const {if (isEmpty()) return "Empty"; return (subtype&2)?param->getName():paraminterface->getName();}58 bool matchesInterfaceName(ParamInterface* pi) const {return !strcmp(interfaceName(),pi->getName());}59 void* getTarget() const {return (subtype&1)?dbobject:object;}60 void* getTarget(const char* classname, bool through_barrier=true, bool warn=true) const;61 void setEmpty() {decref();subtype=0;param=NULL;object=NULL;}62 int isEmpty() const {return !param;}63 static const ExtObject& empty() { static const ExtObject& e((ParamInterface*)NULL); return e; }64 ExtObject(const ExtObject& src) {src.incref();copyFrom(src);}65 void operator=(const ExtObject& src) {src.incref();decref();copyFrom(src);}66 bool makeUnique();//< @return false if nothing has changed67 68 bool operator==(const ExtObject& src) const;69 70 SString toString() const;71 SString serialize_inner() const;72 SString serialize() const;73 74 ExtObject(Param *p,void *o):subtype(2),object(o),param(p){}75 ExtObject(ParamInterface *p=0):subtype(0),object(0),paraminterface(p){}76 ExtObject(Param *p,DestrBase *o):subtype(1+2),dbobject(o),param(p){incref();}77 ExtObject(ParamInterface *p,DestrBase *o):subtype(1),dbobject(o),paraminterface(p){incref();}78 79 ~ExtObject(){decref();}80 81 class Serialization82 {83 std::vector<ExtObject> refs;84 int level;85 86 Serialization():level(0) {}87 void begin();88 void end();89 int add(const ExtObject& o);90 void replace(const ExtObject& o,const ExtObject& other);91 void remove(const ExtObject& o);92 const ExtObject* get(int ref);93 };94 95 static THREAD_LOCAL_DECL(Serialization,serialization);57 void operator delete(void* mem, void* t) {} 58 #endif 59 void* operator new(size_t s){ return malloc(sizeof(ExtObject)); } 60 void operator delete(void* mem) { free(mem); } 61 ///@param tmp_param can be used for temporary storage, the result ParamInterface* is only valid for as long as tmp_param is valid 62 ParamInterface *getParamInterface(Param &tmp_param) const { if (subtype & 2){ tmp_param.setParamTab(param->getParamTab()); tmp_param.select(object); return &tmp_param; } return paraminterface; } 63 const char* interfaceName() const { if (isEmpty()) return "Empty"; return (subtype & 2) ? param->getName() : paraminterface->getName(); } 64 bool matchesInterfaceName(ParamInterface* pi) const { return !strcmp(interfaceName(), pi->getName()); } 65 void* getTarget() const { return (subtype & 1) ? dbobject : object; } 66 void* getTarget(const char* classname, bool through_barrier = true, bool warn = true) const; 67 void setEmpty() { decref(); subtype = 0; param = NULL; object = NULL; } 68 int isEmpty() const { return !param; } 69 static const ExtObject& empty() { static const ExtObject& e((ParamInterface*)NULL); return e; } 70 ExtObject(const ExtObject& src) { src.incref(); copyFrom(src); } 71 void operator=(const ExtObject& src) { src.incref(); decref(); copyFrom(src); } 72 bool makeUnique();//< @return false if nothing has changed 73 74 bool operator==(const ExtObject& src) const; 75 76 SString toString() const; 77 SString serialize_inner() const; 78 SString serialize() const; 79 80 ExtObject(Param *p, void *o) :subtype(2), object(o), param(p){} 81 ExtObject(ParamInterface *p = 0) :subtype(0), object(0), paraminterface(p){} 82 ExtObject(Param *p, DestrBase *o) :subtype(1 + 2), dbobject(o), param(p){ incref(); } 83 ExtObject(ParamInterface *p, DestrBase *o) :subtype(1), dbobject(o), paraminterface(p){ incref(); } 84 85 ~ExtObject(){ decref(); } 86 87 class Serialization 88 { 89 std::vector<ExtObject> refs; 90 int level; 91 public: 92 Serialization() :level(0) {} 93 void begin(); 94 void end(); 95 int add(const ExtObject& o); 96 void replace(const ExtObject& o, const ExtObject& other); 97 void remove(const ExtObject& o); 98 const ExtObject* get(int ref); 99 }; 100 101 static THREAD_LOCAL_DECL(Serialization, serialization); 96 102 }; 97 103 … … 99 105 { 100 106 public: 101 ExtPType type;107 ExtPType type; 102 108 #ifdef EXTVALUEUNION 103 long data[(EXTVALUEUNIONSIZE+sizeof(long)-1)/sizeof(long)];104 paInt& idata() const {return (paInt&)data[0];};105 double& ddata() const {return *(double*)data;};106 ExtObject& odata() const {return *(ExtObject*)data;};107 SString& sdata() const {return *(SString*)data;};109 long data[(EXTVALUEUNIONSIZE + sizeof(long) - 1) / sizeof(long)]; 110 paInt& idata() const { return (paInt&)data[0]; }; 111 double& ddata() const { return *(double*)data; }; 112 ExtObject& odata() const { return *(ExtObject*)data; }; 113 SString& sdata() const { return *(SString*)data; }; 108 114 #else 109 union { 110 paInt i; 111 double d; 112 SString *s; 113 ExtObject *o; 114 }; 115 paInt& idata() const {return (paInt&)i;}; 116 double& ddata() const {return (double&)d;}; 117 ExtObject& odata() const {return *o;}; 118 SString& sdata() const {return *s;}; 119 #endif 120 121 void* operator new(size_t s, void* mem) {return mem;} 122 void* operator new(size_t s) {return ::operator new(s);} 123 124 ExtValue():type(TUnknown){} 125 ~ExtValue() {setEmpty();} 126 ExtValue(paInt v) {seti(v);} 127 ExtValue(double v) {setd(v);} 128 ExtValue(const SString &v) {sets(v);} 129 ExtValue(const ExtObject &srco) {seto(srco);} 130 static ExtValue invalid() {ExtValue v; v.setInvalid(); return v;} 131 static const ExtValue& empty() { static const ExtValue v; return v; } 132 int compare(const ExtValue& src) const; 133 int operator==(const ExtValue& src) const; 134 void operator+=(const ExtValue& src); 135 void operator-=(const ExtValue& src); 136 void operator*=(const ExtValue& src); 137 void operator/=(const ExtValue& src); 138 void operator%=(const ExtValue& src); 139 void operator=(const ExtValue& src) 140 {setr(src);} 141 ExtValue(const ExtValue& src) 142 :type(TUnknown) {set(src);} 143 void setEmpty(); 144 void setInvalid() {setEmpty();type=TInvalid;} 145 bool makeUnique() {return (type==TObj) && odata().makeUnique();} //< @return false if nothing has changed 146 ExtPType getType() {return type;} 147 void *getObjectTarget(const char* classname,bool warn=true) const; 148 void setInt(paInt v) {if (type!=TInt) setri(v); else idata()=v;} 149 void setDouble(double v) {if (type!=TDouble) setrd(v); else ddata()=v;} 150 void setString(const SString &v) {if (type!=TString) setrs(v); else sdata()=v;} 151 void setObject(const ExtObject &src) {if (type!=TObj) setro(src); else odata()=src;} 152 static paInt getInt(const char* s); 153 static double getDouble(const char* s); 154 paInt getInt() const; 155 double getDouble() const; 156 SString getString() const; 157 const SString* getStringPtr() const;//< @return pointer to the internal sstring object or NULL if the current type is not string 158 SString serialize() const; 159 ExtObject getObject() const; 160 bool isNull() const {return (type==TUnknown)||((type==TObj)&&odata().isEmpty());} 161 SString typeDescription() const;//< @return human readable type name (used in error messages) 162 const char* parseNumber(const char* in); 163 const char* deserialize(const char* in);//< @return first character after the succesfully parsed string or NULL if failed 164 const char* deserialize_inner(const char* in); 165 static ParamInterface *findDeserializableClass(const char* name); 166 static PtrListTempl<ParamInterface*> &getDeserializableClasses(); 167 template<typename T> class AddDeserializable 168 { 169 public: 170 AddDeserializable() {ExtValue::getDeserializableClasses()+=&T::getStaticParam();} 171 }; 172 173 static SString format(SString& fmt,const ExtValue **values,int count); 174 175 ExtValue getExtType(); 176 177 private: // setrx - release and set, setx - assume released 178 void setr(const ExtValue& src){setEmpty();set(src);} 179 void set(const ExtValue& src); 180 void setri(paInt v) {setEmpty();seti(v);} 181 void setrd(double v) {setEmpty();setd(v);} 182 void seti(paInt v) {type=TInt;idata()=v;} 183 void setd(double v) {type=TDouble;ddata()=v;} 115 union { 116 paInt i; 117 double d; 118 SString *s; 119 ExtObject *o; 120 }; 121 paInt& idata() const {return (paInt&)i;}; 122 double& ddata() const {return (double&)d;}; 123 ExtObject& odata() const {return *o;}; 124 SString& sdata() const {return *s;}; 125 #endif 126 127 void* operator new(size_t s, void* mem){ return mem; } 128 void* operator new(size_t s){ return ::operator new(s); } 129 130 ExtValue() :type(TUnknown){} 131 ~ExtValue() { setEmpty(); } 132 ExtValue(paInt v) { seti(v); } 133 ExtValue(double v) { setd(v); } 134 ExtValue(const SString &v) { sets(v); } 135 ExtValue(const ExtObject &srco) { seto(srco); } 136 static ExtValue invalid() { ExtValue v; v.setInvalid(); return v; } 137 static const ExtValue& empty() { static const ExtValue v; return v; } 138 int compare(const ExtValue& src) const; 139 int operator==(const ExtValue& src) const; 140 void operator+=(const ExtValue& src); 141 void operator-=(const ExtValue& src); 142 void operator*=(const ExtValue& src); 143 void operator/=(const ExtValue& src); 144 void operator%=(const ExtValue& src); 145 void operator=(const ExtValue& src) 146 { 147 setr(src); 148 } 149 ExtValue(const ExtValue& src) 150 :type(TUnknown) { 151 set(src); 152 } 153 void setEmpty(); 154 void setInvalid() { setEmpty(); type = TInvalid; } 155 bool makeUnique() { return (type == TObj) && odata().makeUnique(); } //< @return false if nothing has changed 156 ExtPType getType() { return type; } 157 void *getObjectTarget(const char* classname, bool warn = true) const; 158 void setInt(paInt v) { if (type != TInt) setri(v); else idata() = v; } 159 void setDouble(double v) { if (type != TDouble) setrd(v); else ddata() = v; } 160 void setString(const SString &v) { if (type != TString) setrs(v); else sdata() = v; } 161 void setObject(const ExtObject &src) { if (type != TObj) setro(src); else odata() = src; } 162 static bool parseInt(const char* s, paInt &result, bool strict = false); 163 static bool parseDouble(const char* s, double &result); 164 static paInt getInt(const char* s, bool strict = false);//< @param strict=true will fail on floating point 165 static double getDouble(const char* s); 166 paInt getInt() const; 167 double getDouble() const; 168 SString getString() const; 169 const SString* getStringPtr() const;//< @return pointer to the internal sstring object or NULL if the current type is not string 170 SString serialize() const; 171 ExtObject getObject() const; 172 bool isNull() const { return (type == TUnknown) || ((type == TObj) && odata().isEmpty()); } 173 SString typeDescription() const;//< @return human readable type name (used in error messages) 174 const char* parseNumber(const char* in, ExtPType strict_type = TUnknown); 175 const char* deserialize(const char* in);//< @return first character after the succesfully parsed string or NULL if failed 176 const char* deserialize_inner(const char* in); 177 static ParamInterface *findDeserializableClass(const char* name); 178 static PtrListTempl<ParamInterface*> &getDeserializableClasses(); 179 template<typename T> class AddDeserializable 180 { 181 public: 182 AddDeserializable() { ExtValue::getDeserializableClasses() += &T::getStaticParam(); } 183 }; 184 185 static SString format(SString& fmt, const ExtValue **values, int count); 186 187 ExtValue getExtType(); 188 189 private: // setrx - release and set, setx - assume released 190 void setr(const ExtValue& src){ setEmpty(); set(src); } 191 void set(const ExtValue& src); 192 void setri(paInt v) { setEmpty(); seti(v); } 193 void setrd(double v) { setEmpty(); setd(v); } 194 void seti(paInt v) { type = TInt; idata() = v; } 195 void setd(double v) { type = TDouble; ddata() = v; } 184 196 #ifdef EXTVALUEUNION 185 void setrs(const SString &v) {setEmpty();sets(v);}186 void setro(const ExtObject &src) {setEmpty();seto(src);}187 void sets(const SString &v) {type=TString;new(data) SString(v);}188 void seto(const ExtObject &src) {type=TObj;new(data) ExtObject(src);}197 void setrs(const SString &v) { setEmpty(); sets(v); } 198 void setro(const ExtObject &src) { setEmpty(); seto(src); } 199 void sets(const SString &v) { type = TString; new(data)SString(v); } 200 void seto(const ExtObject &src) { type = TObj; new(data)ExtObject(src); } 189 201 #else 190 void setrs(const SString &v) {setEmpty();sets(v);}191 void setro(const ExtObject &src) {setEmpty();seto(src);}192 void sets(const SString &v) {type=TString;s=new SString(v);}193 void seto(const ExtObject &src) {type=TObj;o=new ExtObject(src);}202 void setrs(const SString &v) {setEmpty();sets(v);} 203 void setro(const ExtObject &src) {setEmpty();seto(src);} 204 void sets(const SString &v) {type=TString;s=new SString(v);} 205 void seto(const ExtObject &src) {type=TObj;o=new ExtObject(src);} 194 206 #endif 195 207
Note: See TracChangeset
for help on using the changeset viewer.