00001
00002
00003
00004 #ifndef _VAR_H
00005 #define _VAR_H
00006
00007 #include "util.h"
00008 #include "arr.h"
00009 #include "str.h"
00010 #include <math.h>
00011
00012 #define VNULL Variant::vNull
00013 #define VEMPTY Variant::vEmpty
00014
00015 #define VAR_PATH_DELIM "."
00016
00017 namespace jvar
00018 {
00019
00020 class VarFuncObj;
00021
00027 class Variant
00028 {
00029 public:
00030 typedef int (*Compare)(const Variant*, const Variant*);
00031
00032 enum Type
00033 {
00034 V_EMPTY,
00035 V_NULL,
00036 V_INT,
00037 V_BOOL,
00038 V_DOUBLE,
00039 V_STRING,
00040 V_ARRAY,
00041 V_OBJECT,
00042 V_FUNCTION,
00043 V_POINTER
00044 };
00045
00046 public:
00047
00051 inline Variant()
00052 {
00053 mData.type = V_EMPTY;
00054 mData.flags = 0;
00055 }
00056
00060 inline Variant(longint i)
00061 {
00062 mData.type = V_INT;
00063 mData.intData = i;
00064 }
00065
00069 inline Variant(int i)
00070 {
00071 mData.type = V_INT;
00072 mData.intData = (longint)i;
00073 }
00074
00078 inline Variant(double d)
00079 {
00080 mData.type = V_DOUBLE;
00081 mData.dblData = d;
00082 }
00083
00087 inline Variant(std::string s)
00088 {
00089 mData.type = V_STRING;
00090
00091
00092
00093
00094 new (&mData.strMemData) std::string(s);
00095 }
00096
00100 inline Variant(const char* s)
00101 {
00102 mData.type = V_STRING;
00103
00104
00105
00106
00107 new (&mData.strMemData) std::string(s);
00108 }
00109
00113 inline Variant(Variant const& src)
00114 {
00115 mData.type = V_EMPTY;
00116 *this = src;
00117 }
00118
00122 inline ~Variant()
00123 {
00124 (void)deleteData();
00125 }
00126
00130 inline Variant& operator=(const Variant& src)
00131 {
00132 copyFrom(&src);
00133 return *this;
00134 }
00135
00139 inline Variant& operator=(const Variant* src)
00140 {
00141 copyFrom(src);
00142 return *this;
00143 }
00144
00148 inline Variant& operator=(const char* src)
00149 {
00150 assignStr(src);
00151 return *this;
00152 }
00153
00157 inline Variant& operator=(const std::string& src)
00158 {
00159 assignStr(src);
00160 return *this;
00161 }
00162
00166 inline Variant& operator=(bool src)
00167 {
00168 assignBool(src);
00169 return *this;
00170 }
00171
00175 inline Variant& operator=(longint src)
00176 {
00177 assignInt(src);
00178 return *this;
00179 }
00180
00184 inline Variant& operator=(int src)
00185 {
00186 assignInt((longint)src);
00187 return *this;
00188 }
00189
00193 inline Variant& operator=(double src)
00194 {
00195 assignDbl(src);
00196 return *this;
00197 }
00198
00202 inline Variant& operator=(float src)
00203 {
00204 assignDbl((double)src);
00205 return *this;
00206 }
00207
00220 inline Variant& operator+=(const Variant& rhs)
00221 {
00222 internalAdd(*this, rhs);
00223 return *this;
00224 }
00225
00229 inline Variant& operator+=(longint rhs)
00230 {
00231 Variant r(rhs);
00232 internalAdd(*this, r);
00233 return *this;
00234 }
00235
00239 inline Variant& operator+=(int rhs)
00240 {
00241 Variant r((longint)rhs);
00242 internalAdd(*this, r);
00243 return *this;
00244 }
00245
00249 inline Variant& operator+=(const char* rhs)
00250 {
00251 Variant r(rhs);
00252 internalAdd(*this, r);
00253 return *this;
00254 }
00255
00259 inline Variant& operator+=(const std::string& rhs)
00260 {
00261 Variant r(rhs);
00262 internalAdd(*this, r);
00263 return *this;
00264 }
00265
00269 inline Variant& operator+=(double rhs)
00270 {
00271 Variant r(rhs);
00272 internalAdd(*this, r);
00273 return *this;
00274 }
00275
00280 inline Variant& operator++()
00281 {
00282 Variant r(1);
00283 internalAdd(*this, r);
00284 return *this;
00285 }
00286
00291 inline Variant operator++(int)
00292 {
00293 Variant r(1);
00294 internalAdd(*this, r);
00295 return *this;
00296 }
00297
00301 inline longint toInt() const
00302 {
00303 return makeInt();
00304 }
00305
00309 inline double toDouble() const
00310 {
00311 return makeDbl();
00312 }
00313
00317 inline bool toBool() const
00318 {
00319 return makeBool();
00320 }
00321
00325 inline operator longint() const
00326 {
00327 return makeInt();
00328 }
00329
00333 inline operator double() const
00334 {
00335 return makeDbl();
00336 }
00337
00341 inline operator bool() const
00342 {
00343 return makeBool();
00344 }
00345
00349 inline operator const char*()
00350 {
00351 return c_str();
00352 }
00353
00357 inline const char* c_str() const
00358 {
00359 if (mData.type == V_STRING)
00360 {
00361 return mData.strData()->c_str();
00362 }
00363 return NULL;
00364 }
00365
00375 std::string& s();
00376
00383 std::string toString() const;
00384
00393 std::string toFixed(int digs = 0) const;
00394
00400 std::string toJsonString() const;
00401
00409 bool parseJson(const char* jsontxt);
00410
00414 void format(const char* fmt, ...);
00415
00421 inline Type type() const
00422 {
00423 return (Type)(mData.type);
00424 }
00425
00431 const char* typeName() const;
00432
00433 inline bool isNull() const
00434 {
00435 return (mData.type == V_NULL);
00436 }
00437 inline bool isEmpty() const
00438 {
00439 return (mData.type == V_EMPTY);
00440 }
00441 inline bool isObject() const
00442 {
00443 return (mData.type == V_OBJECT);
00444 }
00445 inline bool isArray() const
00446 {
00447 return (mData.type == V_ARRAY);
00448 }
00449 inline bool isPointer() const
00450 {
00451 return (mData.type == V_POINTER);
00452 }
00453 inline bool isNaN()
00454 {
00455 if (mData.type == V_DOUBLE)
00456 {
00457 return isnan(mData.dblData);
00458 }
00459 else if (mData.type == V_INT)
00460 {
00461 return false;
00462 }
00463 return true;
00464 }
00465
00470 int length() const;
00471
00475 Variant& operator[](int i);
00476
00480 const Variant& operator[](int i) const;
00481
00485 Variant& operator[](const char* key);
00486
00490 const Variant& operator[](const char* key) const;
00491
00500 Variant& path(const char* pathkey);
00501
00510 inline Variant& path(const std::string& pathkey)
00511 {
00512 return path(pathkey.c_str());
00513 }
00514
00520 void createArray(const char* initvalue = NULL);
00521
00529 Variant* append(const Variant& elem = VEMPTY);
00530
00534 inline void push(const Variant& elem)
00535 {
00536 (void)append(elem);
00537 }
00538
00544 Variant pop();
00545
00551 Variant shift();
00552
00558 void sort(Compare comp);
00559
00565 void createObject(const char* initvalue = NULL);
00566
00575 Variant& addProperty(const char* key, const Variant& value = vEmpty);
00576
00584 bool hasProperty(const char* key);
00585
00593 const char* getKey(int n);
00594
00600 void createFunction(Variant (*func)(Variant& env, Variant& arg));
00601
00610 bool addEnv(const char* varname, const Variant& value = vEmpty);
00611 Variant operator() ();
00612 Variant operator() (const Variant& value1);
00613 Variant operator() (const Variant& value1, const Variant& value2);
00614 Variant operator() (const Variant& value1, const Variant& value2, const Variant& value3);
00615 Variant operator() (const Variant& value1, const Variant& value2, const Variant& value3, const Variant& value4);
00616
00624 inline bool forEach(Iter<Variant>& iter)
00625 {
00626 if (mData.type == V_ARRAY)
00627 {
00628 return mData.arrayData->forEach(iter);
00629 }
00630 else if (mData.type == V_OBJECT)
00631 {
00632 return mData.objectData->forEach(iter);
00633 }
00634 return false;
00635 }
00636
00640 inline void clear()
00641 {
00642 (void)deleteData();
00643 }
00644
00648 inline void setModified()
00649 {
00650 setFlag(mData.flags, VF_MODIFIED);
00651 }
00652
00656 inline void clearModified()
00657 {
00658 clearFlag(mData.flags, VF_MODIFIED);
00659 }
00660
00664 inline bool isModified()
00665 {
00666 return isFlagSet(mData.flags, VF_MODIFIED);
00667 }
00668
00669 private:
00670
00671 enum Flags
00672 {
00673 VF_MODIFIED = 0x1
00674 };
00675
00676 #pragma pack(push, 4)
00677 struct VarData
00678 {
00679 ushortint type;
00680 shortint flags;
00681 union
00682 {
00683 longint intData;
00684 double dblData;
00685 bool boolData;
00686 char strMemData[sizeof(std::string)];
00687 ObjArray<Variant>* arrayData;
00688 PropArray<Variant>* objectData;
00689 VarFuncObj* funcData;
00690 Variant* vptrData;
00691 };
00692
00693 std::string* strData() const
00694 {
00695 return (std::string*)&strMemData;
00696 }
00697 };
00698 #pragma pack(pop)
00699
00700 VarData mData;
00701
00702 private:
00703
00704 bool deleteData();
00705 void copyFrom(const Variant* src);
00706
00707 void assignInt(longint src);
00708 void assignDbl(double src);
00709 void assignBool(bool src);
00710 void assignStr(const char* src);
00711 void assignStr(const std::string& src);
00712
00713 longint makeInt() const;
00714 double makeDbl() const;
00715 inline bool makeBool() const
00716 {
00717 return makeInt() == 0 ? false : true;
00718 }
00719 void makeString(std::string& s, int level, bool json);
00720
00721 void jsonifyStr(std::string& s);
00722 inline void appendQuote(std::string& s, Type type)
00723 {
00724 if (type == V_STRING)
00725 {
00726 s += '"';
00727 }
00728 }
00729 inline void appendNewline(std::string& s, int level, bool json)
00730 {
00731 if (json)
00732 {
00733 s += '\n';
00734 s += std::string(level, '\t');
00735 }
00736 }
00737
00738 static const KeywordArray::Entry sTypeNames[];
00739
00740 public:
00741 static Variant vEmpty;
00742 static Variant vNull;
00743
00744 public:
00747 Variant(Type type)
00748 {
00749 mData.type = type;
00750 }
00751
00752 void internalAdd(const Variant& lhs, const Variant& rhs);
00753 void internalSetPtr(const Variant* v);
00754
00756 };
00757
00759 class VarFuncObj
00760 {
00761 public:
00762 VarFuncObj() :
00763 mFunc(NULL)
00764 {
00765 }
00766
00767 Variant mEnv;
00768 Variant (*mFunc)(Variant& env, Variant& arg);
00769 };
00777 inline Variant operator+(const Variant& lhs, const Variant& rhs)
00778 {
00779 Variant res;
00780 res.internalAdd(lhs, rhs);
00781 return res;
00782 }
00783
00789 inline Variant operator+(const Variant& lhs, const char* rhs)
00790 {
00791 Variant res;
00792 Variant r(rhs);
00793 res.internalAdd(lhs, r);
00794 return res;
00795 }
00796
00802 inline Variant operator+(const char* lhs, const Variant& rhs)
00803 {
00804 Variant res;
00805 Variant l(lhs);
00806 res.internalAdd(l, rhs);
00807 return res;
00808 }
00809
00815 inline Variant operator+(const std::string& lhs, const Variant& rhs)
00816 {
00817 Variant res;
00818 Variant l(lhs);
00819 res.internalAdd(l, rhs);
00820 return res;
00821 }
00822
00828 inline Variant operator+(const Variant& lhs, const std::string& rhs)
00829 {
00830 Variant res;
00831 Variant r(rhs);
00832 res.internalAdd(lhs, r);
00833 return res;
00834 }
00835
00841 inline Variant operator+(const Variant& lhs, longint rhs)
00842 {
00843 Variant res;
00844 Variant r(rhs);
00845 res.internalAdd(lhs, r);
00846 return res;
00847 }
00848
00854 inline Variant operator+(const Variant& lhs, int rhs)
00855 {
00856 return operator+(lhs, (longint)rhs);
00857 }
00858
00864 inline Variant operator+(const Variant& lhs, double rhs)
00865 {
00866 Variant res;
00867 Variant r(rhs);
00868 res.internalAdd(lhs, r);
00869 return res;
00870 }
00871
00877 inline Variant operator+(double lhs, const Variant& rhs)
00878 {
00879 Variant res;
00880 Variant l(lhs);
00881 res.internalAdd(l, rhs);
00882 return res;
00883 }
00884
00885 }
00886
00887 #endif // _VAR_H