QScriptValue::PropertyFlags DefaultScriptClass::propertyFlags(const QScriptValue& object, const QScriptString& name, uint id) { QScriptValue::PropertyFlags result; const ScriptHandlerInfo::Mode mode = mHandlerInfo->mode(); Q_ASSERT(mode != ScriptHandlerInfo::None); DataInformation* data = toDataInformation(object); if (!data) { mHandlerInfo->logger()->error() << "could not cast data from" << object.data().toString(); engine()->currentContext()->throwError(QScriptContext::ReferenceError, QStringLiteral("Attempting to access an invalid object")); return 0; } if (name == s_valid || name == s_validationError) { if (mode != ScriptHandlerInfo::Validating) result |= QScriptValue::ReadOnly; } else if (mode != ScriptHandlerInfo::Updating) { result |= QScriptValue::ReadOnly; } for (int i = 0, size = mIterableProperties.size(); i < size; ++i) { if (mIterableProperties.at(i).first == name) return result | mIterableProperties.at(i).second; } if (additionalPropertyFlags(data, name, id, &result)) return result; //is a child element else { data->logError() << "could not find flags for property with name" << name.toString(); return 0; } }
QScriptClass::QueryFlags DefaultScriptClass::queryProperty(const QScriptValue& object, const QScriptString& name, QScriptClass::QueryFlags flags, uint* id) { const ScriptHandlerInfo::Mode mode = mHandlerInfo->mode(); Q_ASSERT(mode != ScriptHandlerInfo::None); DataInformation* data = toDataInformation(object); if (!data) { mHandlerInfo->logger()->error() << "could not cast data from" << object.data().toString(); engine()->currentContext()->throwError(QScriptContext::ReferenceError, QStringLiteral("Attempting to access an invalid object")); return 0; } if (name == s_valid || name == s_validationError) { return mode == ScriptHandlerInfo::Validating ? flags : flags & ~HandlesWriteAccess; } if (mode != ScriptHandlerInfo::Updating) { //the only properties that are possibly writable when not updating are valid and validationError //but we checked them before so we remove handlesWriteAccess from the flags flags &= ~HandlesWriteAccess; } if (name == s_byteOrder || name == s_name || name == s_updateFunc || name == s_validationFunc || name == s_datatype || name == s_customTypeName || name == s_asStringFunc) { return flags; } else if (name == s_wasAbleToRead || name == s_parent) { return flags & ~HandlesWriteAccess; } else if (queryAdditionalProperty(data, name, &flags, id)) { return flags; } else { data->logError() << "could not find property with name" << name.toString(); engine()->currentContext()->throwError(QScriptContext::ReferenceError, QStringLiteral("Could not find property with name ") + name.toString()); return 0; } }
QScriptValue DefaultScriptClass::property(const QScriptValue& object, const QScriptString& name, uint id) { Q_ASSERT(mHandlerInfo->mode() != ScriptHandlerInfo::None); DataInformation* data = toDataInformation(object); if (!data) { mHandlerInfo->logger()->error() << "could not cast data from" << object.data().toString(); return engine()->currentContext()->throwError(QScriptContext::ReferenceError, QStringLiteral("Attempting to access an invalid object")); } if (name == s_valid) { return data->validationSuccessful(); } else if (name == s_wasAbleToRead) { return data->wasAbleToRead(); } else if (name == s_parent) { Q_CHECK_PTR(data->parent()); //parent() cannot be null if (data->parent()->isTopLevel()) return engine()->nullValue(); return data->parent()->asDataInformation()->toScriptValue(engine(), mHandlerInfo); } else if (name == s_datatype) { return data->typeName(); } else if (name == s_updateFunc) { return data->updateFunc(); } else if (name == s_validationFunc) { return data->validationFunc(); } else if (name == s_validationError) { return data->validationError(); } else if (name == s_byteOrder) { return ParserUtils::byteOrderToString(data->byteOrder()); } else if (name == s_name) { return data->name(); } else if (name == s_customTypeName) { return data->typeName(); } else if (name == s_asStringFunc) { return data->toStringFunction(); } QScriptValue other = additionalProperty(data, name, id); if (other.isValid()) return other; else { data->logError() << "could not find property with name" << name.toString(); return engine()->currentContext()->throwError(QScriptContext::ReferenceError, QStringLiteral("Cannot read property ") + name.toString()); } }
void DefaultScriptClass::setProperty(QScriptValue& object, const QScriptString& name, uint id, const QScriptValue& value) { const ScriptHandlerInfo::Mode mode = mHandlerInfo->mode(); Q_ASSERT(mode != ScriptHandlerInfo::None); DataInformation* data = toDataInformation(object); if (!data) { mHandlerInfo->logger()->error() << "could not cast data from" << object.data().toString(); engine()->currentContext()->throwError(QScriptContext::ReferenceError, QStringLiteral("Attempting to access an invalid object")); return; } if (mode == ScriptHandlerInfo::Validating) { //only way write access is allowed is when validating: valid and validationError if (data->hasBeenValidated()) data->logError() << "Cannot modify this object, it has already been validated!"; else if (name == s_valid) data->mValidationSuccessful = value.toBool(); else if (name == s_validationError) data->setValidationError(value.toString()); else data->logError() << "Cannot write to property" << name.toString() << "while validating!"; return; } if (mode != ScriptHandlerInfo::Updating) { data->logError() << "Writing to property" << name.toString() << "is only allowed when updating."; return; } Q_ASSERT(mode == ScriptHandlerInfo::Updating); if (name == s_byteOrder) { data->setByteOrder(ParserUtils::byteOrderFromString(value.toString(), LoggerWithContext(data->logger(), data->fullObjectPath()))); } else if (name == s_datatype) { //change the type of the underlying object setDataType(value, data); } else if (name == s_updateFunc) { data->setUpdateFunc(value); } else if (name == s_validationFunc) { data->setValidationFunc(value); } else if (name == s_name) { data->setName(value.toString()); } else if (name == s_customTypeName) { if (!value.isValid() || value.isNull() || value.isUndefined()) data->setCustomTypeName(QString()); //unset else data->setCustomTypeName(value.toString()); } else if (name == s_asStringFunc) { data->setToStringFunction(value); } else { bool setAdditional = setAdditionalProperty(data, name, id, value); if (setAdditional) return; else { data->logError() << "could not set property with name" << name.toString(); engine()->currentContext()->throwError(QScriptContext::ReferenceError, QStringLiteral("Cannot write property ") + name.toString()); } } }
QVector<TopLevelDataInformation*> OsdParser::parseStructures() const { QFileInfo fileInfo(mAbsolutePath); QVector<TopLevelDataInformation*> structures; QScopedPointer<ScriptLogger> rootLogger(new ScriptLogger()); //only needed in we get an error right now QDomDocument document = openDoc(rootLogger.data()); if (document.isNull()) { structures.append(new TopLevelDataInformation( new DummyDataInformation(0, fileInfo.fileName()), rootLogger.take(), 0, fileInfo)); return structures; } QDomElement rootElem = document.firstChildElement(QStringLiteral("data")); if (rootElem.isNull()) { rootLogger->error() << "Missing top level <data> element!"; structures.append(new TopLevelDataInformation( new DummyDataInformation(0, fileInfo.fileName()), rootLogger.take(), 0, fileInfo)); return structures; } int count = 1; for (QDomElement elem = rootElem.firstChildElement(); !elem.isNull(); elem = elem.nextSiblingElement()) { if (elem.tagName() == TYPE_ENUMDEF) continue; //skip enum defs QScriptEngine* eng = ScriptEngineInitializer::newEngine(); //we need this for dynamic arrays ScriptLogger* logger = new ScriptLogger(); QVector<EnumDefinition::Ptr> enums = parseEnums(rootElem, logger); OsdParserInfo info(QString(), logger, 0, eng, enums); DataInformation* data = parseElement(elem, info); if (!data) { QString name = readProperty(elem, PROPERTY_NAME); if (name.isEmpty()) name = fileInfo.absoluteFilePath() + QStringLiteral("_element") + QString::number(count); qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "Failed to parse element" << elem.tagName() << name; qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "Parsing messages were:" << logger->messages(); data = new DummyDataInformation(0, name); } TopLevelDataInformation* topData = new TopLevelDataInformation(data, logger, eng, fileInfo); QString lockOffsetStr = readProperty(elem, PROPERTY_DEFAULT_LOCK_OFFSET); if (!lockOffsetStr.isEmpty()) { ParsedNumber<quint64> offset = ParserUtils::uint64FromString(lockOffsetStr); if (!offset.isValid) data->logError() << "Default lock offset is not a valid number:" << offset.string; else { data->logInfo() << "Default lock offset is " << offset.string; topData->setDefaultLockOffset(offset.value); } } structures.append(topData); count++; } return structures; }