Showing the changes to libraries/script-engine/src/TypedArrayPrototype.cpp (1 of 13 files). Show all
Unified · Split
| @@ -0,0 +1,106 @@ | ||
| 1 | +// | |
| 2 | +// TypedArrayPrototype.cpp | |
| 3 | +// | |
| 4 | +// | |
| 5 | +// Created by Clement on 7/14/14. | |
| 6 | +// Copyright 2014 High Fidelity, Inc. | |
| 7 | +// | |
| 8 | +// Distributed under the Apache License, Version 2.0. | |
| 9 | +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html | |
| 10 | +// | |
| 11 | + | |
| 12 | +#include "TypedArrays.h" | |
| 13 | + | |
| 14 | +#include "TypedArrayPrototype.h" | |
| 15 | + | |
| 16 | +Q_DECLARE_METATYPE(QByteArray*) | |
| 17 | + | |
| 18 | +TypedArrayPrototype::TypedArrayPrototype(QObject* parent) : QObject(parent) { | |
| 19 | +} | |
| 20 | + | |
| 21 | +QByteArray* TypedArrayPrototype::thisArrayBuffer() const { | |
| 22 | + QScriptValue bufferObject = thisObject().data().property(BUFFER_PROPERTY_NAME); | |
| 23 | + return qscriptvalue_cast<QByteArray*>(bufferObject.data()); | |
| 24 | +} | |
| 25 | + | |
| 26 | +void TypedArrayPrototype::set(QScriptValue array, qint32 offset) { | |
| 27 | + TypedArray* typedArray = static_cast<TypedArray*>(parent()); | |
| 28 | + if (array.isArray() || typedArray) { | |
| 29 | + if (offset < 0) { | |
| 30 | + engine()->evaluate("throw \"ArgumentError: negative offset\""); | |
| 31 | + } | |
| 32 | + quint32 length = array.property("length").toInt32(); | |
| 33 | + if (offset + length > thisObject().data().property(typedArray->_lengthName).toInt32()) { | |
| 34 | + engine()->evaluate("throw \"ArgumentError: array does not fit\""); | |
| 35 | + return; | |
| 36 | + } | |
| 37 | + for (int i = 0; i < length; ++i) { | |
| 38 | + thisObject().setProperty(QString::number(offset + i), array.property(QString::number(i))); | |
| 39 | + } | |
| 40 | + } else { | |
| 41 | + engine()->evaluate("throw \"ArgumentError: not an array\""); | |
| 42 | + } | |
| 43 | +} | |
| 44 | + | |
| 45 | +QScriptValue TypedArrayPrototype::subarray(qint32 begin) { | |
| 46 | + TypedArray* typedArray = static_cast<TypedArray*>(parent()); | |
| 47 | + QScriptValue arrayBuffer = thisObject().data().property(typedArray->_bufferName); | |
| 48 | + qint32 byteOffset = thisObject().data().property(typedArray->_byteOffsetName).toInt32(); | |
| 49 | + qint32 length = thisObject().data().property(typedArray->_lengthName).toInt32(); | |
| 50 | + qint32 bytesPerElement = typedArray->_bytesPerElement; | |
| 51 | + | |
| 52 | + // if indices < 0 then they start from the end of the array | |
| 53 | + begin = (begin < 0) ? length + begin : begin; | |
| 54 | + | |
| 55 | + // here we clamp the indices to fit the array | |
| 56 | + begin = glm::clamp(begin, 0, (length - 1)); | |
| 57 | + | |
| 58 | + byteOffset += begin * bytesPerElement; | |
| 59 | + return typedArray->newInstance(arrayBuffer, byteOffset, length - begin); | |
| 60 | +} | |
| 61 | + | |
| 62 | +QScriptValue TypedArrayPrototype::subarray(qint32 begin, qint32 end) { | |
| 63 | + TypedArray* typedArray = static_cast<TypedArray*>(parent()); | |
| 64 | + QScriptValue arrayBuffer = thisObject().data().property(typedArray->_bufferName); | |
| 65 | + qint32 byteOffset = thisObject().data().property(typedArray->_byteOffsetName).toInt32(); | |
| 66 | + qint32 length = thisObject().data().property(typedArray->_lengthName).toInt32(); | |
| 67 | + qint32 bytesPerElement = typedArray->_bytesPerElement; | |
| 68 | + | |
| 69 | + // if indices < 0 then they start from the end of the array | |
| 70 | + begin = (begin < 0) ? length + begin : begin; | |
| 71 | + end = (end < 0) ? length + end : end; | |
| 72 | + | |
| 73 | + // here we clamp the indices to fit the array | |
| 74 | + begin = glm::clamp(begin, 0, (length - 1)); | |
| 75 | + end = glm::clamp(end, 0, (length - 1)); | |
| 76 | + | |
| 77 | + byteOffset += begin * bytesPerElement; | |
| 78 | + length = (end - begin > 0) ? end - begin : 0; | |
| 79 | + return typedArray->newInstance(arrayBuffer, byteOffset, length); | |
| 80 | +} | |
| 81 | + | |
| 82 | +QScriptValue TypedArrayPrototype::get(quint32 index) { | |
| 83 | + TypedArray* typedArray = static_cast<TypedArray*>(parent()); | |
| 84 | + QScriptString name = engine()->toStringHandle(QString::number(index)); | |
| 85 | + uint id; | |
| 86 | + QScriptClass::QueryFlags flags = typedArray->queryProperty(thisObject(), | |
| 87 | + name, | |
| 88 | + QScriptClass::HandlesReadAccess, &id); | |
| 89 | + if (QScriptClass::HandlesReadAccess & flags) { | |
| 90 | + return typedArray->property(thisObject(), name, id); | |
| 91 | + } | |
| 92 | + return QScriptValue(); | |
| 93 | +} | |
| 94 | + | |
| 95 | +void TypedArrayPrototype::set(quint32 index, QScriptValue& value) { | |
| 96 | + TypedArray* typedArray = static_cast<TypedArray*>(parent()); | |
| 97 | + QScriptValue object = thisObject(); | |
| 98 | + QScriptString name = engine()->toStringHandle(QString::number(index)); | |
| 99 | + uint id; | |
| 100 | + QScriptClass::QueryFlags flags = typedArray->queryProperty(object, | |
| 101 | + name, | |
| 102 | + QScriptClass::HandlesWriteAccess, &id); | |
| 103 | + if (QScriptClass::HandlesWriteAccess & flags) { | |
| 104 | + typedArray->setProperty(object, name, id, value); | |
| 105 | + } | |
| 106 | +} | |