jscript: Implement DataView getters.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
parent
556e3349ab
commit
aa2bd097d6
2 changed files with 219 additions and 5 deletions
|
@ -236,6 +236,45 @@ static inline void copy_type_data(void *dst, const void *src, unsigned type_size
|
|||
out[i] = in[type_size - i - 1];
|
||||
}
|
||||
|
||||
static HRESULT get_data(script_ctx_t *ctx, jsval_t vthis, unsigned argc, jsval_t *argv, unsigned type_size, void *ret)
|
||||
{
|
||||
BOOL little_endian = FALSE;
|
||||
DataViewInstance *view;
|
||||
HRESULT hres;
|
||||
DWORD offset;
|
||||
BYTE *data;
|
||||
double n;
|
||||
|
||||
if(!(view = dataview_this(vthis)))
|
||||
return JS_E_NOT_DATAVIEW;
|
||||
if(!argc || is_undefined(argv[0]))
|
||||
return JS_E_DATAVIEW_NO_ARGUMENT;
|
||||
|
||||
hres = to_integer(ctx, argv[0], &n);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(n < 0.0 || n + type_size > view->size)
|
||||
return JS_E_DATAVIEW_INVALID_ACCESS;
|
||||
|
||||
offset = n;
|
||||
data = &view->buffer->buf[view->offset + offset];
|
||||
|
||||
if(type_size == 1) {
|
||||
*(BYTE*)ret = data[0];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if(argc > 1) {
|
||||
hres = to_boolean(argv[1], &little_endian);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
copy_type_data(ret, data, type_size, little_endian);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT set_data(script_ctx_t *ctx, jsval_t vthis, unsigned argc, jsval_t *argv, unsigned type_size, const void *val)
|
||||
{
|
||||
BOOL little_endian = FALSE;
|
||||
|
@ -275,6 +314,118 @@ static HRESULT set_data(script_ctx_t *ctx, jsval_t vthis, unsigned argc, jsval_t
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT DataView_getFloat32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
||||
{
|
||||
HRESULT hres;
|
||||
float v;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(r) *r = jsval_number(v);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT DataView_getFloat64(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
||||
{
|
||||
HRESULT hres;
|
||||
double v;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(r) *r = jsval_number(v);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT DataView_getInt8(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
||||
{
|
||||
HRESULT hres;
|
||||
INT8 v;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(r) *r = jsval_number(v);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT DataView_getInt16(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
||||
{
|
||||
HRESULT hres;
|
||||
INT16 v;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(r) *r = jsval_number(v);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT DataView_getInt32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
||||
{
|
||||
HRESULT hres;
|
||||
INT32 v;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(r) *r = jsval_number(v);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT DataView_getUint8(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
||||
{
|
||||
HRESULT hres;
|
||||
UINT8 v;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(r) *r = jsval_number(v);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT DataView_getUint16(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
||||
{
|
||||
HRESULT hres;
|
||||
UINT16 v;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(r) *r = jsval_number(v);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT DataView_getUint32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
||||
{
|
||||
HRESULT hres;
|
||||
UINT32 v;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(r) *r = jsval_number(v);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT DataView_setFloat32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
@ -382,6 +533,14 @@ static HRESULT DataView_setInt32(script_ctx_t *ctx, jsval_t vthis, WORD flags, u
|
|||
}
|
||||
|
||||
static const builtin_prop_t DataView_props[] = {
|
||||
{L"getFloat32", DataView_getFloat32, PROPF_METHOD|1},
|
||||
{L"getFloat64", DataView_getFloat64, PROPF_METHOD|1},
|
||||
{L"getInt16", DataView_getInt16, PROPF_METHOD|1},
|
||||
{L"getInt32", DataView_getInt32, PROPF_METHOD|1},
|
||||
{L"getInt8", DataView_getInt8, PROPF_METHOD|1},
|
||||
{L"getUint16", DataView_getUint16, PROPF_METHOD|1},
|
||||
{L"getUint32", DataView_getUint32, PROPF_METHOD|1},
|
||||
{L"getUint8", DataView_getUint8, PROPF_METHOD|1},
|
||||
{L"setFloat32", DataView_setFloat32, PROPF_METHOD|1},
|
||||
{L"setFloat64", DataView_setFloat64, PROPF_METHOD|1},
|
||||
{L"setInt16", DataView_setInt16, PROPF_METHOD|1},
|
||||
|
|
|
@ -1751,10 +1751,10 @@ sync_test("ArrayBuffers & Views", function() {
|
|||
|
||||
test_own_props("DataView.prototype", [
|
||||
"buffer", "byteLength", "byteOffset",
|
||||
"setInt8", "setUint8",
|
||||
"setInt16", "setUint16",
|
||||
"setInt32", "setUint32",
|
||||
"setFloat32", "setFloat64"
|
||||
"getInt8", "setInt8", "getUint8", "setUint8",
|
||||
"getInt16", "setInt16", "getUint16", "setUint16",
|
||||
"getInt32", "setInt32", "getUint32", "setUint32",
|
||||
"getFloat32", "setFloat32", "getFloat64", "setFloat64"
|
||||
]);
|
||||
|
||||
r = Object.prototype.toString.call(new DataView(buf));
|
||||
|
@ -1869,8 +1869,51 @@ sync_test("ArrayBuffers & Views", function() {
|
|||
ok(view.byteLength === 10, "DataView(buf).byteLength = " + view.byteLength);
|
||||
ok(view.byteOffset === 0, "DataView(buf).byteOffset = " + view.byteOffset);
|
||||
|
||||
for(i = 0; i < 10; i++) {
|
||||
r = view.getInt8(i);
|
||||
ok(r === 0, "view byte " + i + " = " + r);
|
||||
}
|
||||
|
||||
for(i = 0; i < types.length; i++) {
|
||||
var method = "set" + types[i][0], offs = 11 - types[i][1];
|
||||
var method = "get" + types[i][0], offs = 11 - types[i][1];
|
||||
r = DataView.prototype[method].length;
|
||||
ok(r === 1, "DataView.prototype." + method + ".length = " + r);
|
||||
try {
|
||||
view[method]();
|
||||
ok(false, "view." + method + "() did not throw exception");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_DATAVIEW_NO_ARGUMENT, "view." + method + "() threw " + n);
|
||||
}
|
||||
try {
|
||||
view[method](-1);
|
||||
ok(false, "view." + method + "(-1) did not throw exception");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_DATAVIEW_INVALID_ACCESS, "view." + method + "(-1) threw " + n);
|
||||
}
|
||||
try {
|
||||
view[method](offs);
|
||||
ok(false, "view." + method + "(" + offs + ") did not throw exception");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_DATAVIEW_INVALID_ACCESS, "view." + method + "(" + offs + ") threw " + n);
|
||||
}
|
||||
try {
|
||||
view[method].call(null, 0);
|
||||
ok(false, "view." + method + "(0) with null context did not throw exception");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_NOT_DATAVIEW, "view." + method + "(0) with null context threw " + n);
|
||||
}
|
||||
try {
|
||||
view[method].call({}, 0);
|
||||
ok(false, "view." + method + "(0) with an object context did not throw exception");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_NOT_DATAVIEW, "view." + method + "(0) with an object context threw " + n);
|
||||
}
|
||||
method = "set" + types[i][0];
|
||||
r = DataView.prototype[method].length;
|
||||
ok(r === 1, "DataView.prototype." + method + ".length = " + r);
|
||||
try {
|
||||
|
@ -1919,14 +1962,26 @@ sync_test("ArrayBuffers & Views", function() {
|
|||
|
||||
r = view.setInt8(1, -257);
|
||||
ok(r === undefined, "view.setInt8(1, -1) returned " + r);
|
||||
r = view.getUint16(0);
|
||||
ok(r === 255, "view.getUint16(0) returned " + r);
|
||||
r = view.getUint16(0, true);
|
||||
ok(r === 65280, "view.getUint16(0, true) returned " + r);
|
||||
r = view.setUint32(2, "12345678", true);
|
||||
ok(r === undefined, "view.setUint32(2, '12345678', true) returned " + r);
|
||||
r = view.getInt32(1);
|
||||
ok(r === -11640388, "view.getInt32(1) returned " + r);
|
||||
r = view.setInt16(3, 65535, true);
|
||||
ok(r === undefined, "view.setInt16(3, 65535) returned " + r);
|
||||
r = view.getUint16(3);
|
||||
ok(r === 65535, "view.getUint16(3) returned " + r);
|
||||
r = view.setUint32(0, -2, true);
|
||||
ok(r === undefined, "view.setUint32(0, -2) returned " + r);
|
||||
r = view.getInt32(0, true);
|
||||
ok(r === -2, "view.getInt32(0) returned " + r);
|
||||
r = view.setFloat32(6, 1234.5, true);
|
||||
ok(r === undefined, "view.setFloat32(6, 1234.5) returned " + r);
|
||||
r = view2.getFloat32(0, true);
|
||||
ok(r === 1234.5, "view2.getFloat32(0) returned " + r);
|
||||
|
||||
/* setters differing only in signedness have identical behavior, but they're not the same methods */
|
||||
ok(view.setInt8 !== view.setUint8, "setInt8 and setUint8 are the same method");
|
||||
|
|
Loading…
Add table
Reference in a new issue