diff --git a/core/decoders/hextile.js b/core/decoders/hextile.js index ac21eff0..6d96927f 100644 --- a/core/decoders/hextile.js +++ b/core/decoders/hextile.js @@ -31,10 +31,7 @@ export default class HextileDecoder { return false; } - let rQ = sock.rQ; - let rQi = sock.rQi; - - let subencoding = rQ[rQi]; // Peek + let subencoding = sock.rQpeek8(); if (subencoding > 30) { // Raw throw new Error("Illegal hextile subencoding (subencoding: " + subencoding + ")"); @@ -65,7 +62,7 @@ export default class HextileDecoder { return false; } - let subrects = rQ[rQi + bytes - 1]; // Peek + let subrects = sock.rQpeekBytes(bytes).at(-1); if (subencoding & 0x10) { // SubrectsColoured bytes += subrects * (4 + 2); } else { @@ -79,7 +76,7 @@ export default class HextileDecoder { } // We know the encoding and have a whole tile - rQi++; + sock.rQshift8(); if (subencoding === 0) { if (this._lastsubencoding & 0x01) { // Weird: ignore blanks are RAW @@ -89,42 +86,36 @@ export default class HextileDecoder { } } else if (subencoding & 0x01) { // Raw let pixels = tw * th; + let data = sock.rQshiftBytes(pixels * 4); // Max sure the image is fully opaque for (let i = 0;i < pixels;i++) { - rQ[rQi + i * 4 + 3] = 255; + data[i * 4 + 3] = 255; } - display.blitImage(tx, ty, tw, th, rQ, rQi); - rQi += bytes - 1; + display.blitImage(tx, ty, tw, th, data, 0); } else { if (subencoding & 0x02) { // Background - this._background = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; - rQi += 4; + this._background = new Uint8Array(sock.rQshiftBytes(4)); } if (subencoding & 0x04) { // Foreground - this._foreground = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; - rQi += 4; + this._foreground = new Uint8Array(sock.rQshiftBytes(4)); } this._startTile(tx, ty, tw, th, this._background); if (subencoding & 0x08) { // AnySubrects - let subrects = rQ[rQi]; - rQi++; + let subrects = sock.rQshift8(); for (let s = 0; s < subrects; s++) { let color; if (subencoding & 0x10) { // SubrectsColoured - color = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; - rQi += 4; + color = sock.rQshiftBytes(4); } else { color = this._foreground; } - const xy = rQ[rQi]; - rQi++; + const xy = sock.rQshift8(); const sx = (xy >> 4); const sy = (xy & 0x0f); - const wh = rQ[rQi]; - rQi++; + const wh = sock.rQshift8(); const sw = (wh >> 4) + 1; const sh = (wh & 0x0f) + 1; @@ -133,7 +124,6 @@ export default class HextileDecoder { } this._finishTile(display); } - sock.rQi = rQi; this._lastsubencoding = subencoding; this._tiles--; } diff --git a/core/decoders/raw.js b/core/decoders/raw.js index d08f7ba9..c69ec7ac 100644 --- a/core/decoders/raw.js +++ b/core/decoders/raw.js @@ -33,29 +33,26 @@ export default class RawDecoder { Math.floor(sock.rQlen / bytesPerLine)); const pixels = width * currHeight; - let data = sock.rQ; - let index = sock.rQi; + let data = sock.rQshiftBytes(currHeight * bytesPerLine); // Convert data if needed if (depth == 8) { const newdata = new Uint8Array(pixels * 4); for (let i = 0; i < pixels; i++) { - newdata[i * 4 + 0] = ((data[index + i] >> 0) & 0x3) * 255 / 3; - newdata[i * 4 + 1] = ((data[index + i] >> 2) & 0x3) * 255 / 3; - newdata[i * 4 + 2] = ((data[index + i] >> 4) & 0x3) * 255 / 3; + newdata[i * 4 + 0] = ((data[i] >> 0) & 0x3) * 255 / 3; + newdata[i * 4 + 1] = ((data[i] >> 2) & 0x3) * 255 / 3; + newdata[i * 4 + 2] = ((data[i] >> 4) & 0x3) * 255 / 3; newdata[i * 4 + 3] = 255; } data = newdata; - index = 0; } // Max sure the image is fully opaque for (let i = 0; i < pixels; i++) { - data[index + i * 4 + 3] = 255; + data[i * 4 + 3] = 255; } - display.blitImage(x, curY, width, currHeight, data, index); - sock.rQskipBytes(currHeight * bytesPerLine); + display.blitImage(x, curY, width, currHeight, data, 0); this._lines -= currHeight; if (this._lines > 0) { return false; diff --git a/core/decoders/tight.js b/core/decoders/tight.js index 7952707c..5eaed545 100644 --- a/core/decoders/tight.js +++ b/core/decoders/tight.js @@ -76,12 +76,8 @@ export default class TightDecoder { return false; } - const rQi = sock.rQi; - const rQ = sock.rQ; - - display.fillRect(x, y, width, height, - [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2]], false); - sock.rQskipBytes(3); + let pixel = sock.rQshiftBytes(3); + display.fillRect(x, y, width, height, pixel, false); return true; } diff --git a/core/websock.js b/core/websock.js index 3813af1c..d5f03d28 100644 --- a/core/websock.js +++ b/core/websock.js @@ -94,22 +94,6 @@ export default class Websock { return "unknown"; } - get sQ() { - return this._sQ; - } - - get rQ() { - return this._rQ; - } - - get rQi() { - return this._rQi; - } - - set rQi(val) { - this._rQi = val; - } - // Receive Queue get rQlen() { return this._rQlen - this._rQi; diff --git a/tests/test.websock.js b/tests/test.websock.js index d2e20e0d..4b6fe230 100644 --- a/tests/test.websock.js +++ b/tests/test.websock.js @@ -19,13 +19,13 @@ describe('Websock', function () { }); describe('rQlen', function () { it('should return the length of the receive queue', function () { - sock.rQi = 0; + sock._rQi = 0; expect(sock.rQlen).to.equal(RQ_TEMPLATE.length); }); it("should return the proper length if we read some from the receive queue", function () { - sock.rQi = 1; + sock._rQi = 1; expect(sock.rQlen).to.equal(RQ_TEMPLATE.length - 1); }); @@ -72,8 +72,8 @@ describe('Websock', function () { describe('rQshiftStr', function () { it('should shift the given number of bytes off of the receive queue and return a string', function () { - const befLen = sock.rQlen; - const befRQi = sock.rQi; + const befLen = sock._rQlen; + const befRQi = sock._rQi; const shifted = sock.rQshiftStr(3); expect(shifted).to.be.a('string'); expect(shifted).to.equal(String.fromCharCode.apply(null, Array.prototype.slice.call(new Uint8Array(RQ_TEMPLATE.buffer, befRQi, 3)))); @@ -112,8 +112,8 @@ describe('Websock', function () { describe('rQshiftBytes', function () { it('should shift the given number of bytes of the receive queue and return an array', function () { - const befLen = sock.rQlen; - const befRQi = sock.rQi; + const befLen = sock._rQlen; + const befRQi = sock._rQi; const shifted = sock.rQshiftBytes(3); expect(shifted).to.be.an.instanceof(Uint8Array); expect(shifted).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, befRQi, 3)); @@ -128,7 +128,7 @@ describe('Websock', function () { describe('rQpeekBytes', function () { beforeEach(function () { - sock.rQi = 0; + sock._rQi = 0; }); it('should not modify the receive queue', function () { @@ -150,14 +150,14 @@ describe('Websock', function () { }); it('should take the current rQi in to account', function () { - sock.rQi = 1; + sock._rQi = 1; expect(sock.rQpeekBytes(2)).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, 1, 2)); }); }); describe('rQwait', function () { beforeEach(function () { - sock.rQi = 0; + sock._rQi = 0; }); it('should return true if there are not enough bytes in the receive queue', function () { @@ -169,20 +169,20 @@ describe('Websock', function () { }); it('should return true and reduce rQi by "goback" if there are not enough bytes', function () { - sock.rQi = 5; + sock._rQi = 5; expect(sock.rQwait('hi', RQ_TEMPLATE.length, 4)).to.be.true; - expect(sock.rQi).to.equal(1); + expect(sock._rQi).to.equal(1); }); it('should raise an error if we try to go back more than possible', function () { - sock.rQi = 5; + sock._rQi = 5; expect(() => sock.rQwait('hi', RQ_TEMPLATE.length, 6)).to.throw(Error); }); it('should not reduce rQi if there are enough bytes', function () { - sock.rQi = 5; + sock._rQi = 5; sock.rQwait('hi', 1, 6); - expect(sock.rQi).to.equal(5); + expect(sock._rQi).to.equal(5); }); }); }); @@ -461,52 +461,52 @@ describe('Websock', function () { }); it('should compact the receive queue when a message handler empties it', function () { - sock._eventHandlers.message = () => { sock.rQi = sock._rQlen; }; + sock._eventHandlers.message = () => { sock._rQi = sock._rQlen; }; sock._rQ = new Uint8Array([0, 1, 2, 3, 4, 5, 0, 0, 0, 0]); sock._rQlen = 6; - sock.rQi = 6; + sock._rQi = 6; const msg = { data: new Uint8Array([1, 2, 3]).buffer }; sock._mode = 'binary'; sock._recvMessage(msg); expect(sock._rQlen).to.equal(0); - expect(sock.rQi).to.equal(0); + expect(sock._rQi).to.equal(0); }); it('should compact the receive queue when we reach the end of the buffer', function () { sock._rQ = new Uint8Array(20); sock._rQbufferSize = 20; sock._rQlen = 20; - sock.rQi = 10; + sock._rQi = 10; const msg = { data: new Uint8Array([1, 2]).buffer }; sock._mode = 'binary'; sock._recvMessage(msg); expect(sock._rQlen).to.equal(12); - expect(sock.rQi).to.equal(0); + expect(sock._rQi).to.equal(0); }); it('should automatically resize the receive queue if the incoming message is larger than the buffer', function () { sock._rQ = new Uint8Array(20); sock._rQlen = 0; - sock.rQi = 0; + sock._rQi = 0; sock._rQbufferSize = 20; const msg = { data: new Uint8Array(30).buffer }; sock._mode = 'binary'; sock._recvMessage(msg); expect(sock._rQlen).to.equal(30); - expect(sock.rQi).to.equal(0); + expect(sock._rQi).to.equal(0); expect(sock._rQ.length).to.equal(240); // keep the invariant that rQbufferSize / 8 >= rQlen }); it('should automatically resize the receive queue if the incoming message is larger than 1/8th of the buffer and we reach the end of the buffer', function () { sock._rQ = new Uint8Array(20); sock._rQlen = 16; - sock.rQi = 16; + sock._rQi = 16; sock._rQbufferSize = 20; const msg = { data: new Uint8Array(6).buffer }; sock._mode = 'binary'; sock._recvMessage(msg); expect(sock._rQlen).to.equal(6); - expect(sock.rQi).to.equal(0); + expect(sock._rQi).to.equal(0); expect(sock._rQ.length).to.equal(48); }); });