Fixed exceptions/endian issues with DataViews

This commit is contained in:
Atlante45 2014-07-09 10:27:23 -07:00
parent 49302b2340
commit 28438d66b1
3 changed files with 68 additions and 21 deletions

View file

@ -54,15 +54,32 @@ QScriptValue DataViewClass::construct(QScriptContext *context, QScriptEngine *en
}
QScriptValue bufferArg = context->argument(0);
QScriptValue byteOffsetArg = (context->argumentCount() >= 2) ? context->argument(1) : QScriptValue(-1);
QScriptValue byteLengthArg = (context->argumentCount() >= 3) ? context->argument(2) : QScriptValue(-1);
QScriptValue byteOffsetArg = (context->argumentCount() >= 2) ? context->argument(1) : QScriptValue();
QScriptValue byteLengthArg = (context->argumentCount() >= 3) ? context->argument(2) : QScriptValue();
QByteArray* arrayBuffer = (bufferArg.isValid()) ? qscriptvalue_cast<QByteArray*>(bufferArg.data()) :NULL;
if (!arrayBuffer) {
engine->evaluate("throw \"TypeError: 1st argument not a ArrayBuffer\"");
return QScriptValue();
}
if (byteOffsetArg.isNumber() &&
(byteOffsetArg.toInt32() < 0 ||
byteOffsetArg.toInt32() >= arrayBuffer->size())) {
engine->evaluate("throw \"RangeError: byteOffset out of range\"");
return QScriptValue();
}
if (byteLengthArg.isNumber() &&
(byteLengthArg.toInt32() < 0 ||
byteOffsetArg.toInt32() + byteLengthArg.toInt32() > arrayBuffer->size())) {
engine->evaluate("throw \"RangeError: byteLength out of range\"");
return QScriptValue();
}
QScriptValue newObject = cls->newInstance(bufferArg, byteOffsetArg.toInt32(), byteLengthArg.toInt32());
QScriptValue newObject = cls->newInstance(bufferArg,
(byteOffsetArg.isNumber()) ? byteOffsetArg.toInt32()
: 0,
(byteLengthArg.isNumber()) ? byteLengthArg.toInt32()
: arrayBuffer->size());
if (context->isCalledAsConstructor()) {
context->setThisObject(newObject);

View file

@ -18,7 +18,7 @@ class DataViewClass : public ArrayBufferViewClass {
Q_OBJECT
public:
DataViewClass(QScriptEngine* engine);
QScriptValue newInstance(QScriptValue buffer, quint32 byteOffset = -1, quint32 byteLength = -1);
QScriptValue newInstance(QScriptValue buffer, quint32 byteOffset, quint32 byteLength);
QString name() const;
QScriptValue prototype() const;

View file

@ -29,10 +29,10 @@ QByteArray* DataViewPrototype::thisArrayBuffer() const {
bool DataViewPrototype::realOffset(quint32& offset, size_t size) const {
quint32 viewOffset = thisObject().data().property(BYTE_OFFSET_PROPERTY_NAME).toInt32();
quint32 viewLength = thisObject().data().property(BYTE_LENGTH_PROPERTY_NAME).toInt32();
qDebug() << "View Offset: " << viewOffset << ", View Lenght: " << viewLength;
qDebug() << "Offset: " << offset << ", Size: " << size;
//qDebug() << "View Offset: " << viewOffset << ", View Lenght: " << viewLength;
//qDebug() << "Offset: " << offset << ", Size: " << size;
offset += viewOffset;
qDebug() << "New offset: " << offset << ", bool: " << ((offset + size) <= viewOffset + viewLength);
//qDebug() << "New offset: " << offset << ", bool: " << ((offset + size) <= viewOffset + viewLength);
return (offset + size) <= viewOffset + viewLength;
}
@ -47,7 +47,8 @@ qint32 DataViewPrototype::getInt8(quint32 byteOffset) {
stream >> result;
return result;
}
return 42;
thisObject().engine()->evaluate("throw \"RangeError: byteOffset out of range\"");
return 0;
}
quint32 DataViewPrototype::getUint8(quint32 byteOffset) {
@ -59,85 +60,92 @@ quint32 DataViewPrototype::getUint8(quint32 byteOffset) {
stream >> result;
return result;
}
return 42;
thisObject().engine()->evaluate("throw \"RangeError: byteOffset out of range\"");
return 0;
}
qint32 DataViewPrototype::getInt16(quint32 byteOffset, bool littleEndian) {
if (realOffset(byteOffset, sizeof(qint16))) {
QDataStream stream(*thisArrayBuffer());
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream.skipRawData(byteOffset);
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
qint16 result;
stream >> result;
return result;
}
return 42;
thisObject().engine()->evaluate("throw \"RangeError: byteOffset out of range\"");
return 0;
}
quint32 DataViewPrototype::getUint16(quint32 byteOffset, bool littleEndian) {
if (realOffset(byteOffset, sizeof(quint16))) {
QDataStream stream(*thisArrayBuffer());
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream.skipRawData(byteOffset);
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
quint16 result;
stream >> result;
return result;
}
return 42;
thisObject().engine()->evaluate("throw \"RangeError: byteOffset out of range\"");
return 0;
}
qint32 DataViewPrototype::getInt32(quint32 byteOffset, bool littleEndian) {
if (realOffset(byteOffset, sizeof(qint32))) {
QDataStream stream(*thisArrayBuffer());
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream.skipRawData(byteOffset);
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
qint32 result;
stream >> result;
return result;
}
return 42;
thisObject().engine()->evaluate("throw \"RangeError: byteOffset out of range\"");
return 0;
}
quint32 DataViewPrototype::getUint32(quint32 byteOffset, bool littleEndian) {
if (realOffset(byteOffset, sizeof(quint32))) {
QDataStream stream(*thisArrayBuffer());
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream.skipRawData(byteOffset);
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
quint32 result;
stream >> result;
return result;
}
return 42;
thisObject().engine()->evaluate("throw \"RangeError: byteOffset out of range\"");
return 0;
}
float DataViewPrototype::getFloat32(quint32 byteOffset, bool littleEndian) {
if (realOffset(byteOffset, sizeof(float))) {
QDataStream stream(*thisArrayBuffer());
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream.skipRawData(byteOffset);
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
float result;
stream >> result;
return result;
}
return 42;
thisObject().engine()->evaluate("throw \"RangeError: byteOffset out of range\"");
return 0;
}
double DataViewPrototype::getFloat64(quint32 byteOffset, bool littleEndian) {
if (realOffset(byteOffset, sizeof(double))) {
QDataStream stream(*thisArrayBuffer());
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream.skipRawData(byteOffset);
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
double result;
stream >> result;
return result;
}
return 42;
thisObject().engine()->evaluate("throw \"RangeError: byteOffset out of range\"");
return 0;
}
///////////////// SETTERS ////////////////////////////
@ -148,6 +156,8 @@ void DataViewPrototype::setInt8(quint32 byteOffset, qint32 value) {
stream.skipRawData(byteOffset);
stream << (qint8)value;
} else {
thisObject().engine()->evaluate("throw \"1RangeError: byteOffset out of range\"");
}
}
@ -157,6 +167,8 @@ void DataViewPrototype::setUint8(quint32 byteOffset, quint32 value) {
stream.skipRawData(byteOffset);
stream << (quint8)value;
} else {
thisObject().engine()->evaluate("throw \"1RangeError: byteOffset out of range\"");
}
}
@ -164,8 +176,11 @@ void DataViewPrototype::setInt16(quint32 byteOffset, qint32 value, bool littleEn
if (realOffset(byteOffset, sizeof(qint16))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream << (qint16)value;
} else {
thisObject().engine()->evaluate("throw \"1RangeError: byteOffset out of range\"");
}
}
@ -173,8 +188,11 @@ void DataViewPrototype::setUint16(quint32 byteOffset, quint32 value, bool little
if (realOffset(byteOffset, sizeof(quint16))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream << (quint16)value;
} else {
thisObject().engine()->evaluate("throw \"1RangeError: byteOffset out of range\"");
}
}
@ -182,8 +200,11 @@ void DataViewPrototype::setInt32(quint32 byteOffset, qint32 value, bool littleEn
if (realOffset(byteOffset, sizeof(qint32))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream << (qint32)value;
} else {
thisObject().engine()->evaluate("throw \"1RangeError: byteOffset out of range\"");
}
}
@ -191,8 +212,11 @@ void DataViewPrototype::setUint32(quint32 byteOffset, quint32 value, bool little
if (realOffset(byteOffset, sizeof(quint32))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream << (quint32)value;
} else {
thisObject().engine()->evaluate("throw \"1RangeError: byteOffset out of range\"");
}
}
@ -200,8 +224,11 @@ void DataViewPrototype::setFloat32(quint32 byteOffset, float value, bool littleE
if (realOffset(byteOffset, sizeof(float))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream << value;
} else {
thisObject().engine()->evaluate("throw \"1RangeError: byteOffset out of range\"");
}
}
@ -209,8 +236,11 @@ void DataViewPrototype::setFloat64(quint32 byteOffset, double value, bool little
if (realOffset(byteOffset, sizeof(double))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream << value;
} else {
thisObject().engine()->evaluate("throw \"1RangeError: byteOffset out of range\"");
}
}