make fromScriptValue logic easier to follow for CR; eliminate extra QByteArray conversion

This commit is contained in:
humbletim 2018-01-24 13:49:58 -05:00
parent c2ee13931e
commit 63a226f999
4 changed files with 29 additions and 45 deletions

View file

@ -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<QScriptClass*>();
int qByteArrayPointerMetaTypeId = qRegisterMetaType<QByteArray*>();
ArrayBufferClass::ArrayBufferClass(ScriptEngine* scriptEngine) :
QObject(scriptEngine),
QScriptClass(scriptEngine),
_scriptEngine(scriptEngine) {
QScriptClass(scriptEngine) {
qScriptRegisterMetaType<QByteArray>(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<ArrayBufferClass*>(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<QByteArray>(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<QByteArray*>(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<QByteArray*>(object.data())) {
byteArray = *buffer;
}
}
}

View file

@ -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

View file

@ -11,8 +11,7 @@
#include "ArrayBufferViewClass.h"
int qScriptClassPointerMetaTypeId = qRegisterMetaType<QScriptClass*>();
int qByteArrayMetaTypeId = qRegisterMetaType<QByteArray>();
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<QByteArray>(typedArray.property("buffer").toVariant());
} else {
byteArray = qvariant_cast<QByteArray>(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<QScriptClass*>(constructor.data());
Q_ASSERT(array);
return engine->newObject(array, data);
}
}
void ArrayBufferViewClass::registerMetaTypes(QScriptEngine* scriptEngine) {
qScriptRegisterMetaType(scriptEngine, byteArrayToScriptValue, byteArrayFromScriptValue);
}

View file

@ -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