123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- define([
- 'underscore',
- ], function (_) {
- "use strict";
-
- var _deserialize_array_buffer = function (buf) {
- var data = new DataView(buf);
- // read the header: 1 + nbufs 32b integers
- var nbufs = data.getUint32(0);
- var offsets = [];
- var i;
- for (i = 1; i <= nbufs; i++) {
- offsets.push(data.getUint32(i * 4));
- }
- var json_bytes = new Uint8Array(buf.slice(offsets[0], offsets[1]));
- var msg = JSON.parse(
- (new TextDecoder('utf8')).decode(json_bytes)
- );
- // 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) {
- /**
- * deserialize the binary message format
- * callback will be called with a message whose buffers attribute
- * will be an array of DataViews.
- */
- if (data instanceof Blob) {
- // data is Blob, have to deserialize from ArrayBuffer in reader callback
- var reader = new FileReader();
- var promise = new Promise(function(resolve, reject) {
- reader.onload = function () {
- var msg = _deserialize_array_buffer(this.result);
- resolve(msg);
- };
- });
- reader.readAsArrayBuffer(data);
- return promise;
- } else {
- // data is ArrayBuffer, can deserialize directly
- var msg = _deserialize_array_buffer(data);
- return msg;
- }
- };
- var deserialize = function (data) {
- /**
- * deserialize a message and return a promise for the unpacked message
- */
- if (typeof data === "string") {
- // text JSON message
- return Promise.resolve(JSON.parse(data));
- } else {
- // binary message
- return Promise.resolve(_deserialize_binary(data));
- }
- };
-
- var _serialize_binary = function (msg) {
- /**
- * implement the binary serialization protocol
- * serializes JSON message to ArrayBuffer
- */
- msg = _.clone(msg);
- var offsets = [];
- var buffers = [];
- var i;
- for (i = 0; i < msg.buffers.length; i++) {
- // msg.buffers elements could be either views or ArrayBuffers
- // buffers elements are ArrayBuffers
- var b = msg.buffers[i];
- buffers.push(b.buffer instanceof ArrayBuffer ? b.buffer : b);
- }
- delete msg.buffers;
- var json_utf8 = (new TextEncoder('utf8')).encode(JSON.stringify(msg));
- buffers.unshift(json_utf8);
- var nbufs = buffers.length;
- offsets.push(4 * (nbufs + 1));
- 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
- );
- // use DataView.setUint32 for network byte-order
- var view = new DataView(msg_buf.buffer);
- // write nbufs to first 4 bytes
- view.setUint32(0, nbufs);
- // write offsets to next 4 * nbufs bytes
- for (i = 0; i < offsets.length; i++) {
- view.setUint32(4 * (i+1), offsets[i]);
- }
- // write all the buffers at their respective offsets
- for (i = 0; i < buffers.length; i++) {
- msg_buf.set(new Uint8Array(buffers[i]), 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
- };
- return exports;
- });
|