123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- #include "shmvar.h"
- #include <gfa/svc/common/conv.h>
- #include <QDebug>
- #define _IS_VALID_VT(vt) ((vt > CShmStringVariable::VT_Invalid) && (vt < CShmStringVariable::VT_Last))
- #define __min(x, y) ((x) < (y) ? (x) : (y))
- #define __max(x, y) ((x) > (y) ? (x) : (y))
- CShmStringVariable::CShmStringVariable(void *pData, size_t nCChData, VT vt, const std::type_info &rti, HSHM hShm, const char *pszName, int nIndex, QObject *pParent)
- : QObject(pParent), m_vt(VT_Invalid), m_data({NULL}), m_cache({NULL}), m_nCbString(0), m_varName(pszName)
- {
- if(!pData || !hShm || !nCChData || !_IS_VALID_VT(vt))
- {
- Q_ASSERT_X(false, "CShmStringVariable::CShmStringVariable", "Invalid parameter!");
- return;
- }
- m_vt = vt;
- m_data.pVoid = pData;
- m_hShm = hShm;
- setObjectName(QStringLiteral("CShmStringVariable"));
- if((m_nIndex = nIndex) >= 0)
- {
- m_varName += QString("%1%2%3").arg('[').arg(nIndex).arg(']');
- }
- 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:
- Q_ASSERT_X(false, "CShmStringVariable::CShmStringVariable", "data type does not support encoding type!");
- return;
- default:
- Q_ASSERT_X(false, "CShmStringVariable::CShmStringVariable", "Invalid string type!");
- 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:
- Q_ASSERT_X(false, "CShmStringVariable::CShmStringVariable", "data type does not support encoding type!");
- return;
- default:
- Q_ASSERT_X(false, "CShmStringVariable::CShmStringVariable", "Invalid string type!");
- 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:
- Q_ASSERT_X(false, "CShmStringVariable::CShmStringVariable", "data type does not support encoding type!");
- return;
- default:
- Q_ASSERT_X(false, "CShmStringVariable::CShmStringVariable", "Invalid string type!");
- 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:
- Q_ASSERT_X(false, "CShmStringVariable::CShmStringVariable", "data type does not support encoding type!");
- return;
- default:
- Q_ASSERT_X(false, "CShmStringVariable::CShmStringVariable", "Invalid string type!");
- return;
- }
- }
- else
- {
- Q_ASSERT_X(false, "CShmStringVariable::CShmStringVariable", "Unrecognized data type!");
- }
- }
- CShmStringVariable::~CShmStringVariable(void)
- {
- if(m_cache.pVoid)
- ::free(m_cache.pVoid);
- }
- void CShmStringVariable::valRaw(QString &v)
- {
- switch(m_vt)
- {
- case VT_Latin1:
- v = QString::fromLatin1(m_data.pszMbs, m_nCbString);
- break;
- case VT_UTF_8:
- v = QString::fromUtf8(m_data.pszMbs, m_nCbString);
- break;
- case VT_UTF_16:
- v = QString::fromUtf16(m_data.pszWc16, m_nCbString / sizeof(char16_t));
- break;
- case VT_UTF_32:
- v = QString::fromUcs4(m_data.pszWc32, m_nCbString / sizeof(char32_t));
- break;
- case VT_Unicode:
- v = QString::fromWCharArray(m_data.pszWcs, m_nCbString / sizeof(wchar_t));
- break;
- default:
- // Q_ASSERT_X(false, "CShmStringVariable::valRaw", "Unrecognized string type!");
- break;
- }
- }
- QString CShmStringVariable::val(void)
- {
- QString v;
- Lock();
- valRaw(v);
- Unlock();
- return v;
- }
- void CShmStringVariable::setVal(const QString &val)
- {
- QByteArray ba;
- QVector<uint> vec;
- size_t nCbVal = 0, nCChVal = 0;
- wchar_t *pszData;
- const void *pData;
- switch(m_vt)
- {
- case VT_Latin1:
- ba = val.toLatin1();
- nCbVal = ba.size();
- nCbVal = __min(nCbVal, m_nCbBuffer - 1);
- nCChVal = nCbVal;
- pData = ba.data();
- break;
- case VT_UTF_8:
- ba = val.toUtf8();
- nCbVal = ba.size();
- nCbVal = __min(nCbVal, m_nCbBuffer - 1);
- nCChVal = nCbVal;
- pData = ba.data();
- break;
- case VT_UTF_16:
- nCbVal = val.size() * sizeof(char16_t);
- nCbVal = __min(nCbVal, m_nCbBuffer - sizeof(char16_t));
- nCChVal = nCbVal / sizeof(char16_t);
- pData = val.utf16();
- break;
- case VT_UTF_32:
- vec = val.toUcs4();
- nCbVal = vec.size() * sizeof(char32_t);
- nCbVal = __min(nCbVal, m_nCbBuffer - sizeof(char32_t));
- nCChVal = nCbVal / sizeof(char32_t);
- pData = vec.data();
- break;
- case VT_Unicode:
- nCChVal = val.size();
- nCbVal = nCChVal * sizeof(wchar_t);
- pszData = (wchar_t*)alloca(nCbVal);
- val.toWCharArray(pszData);
- nCbVal = __min(nCbVal, m_nCbBuffer - sizeof(wchar_t));
- nCChVal = nCbVal / sizeof(wchar_t);
- pData = pszData;
- break;
- default:
- Q_ASSERT_X(false, "CShmStringVariable::setVal", "Unrecognized string type!");
- return;
- }
-
- Lock();
- m_nCbString = nCbVal;
- memcpy(m_cache.pVoid, pData, m_nCbString);
- zeroTerm(m_cache, nCChVal);
-
- if(shmChanged(false))
- {
- memcpy(m_data.pVoid, m_cache.pVoid, m_nCbString);
- zeroTerm(m_data, nCChVal);
- emitChanged(false);
- }
- Unlock();
- }
- void CShmStringVariable::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:
- // Q_ASSERT_X(false, "CShmStringVariable::zeroTerm", "Unrecognized string type!");
- return;
- }
- }
- unsigned int CShmStringVariable::vt(void) const
- {
- return CShmVariable::VT_string;
- }
- unsigned long long CShmStringVariable::CheckUpdateShm(bool fLock)
- {
- CHECK_UPDATE_SHM_RETVAL rv = {1, 0};
- size_t nCChBuf = 0;
- if(fLock)
- Lock();
-
- if(shmChanged(false))
- {
- switch(m_vt)
- {
- case VT_Latin1:
- case VT_UTF_8:
- nCChBuf = m_nCbBuffer - 1;
- zeroTerm(m_data, nCChBuf);
- m_nCbString = strlen(m_data.pszMbs);
- 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);
- 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);
- break;
- case VT_Unicode:
- nCChBuf = m_nCbBuffer / sizeof(wchar_t) - 1;
- zeroTerm(m_data, nCChBuf);
- m_nCbString = wcslen(m_data.pszWcs) * sizeof(wchar_t);
- break;
- default:
- return rv.nRetval;
- }
- memcpy(m_cache.pVoid, m_data.pVoid, m_nCbBuffer);
- emitChanged(false);
- rv.nUpdated = 1;
- }
- if(fLock)
- Unlock();
- return rv.nRetval;
- }
- bool CShmStringVariable::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 CShmStringVariable::Lock(void)
- {
- ::GfaIpcLockSHM(m_hShm);
- // qDebug() << "CShmStringVariable::Lock";
- }
- void CShmStringVariable::Unlock(void)
- {
- // qDebug() << "CShmStringVariable::Unlock";
- ::GfaIpcUnlockSHM(m_hShm);
- }
- void CShmStringVariable::emitChanged(bool fLock)
- {
- // qDebug() << "CShmStringVariable: val changed!";
- if(fLock)
- emit valChanged(val());
- else
- {
- QString v;
- valRaw(v);
- emit valChanged(v);
- }
- }
|