123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- #include "remvar.h"
- #include "conv.h"
- #define _IS_VALID_VT(vt) ((vt > CRemStringVariable::VT_Invalid) && (vt < CRemStringVariable::VT_Last))
- #define __min(x, y) ((x) < (y) ? (x) : (y))
- #define __max(x, y) ((x) > (y) ? (x) : (y))
- /////////////////////////////////////////////////////////////////////////////
- CRemStringVariable::CRemStringVariable(void *pData, size_t nCChData, VT vt, const std::type_info &rti, HSHM hShm, bool bIsDbPersitent, const char *pszName, int nIndex, CRemanent *pParent)
- : m_name(pszName), m_pszPath(NULL), m_nIndex(nIndex), m_vt(VT_Invalid), m_data({NULL}), m_cache({NULL}), m_nCbString(0),
- m_pParent(pParent), m_nUpdates(0), m_bMustLog(false), m_bIsDbPersitent(bIsDbPersitent), m_nCbVarpath(0), m_nCbLog(0)
- {
- if(!pData || !hShm || !nCChData || !_IS_VALID_VT(vt))
- {
- ASSERT(false);
- return;
- }
- m_vt = vt;
- m_data.pVoid = pData;
- m_hShm = hShm;
- memset(m_szLog, 0, sizeof(m_szLog));
- if( (rti == typeid(char)) ||
- (rti == typeid(signed char)) ||
- (rti == typeid(unsigned char)))
- {
- switch(vt)
- {
- case VT_Latin1:
- case VT_UTF_8:
- m_nCbBuffer = nCChData;
- m_cache.pVoid = ::malloc(m_nCbBuffer);
- zeroTerm(m_data, nCChData - 1);
- memcpy(m_cache.pVoid, m_data.pVoid, m_nCbBuffer);
- m_nCbString = strlen(m_cache.pszMbs);
- break;
- case VT_UTF_16:
- case VT_UTF_32:
- case VT_Unicode:
- ASSERT(false);
- return;
- default:
- ASSERT(false);
- return;
- }
- }
- else if(rti == typeid(char16_t))
- {
- switch(vt)
- {
- case VT_UTF_16:
- m_nCbBuffer = nCChData * sizeof(char16_t);
- m_cache.pVoid = malloc(m_nCbBuffer);
- zeroTerm(m_data, nCChData - 1);
- memcpy(m_cache.pVoid, m_data.pVoid, m_nCbBuffer);
- m_nCbString = wcs16len(m_cache.pszWc16) * sizeof(char16_t);
- break;
- case VT_Unicode:
- case VT_Latin1:
- case VT_UTF_8:
- case VT_UTF_32:
- ASSERT(false);
- return;
- default:
- ASSERT(false);
- return;
- }
- }
- else if(rti == typeid(char32_t))
- {
- switch(vt)
- {
- case VT_UTF_32:
- m_nCbBuffer = nCChData * sizeof(char32_t);
- m_cache.pVoid = malloc(m_nCbBuffer);
- zeroTerm(m_data, nCChData - 1);
- memcpy(m_cache.pVoid, m_data.pVoid, m_nCbBuffer);
- m_nCbString = wcs32len(m_cache.pszWc32) * sizeof(char32_t);
- break;
- case VT_Unicode:
- case VT_Latin1:
- case VT_UTF_8:
- case VT_UTF_16:
- ASSERT(false);
- return;
- default:
- ASSERT(false);
- return;
- }
- }
- else if(rti == typeid(wchar_t))
- {
- switch(vt)
- {
- case VT_Unicode:
- m_nCbBuffer = nCChData * sizeof(wchar_t);
- m_cache.pVoid = malloc(m_nCbBuffer);
- zeroTerm(m_data, nCChData - 1);
- memcpy(m_cache.pVoid, m_data.pVoid, m_nCbBuffer);
- m_nCbString = wcslen(m_cache.pszWcs) * sizeof(wchar_t);
- break;
- case VT_Latin1:
- case VT_UTF_8:
- case VT_UTF_16:
- case VT_UTF_32:
- ASSERT(false);
- return;
- default:
- ASSERT(false);
- return;
- }
- }
- else
- {
- ASSERT(false);
- }
- }
- CRemStringVariable::~CRemStringVariable(void)
- {
- }
- /////////////////////////////////////////////////////////////////////////////
- void CRemStringVariable::InitPath(CRemanent *pParent, const char *pszMemberName)
- {
- if(!pszMemberName)
- pszMemberName = "";
- if(pParent)
- {
- m_path = pParent->GetPath();
- if(m_path.size() > 0)
- m_path += "/";
- m_path += pszMemberName;
- if(m_nIndex >= 0)
- {
- char szIndex[32];
- sprintf(szIndex, "[%d]", m_nIndex);
- m_path += szIndex;
- }
- }
- else
- {
- m_path = pszMemberName;
- }
- m_pszPath = m_path.c_str();
- m_nCbVarpath = m_path.length();
- }
- #if 0
- static int _fnprintf(FILE *f, size_t n, const char * format, ...)
- {
- if(!n)
- return 0;
- int nRet;
- char *pszBuffer = malloc(n);
- va_list args;
- va_start (args, format);
- nRet = vsnprintf(pszBuffer, n, format, args);
- va_end (args);
- if(nRet > 0)
- nRet = (int)fwrite(pszBuffer, nRet, 1, f);
- free(pszBuffer);
- return nRet;
- }
- #endif
- bool CRemStringVariable::SaveJSON(FILE *f, int nIndent, bool bValueOnly, bool bWriteComma)
- {
- if(m_bIsDbPersitent)
- return true;
- size_t nToWrite;
- if(bWriteComma)
- {
- if(fprintf(f, ",") < 0)
- return false;
- }
- if(!bValueOnly)
- {
- if(fprintf(f, "\n") < 0)
- return false;
- if(nIndent > 0)
- {
- if(fprintf(f, "%*s", nIndent * _JSON_SPACES_PER_TAB, "") < 0)
- return false;
- }
- if(fprintf(f, "\"%s\": ", m_name.c_str()) < 0)
- return false;
- }
- switch(m_vt)
- {
- case VT_Latin1:
- case VT_UTF_8:
- if(fputc('\"', f) == EOF)
- return false;
- nToWrite = _MIN(m_nCbString, (m_nCbBuffer - 1));
- if(fwrite(m_cache.pszMbs, 1, nToWrite, f) != nToWrite)
- return false;
- if(fputc('\"', f) == EOF)
- return false;
- break;
- default:
- break;
- }
- return true;
- }
- void CRemStringVariable::CreateMembersTable(CRemVarTable &vt)
- {
- if(!m_bIsDbPersitent)
- vt.AddVar(static_cast<CRemanent*>(this));
- }
- bool CRemStringVariable::SetJSONValue(const Json::Value &jv, bool fLock)
- {
- if(jv.type() != Json::stringValue)
- return false;
- const char *pszStr = jv.asCString();
- if(!pszStr || !*pszStr)
- {
- memset(m_cache.pVoid, 0, m_nCbBuffer);
- if(fLock) Lock();
- memset(m_data.pVoid, 0, m_nCbBuffer);
- if(fLock) Unlock();
- return true;
- }
- size_t nLen = strlen(pszStr);
- switch(m_vt)
- {
- case VT_Latin1:
- Utf8ToLatin1(pszStr, nLen, m_cache.pszMbs, m_nCbBuffer);
- m_nCbString = strlen(m_cache.pszMbs);
- break;
- case VT_UTF_8:
- if(nLen >= m_nCbBuffer)
- nLen = m_nCbBuffer - 1;
- memset(m_cache.pszMbs, 0, m_nCbBuffer);
- memcpy(m_cache.pszMbs, pszStr, nLen);
- m_nCbString = nLen;
- break;
- case VT_UTF_16:
- Utf8ToUtf16(pszStr, nLen, m_cache.pszWc16, m_nCbBuffer / sizeof(char16_t));
- m_nCbString = wcs16len(m_cache.pszWc16) * sizeof(char16_t);
- break;
- case VT_UTF_32:
- Utf8ToUtf32(pszStr, nLen, m_cache.pszWc32, m_nCbBuffer / sizeof(char32_t));
- m_nCbString = wcs32len(m_cache.pszWc32) * sizeof(char32_t);
- break;
- case VT_Unicode:
- Utf8ToWcs(pszStr, nLen, m_cache.pszWcs, m_nCbBuffer / sizeof(wchar_t));
- m_nCbString = wcslen(m_cache.pszWcs) * sizeof(wchar_t);
- break;
- default:
- return false;
- }
- if(fLock) Lock();
- memcpy(m_data.pVoid, m_cache.pVoid, m_nCbBuffer);
- if(fLock) Unlock();
- return true;
- }
- unsigned long long CRemStringVariable::CheckUpdateShm(bool fLock)
- {
- CHECK_UPDATE_SHM_RETVAL rv = {1, 0};
- if(m_bIsDbPersitent)
- return rv.nRetval;
- size_t nCChBuf = 0;
- if(fLock)
- Lock();
- if(shmChanged(false))
- {
- switch(m_vt)
- {
- case VT_Latin1:
- nCChBuf = m_nCbBuffer - 1;
- zeroTerm(m_data, nCChBuf);
- m_nCbString = strlen(m_data.pszMbs);
- m_nCbLog = ::Latin1ToUtf8(m_data.pszMbs, m_nCbString, m_szLog, _RL_MAX_STRVAL_LENGTH);
- break;
- case VT_UTF_8:
- nCChBuf = m_nCbBuffer - 1;
- zeroTerm(m_data, nCChBuf);
- m_nCbString = strlen(m_data.pszMbs);
- m_nCbLog = _MIN(m_nCbString, _RL_MAX_STRVAL_LENGTH - 1);
- memcpy(m_szLog, m_data.pszMbs, m_nCbLog);
- m_szLog[m_nCbLog] = '\0';
- break;
- case VT_UTF_16:
- nCChBuf = m_nCbBuffer / sizeof(char16_t) - 1;
- zeroTerm(m_data, nCChBuf);
- m_nCbString = wcs16len(m_data.pszWc16) * sizeof(char16_t);
- m_nCbLog = ::Utf16ToUtf8(m_data.pszWc16, m_nCbString / sizeof(char16_t), m_szLog, _RL_MAX_STRVAL_LENGTH);
- break;
- case VT_UTF_32:
- nCChBuf = m_nCbBuffer / sizeof(char32_t) - 1;
- zeroTerm(m_data, nCChBuf);
- m_nCbString = wcs32len(m_data.pszWc32) * sizeof(char32_t);
- m_nCbLog = ::Utf32ToUtf8(m_data.pszWc32, m_nCbString / sizeof(char32_t), m_szLog, _RL_MAX_STRVAL_LENGTH);
- break;
- case VT_Unicode:
- nCChBuf = m_nCbBuffer / sizeof(wchar_t) - 1;
- zeroTerm(m_data, nCChBuf);
- m_nCbString = wcslen(m_data.pszWcs) * sizeof(wchar_t);
- m_nCbLog = ::WcsToUtf8(m_data.pszWcs, m_nCbString / sizeof(wchar_t), m_szLog, _RL_MAX_STRVAL_LENGTH);
- break;
- default:
- if(fLock)
- Unlock();
- return rv.nRetval;
- }
- memcpy(m_cache.pVoid, m_data.pVoid, m_nCbBuffer);
- rv.nUpdated = 1;
- }
- if(fLock)
- Unlock();
- if(rv.nUpdated)
- {
- m_bMustLog = true;
- m_nUpdates++;
- }
- return rv.nRetval;
- }
- void CRemStringVariable::Log(time_t ts, CRemLogger &rlogger)
- {
- if(!m_bIsDbPersitent && m_bMustLog)
- {
- rlogger.Log(m_pszPath, m_nCbVarpath, 0.0, m_szLog, m_nCbLog, ts, false);
- m_bMustLog = false;
- }
- }
- bool CRemStringVariable::shmChanged(bool fLock)
- {
- bool bRet;
- if(fLock) Lock();
- bRet = !!memcmp(m_cache.pVoid, m_data.pVoid, m_nCbString + 1);
- if(fLock) Unlock();
- return bRet;
- }
- void CRemStringVariable::Lock(void)
- {
- ::GfaIpcLockSHM(m_hShm);
- }
- void CRemStringVariable::Unlock(void)
- {
- ::GfaIpcUnlockSHM(m_hShm);
- }
- void CRemStringVariable::zeroTerm(volatile V_Ptr &rp, size_t at)
- {
- switch(m_vt)
- {
- case VT_Latin1:
- case VT_UTF_8:
- rp.pszMbs[at] = '\0';
- break;
- case VT_UTF_16:
- rp.pszWc16[at] = (char16_t)0;
- break;
- case VT_UTF_32:
- rp.pszWc32[at] = (char32_t)0;
- break;
- case VT_Unicode:
- rp.pszWcs[at] = L'\0';
- break;
- default:
- ASSERT(false);
- return;
- }
- }
|