Skip to content

Commit 0d3eaca

Browse files
committed
Merge pull request #52 from darrachequesne/patch-1
Fix ArrayBuffer encoding in base64 string
2 parents 3aee0c7 + 96fa4f9 commit 0d3eaca

File tree

2 files changed

+72
-25
lines changed

2 files changed

+72
-25
lines changed

lib/index.js

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {
6363
if (Buffer.isBuffer(packet.data)) {
6464
return encodeBuffer(packet, supportsBinary, callback);
6565
} else if (packet.data && (packet.data.buffer || packet.data) instanceof ArrayBuffer) {
66-
return encodeArrayBuffer(packet, supportsBinary, callback);
66+
packet.data = arrayBufferToBuffer(packet.data);
67+
return encodeBuffer(packet, supportsBinary, callback);
6768
}
6869

6970
// Sending data as a utf-8 string
@@ -92,24 +93,6 @@ function encodeBuffer(packet, supportsBinary, callback) {
9293
return callback(Buffer.concat([typeBuffer, data]));
9394
}
9495

95-
function encodeArrayBuffer(packet, supportsBinary, callback) {
96-
97-
var data = packet.data.buffer || packet.data;
98-
99-
if (!supportsBinary) {
100-
return exports.encodeBase64Packet(packet, callback);
101-
}
102-
103-
var contentArray = new Uint8Array(data);
104-
var resultBuffer = new Buffer(1 + data.byteLength);
105-
106-
resultBuffer[0] = packets[packet.type];
107-
for (var i = 0; i < contentArray.length; i++){
108-
resultBuffer[i+1] = contentArray[i];
109-
}
110-
return callback(resultBuffer);
111-
}
112-
11396
/**
11497
* Encodes a packet with binary data in a base64 string
11598
*
@@ -118,13 +101,8 @@ function encodeArrayBuffer(packet, supportsBinary, callback) {
118101
*/
119102

120103
exports.encodeBase64Packet = function(packet, callback){
121-
122104
if (!Buffer.isBuffer(packet.data)) {
123-
var buf = new Buffer(packet.data.byteLength);
124-
for (var i = 0; i < buf.length; i++) {
125-
buf[i] = packet.data[i];
126-
}
127-
packet.data = buf;
105+
packet.data = arrayBufferToBuffer(packet.data);
128106
}
129107

130108
var message = 'b' + packets[packet.type];
@@ -364,6 +342,26 @@ function stringToBuffer(string) {
364342
return buf;
365343
}
366344

345+
/**
346+
*
347+
* Converts an ArrayBuffer to a Buffer
348+
*
349+
* @api private
350+
*/
351+
352+
function arrayBufferToBuffer(data) {
353+
// data is either an ArrayBuffer or ArrayBufferView.
354+
var array = new Uint8Array(data.buffer || data);
355+
var length = data.byteLength || data.length;
356+
var offset = data.byteOffset || 0;
357+
var buffer = new Buffer(length);
358+
359+
for (var i = 0; i < length; i++) {
360+
buffer[i] = array[offset + i];
361+
}
362+
return buffer;
363+
}
364+
367365
/**
368366
* Encodes multiple messages (payload) as binary.
369367
*

test/node/index.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,53 @@ describe('parser', function() {
8989
});
9090
});
9191
});
92+
93+
it('should encode/decode an ArrayBuffer as b64', function(done) {
94+
var buffer = new ArrayBuffer(4);
95+
var dataview = new DataView(buffer);
96+
for (var i = 0; i < buffer.byteLength ; i++) dataview.setInt8(i, i);
97+
98+
encode({ type: 'message', data: buffer }, function(encoded) {
99+
var decoded = decode(encoded, 'arraybuffer');
100+
expect(decoded).to.eql({ type: 'message', data: buffer });
101+
expect(new Uint8Array(decoded.data)).to.eql(new Uint8Array(buffer));
102+
done();
103+
});
104+
});
105+
106+
it('should encode/decode an ArrayBuffer as binary', function(done) {
107+
var buffer = new ArrayBuffer(4);
108+
var dataview = new DataView(buffer);
109+
for (var i = 0; i < buffer.byteLength ; i++) dataview.setInt8(i, i);
110+
111+
encode({ type: 'message', data: buffer }, true, function(encoded) {
112+
var decoded = decode(encoded, 'arraybuffer');
113+
expect(decoded).to.eql({ type: 'message', data: buffer });
114+
expect(new Uint8Array(decoded.data)).to.eql(new Uint8Array(buffer));
115+
done();
116+
});
117+
});
118+
119+
it('should encode/decode a typed array as binary', function(done) {
120+
var buffer = new ArrayBuffer(32);
121+
var typedArray = new Int32Array(buffer, 4, 2);
122+
typedArray[0] = 1;
123+
typedArray[1] = 2;
124+
125+
encode({ type: 'message', data: typedArray }, true, function(encoded) {
126+
var decoded = decode(encoded, 'arraybuffer');
127+
expect(decoded.type).to.eql('message');
128+
expect(areArraysEqual(new Int32Array(decoded.data), typedArray)).to.eql(true);
129+
done();
130+
});
131+
});
132+
92133
});
134+
135+
function areArraysEqual(x, y) {
136+
if (x.length != y.length) return false;
137+
for (var i = 0, l = x.length; i < l; i++) {
138+
if (x[i] !== y[i]) return false;
139+
}
140+
return true;
141+
}

0 commit comments

Comments
 (0)