serialize.js
119 lines
| 3.9 KiB
| application/javascript
|
JavascriptLexer
MinRK
|
r18331 | // Copyright (c) IPython Development Team. | |
// Distributed under the terms of the Modified BSD License. | |||
define([ | |||
MinRK
|
r18416 | 'underscore', | |
], function (_) { | |||
MinRK
|
r18331 | "use strict"; | |
MinRK
|
r18332 | ||
var _deserialize_array_buffer = function (buf) { | |||
var data = new DataView(buf); | |||
// read the header: 1 + nbufs 32b integers | |||
MinRK
|
r18338 | var nbufs = data.getUint32(0); | |
MinRK
|
r18332 | var offsets = []; | |
var i; | |||
for (i = 1; i <= nbufs; i++) { | |||
MinRK
|
r18338 | offsets.push(data.getUint32(i * 4)); | |
MinRK
|
r18332 | } | |
MinRK
|
r18333 | var json_bytes = new Uint8Array(buf.slice(offsets[0], offsets[1])); | |
MinRK
|
r18416 | var msg = JSON.parse( | |
MinRK
|
r18333 | (new TextDecoder('utf8')).decode(json_bytes) | |
MinRK
|
r18332 | ); | |
// the remaining chunks are stored as DataViews in msg.buffers | |||
msg.buffers = []; | |||
var start, stop; | |||
for (i = 1; i < nbufs; i++) { | |||
start = offsets[i]; | |||
stop = offsets[i+1] || buf.byteLength; | |||
msg.buffers.push(new DataView(buf.slice(start, stop))); | |||
} | |||
return msg; | |||
}; | |||
var _deserialize_binary = function(data, callback) { | |||
Jonathan Frederic
|
r19176 | /** | |
* deserialize the binary message format | |||
* callback will be called with a message whose buffers attribute | |||
* will be an array of DataViews. | |||
*/ | |||
MinRK
|
r18332 | if (data instanceof Blob) { | |
// data is Blob, have to deserialize from ArrayBuffer in reader callback | |||
var reader = new FileReader(); | |||
reader.onload = function () { | |||
var msg = _deserialize_array_buffer(this.result); | |||
callback(msg); | |||
}; | |||
reader.readAsArrayBuffer(data); | |||
} else { | |||
// data is ArrayBuffer, can deserialize directly | |||
var msg = _deserialize_array_buffer(data); | |||
MinRK
|
r18331 | callback(msg); | |
MinRK
|
r18332 | } | |
MinRK
|
r18331 | }; | |
var deserialize = function (data, callback) { | |||
Jonathan Frederic
|
r19176 | /** | |
* deserialize a message and pass the unpacked message object to callback | |||
*/ | |||
MinRK
|
r18331 | if (typeof data === "string") { | |
// text JSON message | |||
MinRK
|
r18416 | callback(JSON.parse(data)); | |
MinRK
|
r18331 | } else { | |
// binary message | |||
_deserialize_binary(data, callback); | |||
} | |||
}; | |||
MinRK
|
r18332 | var _serialize_binary = function (msg) { | |
Jonathan Frederic
|
r19176 | /** | |
* implement the binary serialization protocol | |||
* serializes JSON message to ArrayBuffer | |||
*/ | |||
MinRK
|
r18416 | msg = _.clone(msg); | |
MinRK
|
r18332 | var offsets = []; | |
MinRK
|
r18337 | var buffers = []; | |
MinRK
|
r18416 | msg.buffers.map(function (buf) { | |
MinRK
|
r18337 | buffers.push(buf); | |
}); | |||
MinRK
|
r18332 | delete msg.buffers; | |
MinRK
|
r18333 | var json_utf8 = (new TextEncoder('utf8')).encode(JSON.stringify(msg)); | |
MinRK
|
r18332 | buffers.unshift(json_utf8); | |
var nbufs = buffers.length; | |||
offsets.push(4 * (nbufs + 1)); | |||
var i; | |||
for (i = 0; i + 1 < buffers.length; i++) { | |||
offsets.push(offsets[offsets.length-1] + buffers[i].byteLength); | |||
} | |||
var msg_buf = new Uint8Array( | |||
offsets[offsets.length-1] + buffers[buffers.length-1].byteLength | |||
); | |||
MinRK
|
r18338 | // use DataView.setUint32 for network byte-order | |
MinRK
|
r18332 | var view = new DataView(msg_buf.buffer); | |
// write nbufs to first 4 bytes | |||
MinRK
|
r18338 | view.setUint32(0, nbufs); | |
MinRK
|
r18332 | // write offsets to next 4 * nbufs bytes | |
for (i = 0; i < offsets.length; i++) { | |||
MinRK
|
r18338 | view.setUint32(4 * (i+1), offsets[i]); | |
MinRK
|
r18332 | } | |
// write all the buffers at their respective offsets | |||
for (i = 0; i < buffers.length; i++) { | |||
msg_buf.set(new Uint8Array(buffers[i].buffer), offsets[i]); | |||
} | |||
// return raw ArrayBuffer | |||
return msg_buf.buffer; | |||
}; | |||
var serialize = function (msg) { | |||
if (msg.buffers && msg.buffers.length) { | |||
return _serialize_binary(msg); | |||
} else { | |||
return JSON.stringify(msg); | |||
} | |||
}; | |||
var exports = { | |||
deserialize : deserialize, | |||
serialize: serialize | |||
MinRK
|
r18331 | }; | |
MinRK
|
r18332 | return exports; | |
MinRK
|
r18331 | }); |