// restvar.h : // #if !defined(AGD_RESTVAR_H__77EB9782_2B70_4713_A649_F4695F617197__INCLUDED_) #define AGD_RESTVAR_H__77EB9782_2B70_4713_A649_F4695F617197__INCLUDED_ #include #include #include #include #include #include #include #include #include #ifndef _LIBBUILD #include #include #else // _LIBBUILD #include "defines.h" #include "common/debug.h" #endif // _LIBBUILD extern "C" { #include } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // class CJson_t class CJson_t { public: CJson_t(json_t *pjt, bool bFree = true) : m_pjt(pjt), m_bFree(bFree) { } ~CJson_t(void) { if(m_pjt && m_bFree) json_decref(m_pjt); } CJson_t& operator = (json_t *pjt) { m_pjt = pjt; return *this; } operator json_t*(void) { return m_pjt;} operator const json_t*(void) const { return m_pjt;} bool IsValid(void) const { return !!m_pjt;} bool IsArray(void) { return json_is_array(m_pjt);} bool IsObject(void) { return json_is_object(m_pjt);} int Type(void) const { return IsValid() ? json_typeof(m_pjt) : -1;} private: json_t *m_pjt; bool m_bFree; }; ///////////////////////////////////////////////////////////////////////////// class CRestVarTable; class CRest { public: virtual void CreateMembersTable(CRestVarTable &vt) = 0; virtual void InitPath(CRest *pParent, const char *pszMemberName, int nIndex) = 0; virtual const char* GetPath(void) const = 0; virtual void GetValue(int nReqIndex, json_t* pjtMap) = 0; virtual json_t* GetValue(int nReqIndex) = 0; virtual json_t* SetValue(int nReqIndex, json_t* pjtVal) { UNUSED(pjtVal); return CreateStatusObject(nReqIndex, -1, "Cannot assign a value to an object!", GetPath()); } static json_t* CreateStatusObject(int nReqIndex, int nStatusCode, const char *pszStatusMsg = nullptr, const char *pszPath = nullptr) { if(!pszStatusMsg) pszStatusMsg = ""; CJson_t jtStatus(json_object(), false); CJson_t jtResponseType(json_integer(1)); CJson_t jtReqIndex(json_integer(nReqIndex)); CJson_t jtCode(json_integer(nStatusCode)); CJson_t jtMsg(json_string(pszStatusMsg)); json_object_set(jtStatus, "responseType", jtResponseType); json_object_set(jtStatus, "requestIndex", jtReqIndex); json_object_set(jtStatus, "code", jtCode); json_object_set(jtStatus, "message", jtMsg); if(pszPath && *pszPath) { CJson_t jtPath(json_string(pszPath)); json_object_set(jtStatus, "path", jtPath); } return jtStatus; } static json_t* CreateValueObject(int nReqIndex, const char *pszPath, int nIndex, int nValType, const char *pszValName, json_t *pjtVal) { CJson_t jtValue(json_object(), false); CJson_t jtResponseType(json_integer(0)); CJson_t jtReqIndex(json_integer(nReqIndex)); CJson_t jtPath(json_string(pszPath)); CJson_t jtIndex(json_integer(nIndex)); CJson_t jtType(json_integer(nValType)); CJson_t jtName(json_string(pszValName)); json_object_set(jtValue, "responseType", jtResponseType); json_object_set(jtValue, "requestIndex", jtReqIndex); json_object_set(jtValue, "path", jtPath); json_object_set(jtValue, "index", jtIndex); json_object_set(jtValue, "valType", jtType); json_object_set(jtValue, "valName", jtName); json_object_set(jtValue, "value", pjtVal); return jtValue; } static void CreatePath(CRest *pParent, const char *pszMemberName, int nIndex, std::string &rPath) { char szIndex[32] = {0}; if(!pszMemberName || !*pszMemberName) pszMemberName = "/"; if(nIndex >= 0) { sprintf(szIndex, "[%d]", nIndex); } if(pParent) { rPath = pParent->GetPath(); auto len = rPath.size(); if(len > 0) { auto rend = rPath.rbegin(); if(*rend != '/') rPath += "/"; } rPath += pszMemberName; rPath += szIndex; } else { rPath = pszMemberName; rPath += szIndex; } // printf("%s\n", rPath.c_str()); } }; ///////////////////////////////////////////////////////////////////////////// class CRestVarTable { public: typedef bool (*_PFNCMP)(const std::string&, const std::string&); public: CRestVarTable(void) : m_map(fncomp) { }; virtual ~CRestVarTable(void) { }; void AddVar(CRest *pVar) { if(pVar) m_map[std::string(pVar->GetPath())] = pVar; } CRest* Find(const char *key) const { std::map::const_iterator it = m_map.find(std::string(key)); if(it == m_map.end()) return nullptr; return it->second; } size_t size(void) { return m_map.size(); } private: static bool fncomp(const std::string &p1, const std::string &p2) { return p1.compare(p2) < 0; } private: std::map m_map; }; ///////////////////////////////////////////////////////////////////////////// class CRestVariable : public CRest { public: enum VT { VT_Invalid, VT_bool, VT_I1, VT_UI1, VT_I2, VT_UI2, VT_I4, VT_UI4, VT_I8, VT_UI8, VT_float, VT_double, VT_string }; typedef union { void *pVoid; bool *pBool; signed char *pI1; unsigned char *pUI1; signed short *pI2; unsigned short *pUI2; signed int *pI4; unsigned int *pUI4; signed long long *pI8; unsigned long long *pUI8; float *pFloat; double *pDouble; }V_Ptr; typedef union { bool boolVal; signed char I1Val; unsigned char UI1Val; signed short I2Val; unsigned short UI2Val; signed int I4Val; unsigned int UI4Val; signed long long I8Val; unsigned long long UI8Val; float FloatVal; double DoubleVal; }V_Val; public: CRestVariable(void *pData, const std::type_info &rti, HSHM hShm, const char *pszName, int nIndex, CRest *pParent); virtual ~CRestVariable(void); virtual void CreateMembersTable(CRestVarTable &vt); virtual void InitPath(CRest*pParent, const char *pszMemberName, int nIndex = -1); virtual const char* GetPath(void) const { return m_pszPath; } virtual void GetValue(int nReqIndex, json_t* pjtMap); virtual json_t* GetValue(int nReqIndex); virtual json_t* SetValue(int nReqIndex, json_t* pjtVal); private: void Lock(void); void Unlock(void); private: std::string m_name; std::string m_path; const char *m_pszPath; int m_nIndex; enum VT m_vt; volatile V_Ptr m_data; HSHM m_hShm; CRest *m_pParent; size_t m_nCbVarpath; }; ///////////////////////////////////////////////////////////////////////////// class CRestStringVariable : public CRest { public: typedef enum { VT_Invalid, // 0 VT_Latin1, // 1 VT_UTF_8, // 2 VT_UTF_16, // 3 VT_UTF_32, // 4 VT_Unicode, // 5 VT_Last }VT; typedef union { void *pVoid; char *pszMbs; char16_t *pszWc16; char32_t *pszWc32; wchar_t *pszWcs; }V_Ptr; public: CRestStringVariable(void *pData, size_t nCChData, VT vt, const std::type_info &rti, HSHM hShm, const char *pszName, int nIndex, CRest *pParent); virtual ~CRestStringVariable(void); virtual void CreateMembersTable(CRestVarTable &vt); virtual void InitPath(CRest*pParent, const char *pszMemberName, int nIndex = -1); virtual const char* GetPath(void) const { return m_pszPath; } virtual void GetValue(int nReqIndex, json_t* pjtMap); virtual json_t* GetValue(int nReqIndex); virtual json_t* SetValue(int nReqIndex, json_t* pjtVal); private: void Lock(void); void Unlock(void); void zeroTerm(volatile V_Ptr &rp, size_t at); private: std::string m_name; std::string m_path; const char *m_pszPath; int m_nIndex; VT m_vt; volatile V_Ptr m_data; size_t m_nCbBuffer; char *m_pszUTF8; size_t m_nCbUTF8; HSHM m_hShm; CRest *m_pParent; size_t m_nCbVarpath; }; ///////////////////////////////////////////////////////////////////////////// class CRestBitVariable : public CRest { public: enum VT { VT_Invalid, VT_bool, VT_I1, VT_UI1, VT_I2, VT_UI2, VT_I4, VT_UI4, VT_I8, VT_UI8, VT_float, VT_double, VT_string }; typedef union { void *pVoid; bool *pBool; signed char *pI1; unsigned char *pUI1; signed short *pI2; unsigned short *pUI2; signed int *pI4; unsigned int *pUI4; signed long long *pI8; unsigned long long *pUI8; float *pFloat; double *pDouble; }V_Ptr; typedef union { bool boolVal; signed char I1Val; unsigned char UI1Val; signed short I2Val; unsigned short UI2Val; signed int I4Val; unsigned int UI4Val; signed long long I8Val; unsigned long long UI8Val; float FloatVal; double DoubleVal; }V_Val; public: CRestBitVariable(void *pData, size_t nOffset, int nBitNr, HSHM hShm, const char *pszName, CRest *pParent); virtual ~CRestBitVariable(void); virtual void CreateMembersTable(CRestVarTable &vt); virtual void InitPath(CRest*pParent, const char *pszMemberName, int nIndex = -1); virtual const char* GetPath(void) const { return m_pszPath; } virtual void GetValue(int nReqIndex, json_t* pjtMap); virtual json_t* GetValue(int nReqIndex); virtual json_t* SetValue(int nReqIndex, json_t* pjtVal); private: void Lock(void); void Unlock(void); private: std::string m_name; std::string m_path; uint8_t *m_pShmByte; uint8_t m_mask; const char *m_pszPath; HSHM m_hShm; CRest *m_pParent; size_t m_nCbVarpath; }; ///////////////////////////////////////////////////////////////////////////// template class CRestArray : public CRest, public std::vector { public: CRestArray(void *pData, const std::type_info &rti, HSHM hShm, const char *pszName, size_t nElemCount, CRest *pParent) : m_name(pszName) { UNUSED(pParent); for(size_t i = 0; i < nElemCount; i++) { this->push_back(new T(&((V*)pData)[i], rti, hShm, pszName, i, static_cast(this))); } } CRestArray(void *pData, size_t nCChData, CRestStringVariable::VT vt, const std::type_info &rti, HSHM hShm, const char *pszName, size_t nElemCount, CRest *pParent) : m_name(pszName) { UNUSED(pParent); for(size_t i = 0; i < nElemCount; i++) { this->push_back(new T(((V*)pData) + nCChData * i, nCChData, vt, rti, hShm, pszName, i, static_cast(this))); } } CRestArray(void *pData, HSHM hShm, const char *pszName, size_t nElemCount, CRest *pParent) : m_name(pszName) { UNUSED(pParent); for(size_t i = 0; i < nElemCount; i++) { this->push_back(new T(&((V*)pData)[i], hShm, i, static_cast(this))); } } virtual ~CRestArray(void) { for(CRest *p : *this) { if(p) delete p; } } public: virtual void CreateMembersTable(CRestVarTable &vt) { vt.AddVar(static_cast(this)); for(CRest *p : *this) { if(p) p->CreateMembersTable(vt); } } virtual void InitPath(CRest *pParent, const char *pszMemberName, int nIndex = -1) { int i = 0; CRest::CreatePath(pParent, pszMemberName, nIndex, m_path); m_pszPath = m_path.c_str(); m_nCbVarpath = m_path.length(); for(CRest *p : *this) { if(p) p->InitPath(pParent, pszMemberName, i++); } } virtual const char* GetPath(void) const { return m_pszPath; } virtual void GetValue(int nReqIndex, json_t* pjtMap) { for(CRest *p : *this) { if(p) p->GetValue(nReqIndex, pjtMap); } } virtual json_t* GetValue(int nReqIndex) { CJson_t jtArr(json_array()); for(CRest *p : *this) { if(p) json_array_append_new(jtArr, p->GetValue(nReqIndex)); } CJson_t jtObj(json_object(), false); CJson_t jtPath(json_string(m_pszPath)); CJson_t jtIndex(json_integer(-1)); CJson_t jtType(json_integer(jtArr.Type())); CJson_t jtName(json_string(m_name.c_str())); json_object_set(jtObj, "path", jtPath); json_object_set(jtObj, "index", jtIndex); json_object_set(jtObj, "valType", jtType); json_object_set(jtObj, "valName", jtName); json_object_set(jtObj, "value", jtArr); return jtObj; } virtual json_t* SetValue(int nReqIndex, json_t* pjtVal) { UNUSED(pjtVal); return CreateStatusObject(nReqIndex, -1, "Cannot assign a value to an array!", GetPath()); } private: std::string m_name; std::string m_path; const char *m_pszPath; size_t m_nCbVarpath; }; ///////////////////////////////////////////////////////////////////////////// #endif // !defined(AGD_RESTVAR_H__77EB9782_2B70_4713_A649_F4695F617197__INCLUDED_)