[gjs/5-replace-bytearray-with-native-es6-typedarray] byteArray: Add backwards-compatible ByteArray class
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/5-replace-bytearray-with-native-es6-typedarray] byteArray: Add backwards-compatible ByteArray class
- Date: Wed, 15 Nov 2017 07:53:11 +0000 (UTC)
commit 7029ef2a45561db649f5c519e1a0e4dbca126733
Author: Philip Chimento <philip chimento gmail com>
Date: Mon Oct 30 11:09:04 2017 -0700
byteArray: Add backwards-compatible ByteArray class
This should make it easier to keep old code working. It adds a legacy
ByteArray.ByteArray class that works just like the old ByteArray class
but uses Uint8Array internally. However, it is not zero-copy.
https://gitlab.gnome.org/GNOME/gjs/issues/5
Makefile-test.am | 1 +
NEWS | 14 +++-
installed-tests/js/testByteArray.js | 6 --
installed-tests/js/testLegacyByteArray.js | 115 ++++++++++++++++++++++++++++++
modules/byteArray.js | 57 +++++++++++++--
modules/overrides/GLib.js | 4 +-
6 files changed, 182 insertions(+), 15 deletions(-)
---
diff --git a/Makefile-test.am b/Makefile-test.am
index 5ea78ad..4315b42 100644
--- a/Makefile-test.am
+++ b/Makefile-test.am
@@ -204,6 +204,7 @@ common_jstests_files = \
installed-tests/js/testGio.js \
installed-tests/js/testImporter.js \
installed-tests/js/testLang.js \
+ installed-tests/js/testLegacyByteArray.js \
installed-tests/js/testLegacyClass.js \
installed-tests/js/testLegacyGObject.js \
installed-tests/js/testLocale.js \
diff --git a/NEWS b/NEWS
index 810e7e5..ba156cc 100644
--- a/NEWS
+++ b/NEWS
@@ -4,7 +4,19 @@ NEXT
- Deprecation: the custom ByteArray is now discouraged. Instead of ByteArray,
use Javascript's native Uint8Array. The ByteArray module still contains
functions for converting between byte arrays, strings, and GLib.Bytes
- instances. With a few exceptions, old code will continue to work.
+ instances.
+
+ The old ByteArray will continue to work as before, except that Uint8Array
+ will now be returned from introspected functions that previously returned a
+ ByteArray. To keep your old code working, change this:
+
+ let byteArray = functionThatReturnsByteArray();
+
+ to this:
+
+ let byteArray = new ByteArray.ByteArray(functionThatReturnsByteArray());
+
+ To port to the new code:
* ByteArray.ByteArray -> Uint8Array
* ByteArray.fromArray() -> Uint8Array.from()
diff --git a/installed-tests/js/testByteArray.js b/installed-tests/js/testByteArray.js
index 3e1ea2c..6746df4 100644
--- a/installed-tests/js/testByteArray.js
+++ b/installed-tests/js/testByteArray.js
@@ -25,12 +25,6 @@ describe('Byte array', function () {
[0xe2, 0x85, 0x9c].forEach((val, ix) => expect(a[ix]).toEqual(val));
});
- it('can be created from an array', function () {
- let a = ByteArray.fromArray([ 1, 2, 3, 4 ]);
- expect(a.length).toEqual(4);
- [1, 2, 3, 4].forEach((val, ix) => expect(a[ix]).toEqual(val));
- });
-
it('can be converted to a string of ASCII characters', function () {
let a = new Uint8Array(4);
a[0] = 97;
diff --git a/installed-tests/js/testLegacyByteArray.js b/installed-tests/js/testLegacyByteArray.js
new file mode 100644
index 0000000..ed1b8c3
--- /dev/null
+++ b/installed-tests/js/testLegacyByteArray.js
@@ -0,0 +1,115 @@
+const ByteArray = imports.byteArray;
+const GIMarshallingTests = imports.gi.GIMarshallingTests;
+
+describe('Legacy byte array', function () {
+ it('has length 0 for empty array', function () {
+ let a = new ByteArray.ByteArray();
+ expect(a.length).toEqual(0);
+ });
+
+ describe('initially sized to 10', function () {
+ let a;
+ beforeEach(function () {
+ a = new ByteArray.ByteArray(10);
+ });
+
+ it('has length 10', function () {
+ expect(a.length).toEqual(10);
+ });
+
+ it('is initialized to zeroes', function () {
+ for (let i = 0; i < a.length; ++i) {
+ expect(a[i]).toEqual(0);
+ }
+ });
+ });
+
+ it('assigns values correctly', function () {
+ let a = new ByteArray.ByteArray(256);
+
+ for (let i = 0; i < a.length; ++i) {
+ a[i] = 255 - i;
+ }
+
+ for (let i = 0; i < a.length; ++i) {
+ expect(a[i]).toEqual(255 - i);
+ }
+ });
+
+ describe('assignment past end', function () {
+ let a;
+ beforeEach(function () {
+ a = new ByteArray.ByteArray();
+ a[2] = 5;
+ });
+
+ it('implicitly lengthens the array', function () {
+ expect(a.length).toEqual(3);
+ expect(a[2]).toEqual(5);
+ });
+
+ it('implicitly creates zero bytes', function () {
+ expect(a[0]).toEqual(0);
+ expect(a[1]).toEqual(0);
+ });
+ });
+
+ it('changes the length when assigning to length property', function () {
+ let a = new ByteArray.ByteArray(20);
+ expect(a.length).toEqual(20);
+ a.length = 5;
+ expect(a.length).toEqual(5);
+ });
+
+
+ describe('conversions', function () {
+ let a;
+ beforeEach(function () {
+ a = new ByteArray.ByteArray();
+ a[0] = 255;
+ });
+
+ it('gives a byte 5 when assigning 5', function () {
+ a[0] = 5;
+ expect(a[0]).toEqual(5);
+ });
+
+ it('gives a byte 0 when assigning null', function () {
+ a[0] = null;
+ expect(a[0]).toEqual(0);
+ });
+
+ it('gives a byte 0 when assigning undefined', function () {
+ a[0] = undefined;
+ expect(a[0]).toEqual(0);
+ });
+
+ it('rounds off when assigning a double', function () {
+ a[0] = 3.14;
+ expect(a[0]).toEqual(3);
+ });
+ });
+
+ it('can be created from an array', function () {
+ let a = ByteArray.fromArray([ 1, 2, 3, 4 ]);
+ expect(a.length).toEqual(4);
+ [1, 2, 3, 4].forEach((val, ix) => expect(a[ix]).toEqual(val));
+ });
+
+ it('can be converted to a string of ASCII characters', function () {
+ let a = new ByteArray.ByteArray(4);
+ a[0] = 97;
+ a[1] = 98;
+ a[2] = 99;
+ a[3] = 100;
+ let s = a.toString();
+ expect(s.length).toEqual(4);
+ expect(s).toEqual('abcd');
+ });
+
+ it('can be passed in with transfer none', function () {
+ const refByteArray = ByteArray.fromArray([0, 49, 0xFF, 51]);
+ expect(() => GIMarshallingTests.bytearray_none_in(refByteArray))
+ .not.toThrow();
+ });
+});
diff --git a/modules/byteArray.js b/modules/byteArray.js
index b12a001..dcd8e2e 100644
--- a/modules/byteArray.js
+++ b/modules/byteArray.js
@@ -5,15 +5,58 @@ var {fromGBytes, fromString, toGBytes, toString} = imports._byteArrayNative;
// For backwards compatibility
function fromArray(a) {
- return Uint8Array.from(a);
+ return new ByteArray(Uint8Array.from(a));
}
-var ByteArray = Uint8Array;
+var ByteArray = class ByteArray {
+ constructor(arg=0) {
+ if (arg instanceof Uint8Array)
+ this._array = arg;
+ else
+ this._array = new Uint8Array(arg);
+ return new Proxy(this, ByteArray);
+ }
-Uint8Array.prototype.toString = function (encoding='UTF-8') {
- return toString(this, encoding);
-};
+ static get(target, prop, receiver) {
+ if (!Number.isNaN(Number.parseInt(prop)))
+ return Reflect.get(target._array, prop);
+ return Reflect.get(target, prop, receiver);
+ }
+
+ static set(target, prop, val, receiver) {
+ let ix = Number.parseInt(prop);
+ if (!Number.isNaN(ix)) {
+ if (ix >= target._array.length) {
+ let newArray = new Uint8Array(ix + 1);
+ newArray.set(target._array);
+ target._array = newArray;
+ }
+ return Reflect.set(target._array, prop, val);
+ }
+ return Reflect.set(target, prop, val, receiver);
+ }
+
+ get length() {
+ return this._array.length;
+ }
+
+ set length(newLength) {
+ if (newLength === this._array.length)
+ return;
+ if (newLength < this._array.length) {
+ this._array = new Uint8Array(this._array.buffer, 0, newLength);
+ return;
+ }
+ let newArray = new Uint8Array(newLength);
+ newArray.set(this._array);
+ this._array = newArray;
+ }
+
+ toString(encoding='UTF-8') {
+ return toString(this._array, encoding);
+ }
-Uint8Array.prototype.toGBytes = function () {
- return toGBytes(this);
+ toGBytes() {
+ return toGBytes(this._array);
+ }
};
diff --git a/modules/overrides/GLib.js b/modules/overrides/GLib.js
index ee50560..0fdaf3d 100644
--- a/modules/overrides/GLib.js
+++ b/modules/overrides/GLib.js
@@ -18,6 +18,8 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
+const ByteArray = imports.byteArray;
+
let GLib;
let originalVariantClass;
@@ -66,7 +68,7 @@ function _read_single_type(signature, forceSimple) {
}
function _makeBytes(byteArray) {
- if (byteArray instanceof Uint8Array)
+ if (byteArray instanceof Uint8Array || byteArray instanceof ByteArray.ByteArray)
return byteArray.toGBytes();
else
return new GLib.Bytes(byteArray);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]