33 #include "private/ArnBasicItem_p.hpp" 38 #include <QDataStream> 39 #include <QThreadStorage> 40 #include <QCoreApplication> 45 QAtomicInt ArnBasicItemPrivate::_idCount(1);
48 ArnBasicItemPrivate::ArnBasicItemPrivate()
50 _reference = arnNullptr;
51 _eventHandler = arnNullptr;
52 _pendingEvChain = arnNullptr;
53 _id = quint32(_idCount.fetchAndAddRelaxed(1));
55 _useUncrossed =
false;
56 _isStdEvHandler =
true;
64 _syncModeLinkShare =
true;
68 ArnBasicItemPrivate::~ArnBasicItemPrivate()
75 _heritage |= heritage;
82 void ArnBasicItem::init()
87 d->_eventHandler = getThreadEventHandler();
112 void ArnBasicItem::setupOpenItem(
bool isFolder)
117 addMode( Arn::ObjectMode::fromInt( d->_mode));
121 bool ArnBasicItem::openWithFlags(
const QString& path,
Arn::LinkFlags linkFlags)
129 :
Arn::ObjectSyncMode();
131 if (!_link)
return false;
134 sendArnEventLink( &ev);
135 ArnM::changeRefCounter(+1);
137 _link->subscribe(
this);
138 setupOpenItem( _link->isFolder());
139 #ifdef ArnBasicItem_INCPATH 159 _link->unsubscribe(
this);
163 sendArnEventLink( &ev);
164 ArnM::changeRefCounter(-1);
166 if (d->_pendingEvChain) {
167 d->_pendingEvChain->setTargetMutex( arnNullptr);
168 d->_pendingEvChain->inhibitPendingChain();
186 return _link != arnNullptr;
192 if (!_link)
return false;
194 return _link->isFolder();
200 if (!_link)
return false;
202 return _link->isProvider();
210 return _link->type();
216 if (!_link)
return 0;
218 return _link->linkId();
224 if (!_link)
return -1;
226 return qMax( _link->refCount(), 0);
234 d->_syncModeLinkShare = linkShare;
236 if (d->_syncModeLinkShare && _link) {
237 _link->addSyncMode( Arn::ObjectSyncMode::fromInt( d->_syncMode));
242 void ArnBasicItem::resetOnlyEcho()
246 d->_isOnlyEcho =
true;
250 void ArnBasicItem::addIsOnlyEcho( quint32 sendId)
254 if (sendId != d->_id)
255 d->_isOnlyEcho =
false;
259 bool ArnBasicItem::isOnlyEcho()
const 263 return d->_isOnlyEcho;
267 quint32 ArnBasicItem::localUpdateCount()
const 269 if (!_link)
return 0;
271 return _link->localUpdateCount();
275 uint ArnBasicItem::retireType()
277 return _link ? _link->retireType() : uint( ArnLink::RetireType::None);
285 if (d->_syncModeLinkShare && _link) {
286 return _link->syncMode();
288 return Arn::ObjectSyncMode::fromInt( d->_syncMode);
297 if (!_link)
return *
this;
299 if (_link->isBiDirMode())
return *
this;
302 ArnLink* twinLink = ArnM::addTwin( _link->linkPath(), _link,
syncMode());
315 return _link->isBiDirMode();
324 d->_ignoreSameValue =
false;
325 if (!_link)
return *
this;
327 if (_link->isPipeMode())
return *
this;
330 ArnLink* twinLink = ArnM::addTwin( _link->linkPath(), _link,
syncMode());
331 _link->setPipeMode(
true);
344 return _link->isPipeMode();
353 if (!_link)
return *
this;
355 _link->setSaveMode(
true);
366 return _link->isSaveMode();
374 _link->setAtomicOpProvider(
true);
381 if (!_link)
return false;
383 return _link->isAtomicOpProvider();
427 if (mode.is( mode.
Pipe)) {
430 else if (mode.is( mode.
BiDir)) {
433 if (mode.is( mode.
Save)) {
450 if (!link)
return Arn::ObjectMode::fromInt( d->_mode);
452 return link->getMode();
460 d->_ignoreSameValue =
isPipeMode() ? false : isIgnore;
468 return d->_ignoreSameValue;
474 if (!_link)
return QString();
476 return _link->linkPath( nameF);
482 if (!_link)
return QString();
484 return _link->linkName( nameF);
500 return d->_reference;
514 ArnLinkHandle handle;
521 if (!data.isEmpty()) {
522 if (data.at(0) < 32) {
523 switch (Arn::ExportCode::fromInt( data.at(0))) {
526 QDataStream stream( data);
529 stream >> dummy >> value;
530 setValue( value, ignoreSame, handleData);
534 int sepPos = data.indexOf(
':', 1);
535 Q_ASSERT(sepPos > 0);
537 QByteArray typeName( data.constData() + 1, sepPos - 1);
538 int type = QMetaType::type( typeName.constData());
540 errorLog( QString(
"Import unknown text type:") + typeName.constData(),
544 QVariant value( QString::fromUtf8( data.constData() + sepPos + 1,
545 data.size() - sepPos - 1));
546 if (!value.convert( QVariant::Type(
type))) {
547 errorLog( QString(
"Can't' import data type:") + typeName.constData(),
552 setValue( value, ignoreSame, handleData);
557 errorLog( QString(
"Import not same DataStream version"),
561 int sepPos = data.indexOf(
':', 3);
562 Q_ASSERT(sepPos > 0);
564 QByteArray typeName( data.constData() + 3, sepPos - 3);
565 int type = QMetaType::type( typeName.constData());
567 errorLog( QString(
"Import unknown binary type:") + typeName.constData(),
571 #if QT_VERSION >= 0x050000 572 void* valData = QMetaType::create(
type);
574 void* valData = QMetaType::construct(
type);
577 QDataStream stream( data);
579 stream.skipRawData( sepPos + 1);
580 #if QT_VERSION >= 0x060000 582 bool isOk = mt.load( stream, valData);
584 bool isOk = QMetaType::load( stream,
type, valData);
587 errorLog( QString(
"Can't' import binary type:") + typeName.constData(),
589 QMetaType::destroy(
type, valData);
593 #if QT_VERSION >= 0x060000 594 QVariant value( mt, valData);
596 QVariant value(
type, valData);
598 QMetaType::destroy(
type, valData);
600 setValue( value, ignoreSame, handleData);
604 setValue( data.mid(1), ignoreSame, handleData);
607 handleData.flags().set( ArnLinkHandle::Flags::Text);
608 setValue( data.mid(1), ignoreSame, handleData);
618 handleData.flags().set( ArnLinkHandle::Flags::Text);
619 setValue( data, ignoreSame, handleData);
625 if (!_link)
return QByteArray();
632 QByteArray typeName( value.typeName());
633 int type = QMetaType::type( typeName.constData());
635 errorLog( QString(
"Export unknown type:") + typeName.constData(),
640 if (value.canConvert( QVariant::String)) {
644 retVal += value.toString().toUtf8();
647 QDataStream stream( &retVal, QIODevice::WriteOnly);
652 stream.writeRawData( typeName.constData(), typeName.size());
653 stream << quint8(
':');
654 if (!QMetaType::save( stream,
type, value.constData())) {
655 errorLog( QString(
"Can't export type:") + typeName,
666 if (!retVal.isEmpty()) {
667 if (retVal.at(0) < 32) {
679 if (!_link)
return QString();
681 return _link->toString( isOk);
687 if (!_link)
return QByteArray();
689 return _link->toByteArray( isOk);
695 if (!_link)
return QVariant();
697 return _link->toVariant( isOk);
703 if (!_link)
return 0;
705 return _link->toInt( isOk);
711 if (!_link)
return 0.0;
713 return _link->toReal( isOk);
719 if (!_link)
return 0.0;
721 return _link->toReal( isOk);
727 if (!_link)
return false;
729 return _link->toInt( isOk) != 0;
735 if (!_link)
return 0;
737 return _link->toByteArray( isOk).toUInt( isOk);
743 if (!_link)
return 0;
745 return _link->toByteArray( isOk).toLongLong( isOk);
751 if (!_link)
return 0;
753 return _link->toByteArray( isOk).toULongLong( isOk);
843 ArnLink *link = other._link;
846 switch (link->type()) {
848 this->
setValue( link->toInt(), ignoreSame);
851 this->
setValue( link->toReal(), ignoreSame);
854 this->
setValue( link->toString(), ignoreSame);
857 this->
setValue( link->toByteArray(), ignoreSame);
860 this->
setValue( link->toVariant(), ignoreSame);
866 errorLog( QString(
"Assigning Null"),
872 errorLog( QString(
"Assigning unknown type"),
877 errorLog( QString(
"Assigning"),
890 ArnLink* holderLink = _link->holderLink( d->_useUncrossed);
892 if ((value == holderLink->toInt( &isOk)) && isOk) {
893 holderLink->setIgnoredValue();
897 d->_isAssigning =
true;
898 _link->setValue( value, d->_id, d->_useUncrossed);
899 d->_isAssigning =
false;
902 errorLog( QString(
"Assigning int:") + QString::number( value),
915 ArnLink* holderLink = _link->holderLink( d->_useUncrossed);
917 if ((value == holderLink->toReal( &isOk)) && isOk) {
918 holderLink->setIgnoredValue();
922 d->_isAssigning =
true;
923 _link->setValue( value, d->_id, d->_useUncrossed);
924 d->_isAssigning =
false;
927 errorLog( QString(
"Assigning ARNREAL:") + QString::number( value),
940 ArnLink* holderLink = _link->holderLink( d->_useUncrossed);
942 if ((value == (holderLink->toInt( &isOk) != 0)) && isOk) {
943 holderLink->setIgnoredValue();
947 d->_isAssigning =
true;
948 _link->setValue( value ? 1 : 0, d->_id, d->_useUncrossed);
949 d->_isAssigning =
false;
952 errorLog( QString(
"Assigning bool:") + QString::number( value),
965 ArnLink* holderLink = _link->holderLink( d->_useUncrossed);
967 if ((value == holderLink->toString( &isOk)) && isOk) {
968 holderLink->setIgnoredValue();
972 d->_isAssigning =
true;
973 _link->setValue( value, d->_id, d->_useUncrossed);
974 d->_isAssigning =
false;
977 errorLog( QString(
"Assigning string:") + value,
990 ArnLink* holderLink = _link->holderLink( d->_useUncrossed);
992 if ((value == holderLink->toByteArray( &isOk)) && isOk) {
993 holderLink->setIgnoredValue();
997 d->_isAssigning =
true;
998 _link->setValue( value, d->_id, d->_useUncrossed);
999 d->_isAssigning =
false;
1002 errorLog( QString(
"Assigning bytearray:") + QString::fromUtf8( value.constData(), value.size()),
1015 ArnLink* holderLink = _link->holderLink( d->_useUncrossed);
1017 if ((value == holderLink->toVariant( &isOk)) && isOk) {
1018 holderLink->setIgnoredValue();
1022 d->_isAssigning =
true;
1023 _link->setValue( value, d->_id, d->_useUncrossed);
1024 d->_isAssigning =
false;
1027 errorLog( QString(
"Assigning variant"),
1035 setValue( QString::fromUtf8( value), ignoreSame);
1042 setValue( QByteArray::number( value), ignoreSame);
1045 errorLog( QString(
"Assigning uint:") + QString::number( value),
1054 setValue( QByteArray::number( qlonglong( value)), ignoreSame);
1057 errorLog( QString(
"Assigning int64:") + QString::number( qlonglong( value)),
1066 setValue( QByteArray::number( qulonglong( value)), ignoreSame);
1069 errorLog( QString(
"Assigning uint64:") + QString::number( qulonglong( value)),
1082 ArnLink* holderLink = _link->holderLink( d->_useUncrossed);
1084 int oldValue = holderLink->toInt( &isOk);
1085 if ((((oldValue & ~mask) | (value & mask)) == oldValue) && isOk) {
1086 holderLink->setIgnoredValue();
1090 d->_isAssigning =
true;
1091 _link->setBits( mask, value, d->_id, d->_useUncrossed);
1092 d->_isAssigning =
false;
1095 errorLog( QString(
"Op setBits: mask=") + QString::number( mask) +
1106 d->_isAssigning =
true;
1107 _link->addValue( value, d->_id, d->_useUncrossed);
1108 d->_isAssigning =
false;
1121 d->_isAssigning =
true;
1122 _link->addValue( value, d->_id, d->_useUncrossed);
1123 d->_isAssigning =
false;
1135 if (d->_eventHandler)
1136 return d->_eventHandler->thread();
1143 bool ArnBasicItem::sendArnEventLink(
ArnEvent* ev)
1145 if (!_link)
return false;
1147 _link->sendArnEvent( ev);
1152 void ArnBasicItem::sendArnEventItem(
ArnEvent* ev,
bool isAlienThread,
bool isLocked)
1159 if (isAlienThread) {
1160 QMutex* targetMutex = _link ? _link->getMutex() : arnNullptr;
1170 arnEvent( ev, isAlienThread);
1174 void ArnBasicItem::arnEvent( QEvent* ev,
bool isAlienThread)
1182 if (isAlienThread) {
1183 if (!d->_eventHandler) {
1187 QCoreApplication::postEvent( d->_eventHandler, ev);
1190 if (d->_isStdEvHandler || !d->_eventHandler) {
1191 ArnBasicItemEventHandler::defaultEvent( ev);
1194 d->_eventHandler->event( ev);
1205 d->_isStdEvHandler =
false;
1213 return d->_eventHandler;
1237 return d->_isAssigning;
1241 void ArnBasicItem::setForceKeep(
bool fk)
1247 bool ArnBasicItem::isForceKeep()
const 1258 ArnLinkHandle::Flags& handleFlags = handleData.flags();
1261 if (handleFlags.is( handleFlags.Text))
1262 valueTxt = QString::fromUtf8( value.constData(), value.size());
1266 ArnLink* holderLink = _link->holderLink( d->_useUncrossed);
1268 if (handleFlags.is( handleFlags.Text)) {
1269 if ((valueTxt == holderLink->toString( &isOk)) && isOk) {
1270 holderLink->setIgnoredValue( handleData);
1275 if ((value == holderLink->toByteArray( &isOk)) && isOk) {
1276 holderLink->setIgnoredValue( handleData);
1281 d->_isAssigning =
true;
1282 if (handleFlags.is( handleFlags.Text)) {
1283 handleFlags.set( handleFlags.Text,
false);
1284 _link->setValue( valueTxt, d->_id, d->_useUncrossed, handleData);
1287 _link->setValue( value, d->_id, d->_useUncrossed, handleData);
1289 d->_isAssigning =
false;
1292 errorLog( QString(
"Assigning bytearray (ArnLinkHandle):") + QString::fromUtf8( value.constData(), value.size()),
1305 ArnLink* holderLink = _link->holderLink( d->_useUncrossed);
1307 if ((value == holderLink->toVariant( &isOk)) && isOk) {
1308 holderLink->setIgnoredValue( handleData);
1312 d->_isAssigning =
true;
1313 _link->setValue( value, d->_id, d->_useUncrossed, handleData);
1314 d->_isAssigning =
false;
1317 errorLog( QString(
"Assigning variant (ArnLinkHandle):"),
1323 QStringList ArnBasicItem::childItemsMain()
const 1326 return ArnM::itemsMain( _link);
1330 void ArnBasicItem::errorLog(
const QString& errText,
ArnError err,
void* reference)
const 1334 itemText =
" Item:" + _link->linkPath();
1341 ArnBasicItemEventHandler* ArnBasicItem::getThreadEventHandler()
1343 static QThreadStorage<ArnBasicItemEventHandler*> evHandlers;
1345 if (!evHandlers.hasLocalData())
1348 return evHandlers.localData();
1352 ArnBasicItemEventHandler::ArnBasicItemEventHandler( QObject* parent)
1358 ArnBasicItemEventHandler::~ArnBasicItemEventHandler()
1364 void ArnBasicItemEventHandler::defaultEvent( QEvent* ev)
1372 if (!target)
return;
1387 if (!target)
return;
1401 void ArnBasicItemEventHandler::customEvent( QEvent* ev)
Data type of an Arn Data Object
bool isUncrossed() const
Get the Uncrossed state of an object.
QString toString(bool *isOk=arnNullptr) const
static int baseType(int setVal=-1)
void destroyLink(bool isGlobal=true)
Destroy the Arn Data Object
QThread * thread() const
Get the thread affinity of this ArnBasicItem.
void setValue(const ArnBasicItem &other, int ignoreSame=Arn::SameValue::DefaultAction)
ArnBasicItem & setPipeMode()
Set general mode as Pipe for this Arn Data Object
quint64 toUInt64(bool *isOk=arnNullptr) const
Arn::ObjectSyncMode syncMode() const
bool toBool(bool *isOk=arnNullptr) const
bool open(const QString &path)
Open a handle to an Arn Data Object
void close()
Close the handle.
void setReference(void *reference)
Set an associated external reference.
ArnBasicItem & setSaveMode()
Set general mode as Save for this Arn Data Object
int refCount() const
Get the number of refs to this Arn Data Object
uint toUInt(bool *isOk=arnNullptr) const
Implies BiDir and all data is preserved as a stream.
void setIgnoreSameValue(bool isIgnore=true)
Set skipping of equal value.
void setUncrossed(bool isUncrossed=true)
Set a Bidirectional item as Uncrossed.
Core base class for the inherited ArnItem classes.
Arn::ObjectMode getMode() const
Use with care, link must be "referenced" before use, otherwise it might have been deleted...
bool isAtomicOpProvider() const
int toInt(bool *isOk=arnNullptr) const
uint itemId() const
Get the id for this ArnItem.
bool isIgnoreSameValue() const
ARNREAL toReal(bool *isOk=arnNullptr) const
Arn::ObjectMode mode() const
QByteArray toByteArray(bool *isOk=arnNullptr) const
void setAtomicOpProvider()
Set this Arn Data Object as Atomic Operator Provider
A two way object, typically for validation or pipe.
void addValue(int value)
AtomicOp adds an integer to an Arn Data Object
void * reference() const
Get the stored external reference.
void setBits(int mask, int value, int ignoreSame=Arn::SameValue::DefaultAction)
AtomicOp assign an integer to specified bits in an Arn Data Object
void arnImport(const QByteArray &data, int ignoreSame=Arn::SameValue::DefaultAction)
Import data to an Arn Data Object
Link flags when accessing an Arn Data Object
ArnBasicItem & operator+=(int val)
QVariant toVariant(bool *isOk=arnNullptr) const
void setTargetPendingChain(ArnEvent **targetPendingChain=arnNullptr)
Destroy this Arn Data Object when client (tcp/ip) closes.
bool isOpen() const
State of the handle.
QString path(Arn::NameF nameF=Arn::NameF::EmptyOk) const
Path of the Arn Data Object
ArnBasicItem & setBiDirMode()
Set general mode as Bidirectional for this Arn Data Object
void addMode(Arn::ObjectMode mode)
Add general mode settings for this Arn Data Object
Arn::DataType type() const
The type stored in the Arn Data Object
bool isAutoDestroy() const
static bool defaultIgnoreSameValue()
ArnBasicItem()
Standard constructor of a closed handle.
ArnBasicItem & setAutoDestroy()
Set client session sync mode as AutoDestroy for this ArnItem.
double toDouble(bool *isOk=arnNullptr) const
uint linkId() const
Get the id for this Arn Data Object
qint64 toInt64(bool *isOk=arnNullptr) const
static void errorLog(QString errText, ArnError err=ArnError::Undef, void *reference=arnNullptr)
static void destroyLink(const QString &path, bool isGlobal=true)
Destroy the Arn Data Object at path
QString name(Arn::NameF nameF) const
Name of the Arn Data Object
void setTargetMutex(QMutex *targetMutex)
void setTarget(void *target)
Data is persistent and will be saved.
friend class ArnBasicItemEventHandler
QByteArray arnExport() const
ArnBasicItem & setMaster()
Set client session sync mode as Master for this ArnItem.
ArnBasicItem & operator=(const ArnBasicItem &other)
QObject * eventHandler() const
Get the event handler of this ArnBasicItem.
void setEventHandler(QObject *eventHandler)
Set event handler for this ArnBasicItem.
Base class handle for an Arn Data Object.
The client is default generator of data.
bool isAssigning() const
Tells if this ArnItem is assigned right now.