Show More
@@ -1,123 +1,125 b'' | |||||
1 | // Copyright (c) IPython Development Team. |
|
1 | // Copyright (c) IPython Development Team. | |
2 | // Distributed under the terms of the Modified BSD License. |
|
2 | // Distributed under the terms of the Modified BSD License. | |
3 |
|
3 | |||
4 | define([ |
|
4 | define([ | |
5 | 'underscore', |
|
5 | 'underscore', | |
6 | ], function (_) { |
|
6 | ], function (_) { | |
7 | "use strict"; |
|
7 | "use strict"; | |
8 |
|
8 | |||
9 | var _deserialize_array_buffer = function (buf) { |
|
9 | var _deserialize_array_buffer = function (buf) { | |
10 | var data = new DataView(buf); |
|
10 | var data = new DataView(buf); | |
11 | // read the header: 1 + nbufs 32b integers |
|
11 | // read the header: 1 + nbufs 32b integers | |
12 | var nbufs = data.getUint32(0); |
|
12 | var nbufs = data.getUint32(0); | |
13 | var offsets = []; |
|
13 | var offsets = []; | |
14 | var i; |
|
14 | var i; | |
15 | for (i = 1; i <= nbufs; i++) { |
|
15 | for (i = 1; i <= nbufs; i++) { | |
16 | offsets.push(data.getUint32(i * 4)); |
|
16 | offsets.push(data.getUint32(i * 4)); | |
17 | } |
|
17 | } | |
18 | var json_bytes = new Uint8Array(buf.slice(offsets[0], offsets[1])); |
|
18 | var json_bytes = new Uint8Array(buf.slice(offsets[0], offsets[1])); | |
19 | var msg = JSON.parse( |
|
19 | var msg = JSON.parse( | |
20 | (new TextDecoder('utf8')).decode(json_bytes) |
|
20 | (new TextDecoder('utf8')).decode(json_bytes) | |
21 | ); |
|
21 | ); | |
22 | // the remaining chunks are stored as DataViews in msg.buffers |
|
22 | // the remaining chunks are stored as DataViews in msg.buffers | |
23 | msg.buffers = []; |
|
23 | msg.buffers = []; | |
24 | var start, stop; |
|
24 | var start, stop; | |
25 | for (i = 1; i < nbufs; i++) { |
|
25 | for (i = 1; i < nbufs; i++) { | |
26 | start = offsets[i]; |
|
26 | start = offsets[i]; | |
27 | stop = offsets[i+1] || buf.byteLength; |
|
27 | stop = offsets[i+1] || buf.byteLength; | |
28 | msg.buffers.push(new DataView(buf.slice(start, stop))); |
|
28 | msg.buffers.push(new DataView(buf.slice(start, stop))); | |
29 | } |
|
29 | } | |
30 | return msg; |
|
30 | return msg; | |
31 | }; |
|
31 | }; | |
32 |
|
32 | |||
33 | var _deserialize_binary = function(data) { |
|
33 | var _deserialize_binary = function(data) { | |
34 | /** |
|
34 | /** | |
35 | * deserialize the binary message format |
|
35 | * deserialize the binary message format | |
36 | * callback will be called with a message whose buffers attribute |
|
36 | * callback will be called with a message whose buffers attribute | |
37 | * will be an array of DataViews. |
|
37 | * will be an array of DataViews. | |
38 | */ |
|
38 | */ | |
39 | if (data instanceof Blob) { |
|
39 | if (data instanceof Blob) { | |
40 | // data is Blob, have to deserialize from ArrayBuffer in reader callback |
|
40 | // data is Blob, have to deserialize from ArrayBuffer in reader callback | |
41 | var reader = new FileReader(); |
|
41 | var reader = new FileReader(); | |
42 | var promise = new Promise(function(resolve, reject) { |
|
42 | var promise = new Promise(function(resolve, reject) { | |
43 | reader.onload = function () { |
|
43 | reader.onload = function () { | |
44 | var msg = _deserialize_array_buffer(this.result); |
|
44 | var msg = _deserialize_array_buffer(this.result); | |
45 | resolve(msg); |
|
45 | resolve(msg); | |
46 | }; |
|
46 | }; | |
47 | }); |
|
47 | }); | |
48 | reader.readAsArrayBuffer(data); |
|
48 | reader.readAsArrayBuffer(data); | |
49 | return promise; |
|
49 | return promise; | |
50 | } else { |
|
50 | } else { | |
51 | // data is ArrayBuffer, can deserialize directly |
|
51 | // data is ArrayBuffer, can deserialize directly | |
52 | var msg = _deserialize_array_buffer(data); |
|
52 | var msg = _deserialize_array_buffer(data); | |
53 | return msg; |
|
53 | return msg; | |
54 | } |
|
54 | } | |
55 | }; |
|
55 | }; | |
56 |
|
56 | |||
57 | var deserialize = function (data) { |
|
57 | var deserialize = function (data) { | |
58 | /** |
|
58 | /** | |
59 | * deserialize a message and return a promise for the unpacked message |
|
59 | * deserialize a message and return a promise for the unpacked message | |
60 | */ |
|
60 | */ | |
61 | if (typeof data === "string") { |
|
61 | if (typeof data === "string") { | |
62 | // text JSON message |
|
62 | // text JSON message | |
63 | return Promise.resolve(JSON.parse(data)); |
|
63 | return Promise.resolve(JSON.parse(data)); | |
64 | } else { |
|
64 | } else { | |
65 | // binary message |
|
65 | // binary message | |
66 | return Promise.resolve(_deserialize_binary(data)); |
|
66 | return Promise.resolve(_deserialize_binary(data)); | |
67 | } |
|
67 | } | |
68 | }; |
|
68 | }; | |
69 |
|
69 | |||
70 | var _serialize_binary = function (msg) { |
|
70 | var _serialize_binary = function (msg) { | |
71 | /** |
|
71 | /** | |
72 | * implement the binary serialization protocol |
|
72 | * implement the binary serialization protocol | |
73 | * serializes JSON message to ArrayBuffer |
|
73 | * serializes JSON message to ArrayBuffer | |
74 | */ |
|
74 | */ | |
75 | msg = _.clone(msg); |
|
75 | msg = _.clone(msg); | |
76 | var offsets = []; |
|
76 | var offsets = []; | |
77 | var buffers = []; |
|
77 | var buffers = []; | |
78 | msg.buffers.map(function (buf) { |
|
78 | var i; | |
79 | buffers.push(buf); |
|
79 | for (i = 0; i < msg.buffers.length; i++) { | |
80 | }); |
|
80 | // msg.buffers elements could be either views or ArrayBuffers | |
|
81 | // buffers elements are ArrayBuffers | |||
|
82 | buffers.push(msg.buffers[i].buffer || msg.buffers[i]) | |||
|
83 | } | |||
81 | delete msg.buffers; |
|
84 | delete msg.buffers; | |
82 | var json_utf8 = (new TextEncoder('utf8')).encode(JSON.stringify(msg)); |
|
85 | var json_utf8 = (new TextEncoder('utf8')).encode(JSON.stringify(msg)); | |
83 | buffers.unshift(json_utf8); |
|
86 | buffers.unshift(json_utf8); | |
84 | var nbufs = buffers.length; |
|
87 | var nbufs = buffers.length; | |
85 | offsets.push(4 * (nbufs + 1)); |
|
88 | offsets.push(4 * (nbufs + 1)); | |
86 | var i; |
|
|||
87 | for (i = 0; i + 1 < buffers.length; i++) { |
|
89 | for (i = 0; i + 1 < buffers.length; i++) { | |
88 | offsets.push(offsets[offsets.length-1] + buffers[i].byteLength); |
|
90 | offsets.push(offsets[offsets.length-1] + buffers[i].byteLength); | |
89 | } |
|
91 | } | |
90 | var msg_buf = new Uint8Array( |
|
92 | var msg_buf = new Uint8Array( | |
91 | offsets[offsets.length-1] + buffers[buffers.length-1].byteLength |
|
93 | offsets[offsets.length-1] + buffers[buffers.length-1].byteLength | |
92 | ); |
|
94 | ); | |
93 | // use DataView.setUint32 for network byte-order |
|
95 | // use DataView.setUint32 for network byte-order | |
94 | var view = new DataView(msg_buf.buffer); |
|
96 | var view = new DataView(msg_buf.buffer); | |
95 | // write nbufs to first 4 bytes |
|
97 | // write nbufs to first 4 bytes | |
96 | view.setUint32(0, nbufs); |
|
98 | view.setUint32(0, nbufs); | |
97 | // write offsets to next 4 * nbufs bytes |
|
99 | // write offsets to next 4 * nbufs bytes | |
98 | for (i = 0; i < offsets.length; i++) { |
|
100 | for (i = 0; i < offsets.length; i++) { | |
99 | view.setUint32(4 * (i+1), offsets[i]); |
|
101 | view.setUint32(4 * (i+1), offsets[i]); | |
100 | } |
|
102 | } | |
101 | // write all the buffers at their respective offsets |
|
103 | // write all the buffers at their respective offsets | |
102 | for (i = 0; i < buffers.length; i++) { |
|
104 | for (i = 0; i < buffers.length; i++) { | |
103 |
msg_buf.set(new Uint8Array(buffers[i] |
|
105 | msg_buf.set(new Uint8Array(buffers[i]), offsets[i]); | |
104 | } |
|
106 | } | |
105 |
|
107 | |||
106 | // return raw ArrayBuffer |
|
108 | // return raw ArrayBuffer | |
107 | return msg_buf.buffer; |
|
109 | return msg_buf.buffer; | |
108 | }; |
|
110 | }; | |
109 |
|
111 | |||
110 | var serialize = function (msg) { |
|
112 | var serialize = function (msg) { | |
111 | if (msg.buffers && msg.buffers.length) { |
|
113 | if (msg.buffers && msg.buffers.length) { | |
112 | return _serialize_binary(msg); |
|
114 | return _serialize_binary(msg); | |
113 | } else { |
|
115 | } else { | |
114 | return JSON.stringify(msg); |
|
116 | return JSON.stringify(msg); | |
115 | } |
|
117 | } | |
116 | }; |
|
118 | }; | |
117 |
|
119 | |||
118 | var exports = { |
|
120 | var exports = { | |
119 | deserialize : deserialize, |
|
121 | deserialize : deserialize, | |
120 | serialize: serialize |
|
122 | serialize: serialize | |
121 | }; |
|
123 | }; | |
122 | return exports; |
|
124 | return exports; | |
123 | }); |
|
125 | }); |
General Comments 0
You need to be logged in to leave comments.
Login now