From 63a226f9994a025093ef9043603d3a84dc410b17 Mon Sep 17 00:00:00 2001 From: humbletim Date: Wed, 24 Jan 2018 13:49:58 -0500 Subject: [PATCH] make fromScriptValue logic easier to follow for CR; eliminate extra QByteArray conversion --- .../script-engine/src/ArrayBufferClass.cpp | 33 ++++++++++++++--- .../script-engine/src/ArrayBufferClass.h | 2 -- .../src/ArrayBufferViewClass.cpp | 35 +------------------ .../script-engine/src/ArrayBufferViewClass.h | 4 --- 4 files changed, 29 insertions(+), 45 deletions(-) diff --git a/libraries/script-engine/src/ArrayBufferClass.cpp b/libraries/script-engine/src/ArrayBufferClass.cpp index b84188f707..4a06dee391 100644 --- a/libraries/script-engine/src/ArrayBufferClass.cpp +++ b/libraries/script-engine/src/ArrayBufferClass.cpp @@ -18,14 +18,19 @@ #include "ArrayBufferClass.h" + static const QString CLASS_NAME = "ArrayBuffer"; +// FIXME: Q_DECLARE_METATYPE is global and really belongs in a shared header file, not per .cpp like this +// (see DataViewClass.cpp, etc. which would also have to be updated to resolve) +Q_DECLARE_METATYPE(QScriptClass*) Q_DECLARE_METATYPE(QByteArray*) +int qScriptClassPointerMetaTypeId = qRegisterMetaType(); +int qByteArrayPointerMetaTypeId = qRegisterMetaType(); ArrayBufferClass::ArrayBufferClass(ScriptEngine* scriptEngine) : QObject(scriptEngine), -QScriptClass(scriptEngine), -_scriptEngine(scriptEngine) { +QScriptClass(scriptEngine) { qScriptRegisterMetaType(engine(), toScriptValue, fromScriptValue); QScriptValue global = engine()->globalObject(); @@ -144,12 +149,30 @@ QScriptValue ArrayBufferClass::toScriptValue(QScriptEngine* engine, const QByteA QScriptValue ctor = engine->globalObject().property(CLASS_NAME); ArrayBufferClass* cls = qscriptvalue_cast(ctor.data()); if (!cls) { - return engine->newVariant(QVariant::fromValue(ba)); + if (engine->currentContext()) { + engine->currentContext()->throwError("arrayBufferClass::toScriptValue -- could not get " + CLASS_NAME + " class constructor"); + } + return QScriptValue::NullValue; } return cls->newInstance(ba); } -void ArrayBufferClass::fromScriptValue(const QScriptValue& obj, QByteArray& ba) { - ba = qvariant_cast(obj.data().toVariant()); +void ArrayBufferClass::fromScriptValue(const QScriptValue& object, QByteArray& byteArray) { + if (object.isString()) { + // UTF-8 encoded String + byteArray = object.toString().toUtf8(); + } else if (object.isArray()) { + // Array of uint8s eg: [ 128, 3, 25, 234 ] + auto Uint8Array = object.engine()->globalObject().property("Uint8Array"); + auto typedArray = Uint8Array.construct(QScriptValueList{object}); + if (QByteArray* buffer = qscriptvalue_cast(typedArray.property("buffer"))) { + byteArray = *buffer; + } + } else if (object.isObject()) { + // ArrayBuffer instance (or any JS class that supports coercion into QByteArray*) + if (QByteArray* buffer = qscriptvalue_cast(object.data())) { + byteArray = *buffer; + } + } } diff --git a/libraries/script-engine/src/ArrayBufferClass.h b/libraries/script-engine/src/ArrayBufferClass.h index 69c2cc0799..a2cf08cc06 100644 --- a/libraries/script-engine/src/ArrayBufferClass.h +++ b/libraries/script-engine/src/ArrayBufferClass.h @@ -40,7 +40,6 @@ public: QString name() const override; QScriptValue prototype() const override; - ScriptEngine* getEngine() { return _scriptEngine; } private: static QScriptValue construct(QScriptContext* context, QScriptEngine* engine); @@ -55,7 +54,6 @@ private: QScriptString _name; QScriptString _byteLength; - ScriptEngine* _scriptEngine; }; #endif // hifi_ArrayBufferClass_h diff --git a/libraries/script-engine/src/ArrayBufferViewClass.cpp b/libraries/script-engine/src/ArrayBufferViewClass.cpp index 84cb32d665..cf776ed834 100644 --- a/libraries/script-engine/src/ArrayBufferViewClass.cpp +++ b/libraries/script-engine/src/ArrayBufferViewClass.cpp @@ -11,8 +11,7 @@ #include "ArrayBufferViewClass.h" -int qScriptClassPointerMetaTypeId = qRegisterMetaType(); -int qByteArrayMetaTypeId = qRegisterMetaType(); +Q_DECLARE_METATYPE(QByteArray*) ArrayBufferViewClass::ArrayBufferViewClass(ScriptEngine* scriptEngine) : QObject(scriptEngine), @@ -22,7 +21,6 @@ _scriptEngine(scriptEngine) { _bufferName = engine()->toStringHandle(BUFFER_PROPERTY_NAME.toLatin1()); _byteOffsetName = engine()->toStringHandle(BYTE_OFFSET_PROPERTY_NAME.toLatin1()); _byteLengthName = engine()->toStringHandle(BYTE_LENGTH_PROPERTY_NAME.toLatin1()); - registerMetaTypes(scriptEngine); } QScriptClass::QueryFlags ArrayBufferViewClass::queryProperty(const QScriptValue& object, @@ -52,34 +50,3 @@ QScriptValue::PropertyFlags ArrayBufferViewClass::propertyFlags(const QScriptVal const QScriptString& name, uint id) { return QScriptValue::Undeletable; } - -namespace { - void byteArrayFromScriptValue(const QScriptValue& object, QByteArray& byteArray) { - if (object.isValid()) { - if (object.isObject()) { - if (object.isArray()) { - auto Uint8Array = object.engine()->globalObject().property("Uint8Array"); - auto typedArray = Uint8Array.construct(QScriptValueList{object}); - byteArray = qvariant_cast(typedArray.property("buffer").toVariant()); - } else { - byteArray = qvariant_cast(object.data().toVariant()); - } - } else { - byteArray = object.toString().toUtf8(); - } - } - } - - QScriptValue byteArrayToScriptValue(QScriptEngine *engine, const QByteArray& byteArray) { - QScriptValue data = engine->newVariant(QVariant::fromValue(byteArray)); - QScriptValue constructor = engine->globalObject().property("ArrayBuffer"); - Q_ASSERT(constructor.isValid()); - auto array = qscriptvalue_cast(constructor.data()); - Q_ASSERT(array); - return engine->newObject(array, data); - } -} - -void ArrayBufferViewClass::registerMetaTypes(QScriptEngine* scriptEngine) { - qScriptRegisterMetaType(scriptEngine, byteArrayToScriptValue, byteArrayFromScriptValue); -} diff --git a/libraries/script-engine/src/ArrayBufferViewClass.h b/libraries/script-engine/src/ArrayBufferViewClass.h index 038cc75ffd..67af4a3fc3 100644 --- a/libraries/script-engine/src/ArrayBufferViewClass.h +++ b/libraries/script-engine/src/ArrayBufferViewClass.h @@ -29,7 +29,6 @@ static const QString BYTE_LENGTH_PROPERTY_NAME = "byteLength"; class ArrayBufferViewClass : public QObject, public QScriptClass { Q_OBJECT public: - static void registerMetaTypes(QScriptEngine* scriptEngine); ArrayBufferViewClass(ScriptEngine* scriptEngine); ScriptEngine* getScriptEngine() { return _scriptEngine; } @@ -50,7 +49,4 @@ protected: ScriptEngine* _scriptEngine; }; -Q_DECLARE_METATYPE(QScriptClass*) -Q_DECLARE_METATYPE(QByteArray) - #endif // hifi_ArrayBufferViewClass_h