root / HServer / 00.Server / 00.Program / node_modules / socket.io-parser / binary.js
이력 | 보기 | 이력해설 | 다운로드 (3.96 KB)
1 | 39 | HKM | /*global Blob,File*/
|
---|---|---|---|
2 | |||
3 | /**
|
||
4 | * Module requirements
|
||
5 | */
|
||
6 | |||
7 | var isArray = require('isarray'); |
||
8 | var isBuf = require('./is-buffer'); |
||
9 | var toString = Object.prototype.toString;
|
||
10 | var withNativeBlob = typeof global.Blob === 'function' || toString.call(global.Blob) === '[object BlobConstructor]'; |
||
11 | var withNativeFile = typeof global.File === 'function' || toString.call(global.File) === '[object FileConstructor]'; |
||
12 | |||
13 | /**
|
||
14 | * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.
|
||
15 | * Anything with blobs or files should be fed through removeBlobs before coming
|
||
16 | * here.
|
||
17 | *
|
||
18 | * @param {Object} packet - socket.io event packet
|
||
19 | * @return {Object} with deconstructed packet and list of buffers
|
||
20 | * @api public
|
||
21 | */
|
||
22 | |||
23 | exports.deconstructPacket = function(packet) { |
||
24 | var buffers = [];
|
||
25 | var packetData = packet.data;
|
||
26 | var pack = packet;
|
||
27 | pack.data = _deconstructPacket(packetData, buffers); |
||
28 | pack.attachments = buffers.length; // number of binary 'attachments'
|
||
29 | return {packet: pack, buffers: buffers}; |
||
30 | }; |
||
31 | |||
32 | function _deconstructPacket(data, buffers) { |
||
33 | if (!data) return data; |
||
34 | |||
35 | if (isBuf(data)) {
|
||
36 | var placeholder = { _placeholder: true, num: buffers.length }; |
||
37 | buffers.push(data); |
||
38 | return placeholder;
|
||
39 | } else if (isArray(data)) { |
||
40 | var newData = new Array(data.length); |
||
41 | for (var i = 0; i < data.length; i++) { |
||
42 | newData[i] = _deconstructPacket(data[i], buffers); |
||
43 | } |
||
44 | return newData;
|
||
45 | } else if (typeof data === 'object' && !(data instanceof Date)) { |
||
46 | var newData = {};
|
||
47 | for (var key in data) { |
||
48 | newData[key] = _deconstructPacket(data[key], buffers); |
||
49 | } |
||
50 | return newData;
|
||
51 | } |
||
52 | return data;
|
||
53 | } |
||
54 | |||
55 | /**
|
||
56 | * Reconstructs a binary packet from its placeholder packet and buffers
|
||
57 | *
|
||
58 | * @param {Object} packet - event packet with placeholders
|
||
59 | * @param {Array} buffers - binary buffers to put in placeholder positions
|
||
60 | * @return {Object} reconstructed packet
|
||
61 | * @api public
|
||
62 | */
|
||
63 | |||
64 | exports.reconstructPacket = function(packet, buffers) { |
||
65 | packet.data = _reconstructPacket(packet.data, buffers); |
||
66 | packet.attachments = undefined; // no longer useful |
||
67 | return packet;
|
||
68 | }; |
||
69 | |||
70 | function _reconstructPacket(data, buffers) { |
||
71 | if (!data) return data; |
||
72 | |||
73 | if (data && data._placeholder) {
|
||
74 | return buffers[data.num]; // appropriate buffer (should be natural order anyway) |
||
75 | } else if (isArray(data)) { |
||
76 | for (var i = 0; i < data.length; i++) { |
||
77 | data[i] = _reconstructPacket(data[i], buffers); |
||
78 | } |
||
79 | } else if (typeof data === 'object') { |
||
80 | for (var key in data) { |
||
81 | data[key] = _reconstructPacket(data[key], buffers); |
||
82 | } |
||
83 | } |
||
84 | |||
85 | return data;
|
||
86 | } |
||
87 | |||
88 | /**
|
||
89 | * Asynchronously removes Blobs or Files from data via
|
||
90 | * FileReader's readAsArrayBuffer method. Used before encoding
|
||
91 | * data as msgpack. Calls callback with the blobless data.
|
||
92 | *
|
||
93 | * @param {Object} data
|
||
94 | * @param {Function} callback
|
||
95 | * @api private
|
||
96 | */
|
||
97 | |||
98 | exports.removeBlobs = function(data, callback) { |
||
99 | function _removeBlobs(obj, curKey, containingObject) { |
||
100 | if (!obj) return obj; |
||
101 | |||
102 | // convert any blob
|
||
103 | if ((withNativeBlob && obj instanceof Blob) || |
||
104 | (withNativeFile && obj instanceof File)) {
|
||
105 | pendingBlobs++; |
||
106 | |||
107 | // async filereader
|
||
108 | var fileReader = new FileReader(); |
||
109 | fileReader.onload = function() { // this.result == arraybuffer |
||
110 | if (containingObject) {
|
||
111 | containingObject[curKey] = this.result;
|
||
112 | } |
||
113 | else {
|
||
114 | bloblessData = this.result;
|
||
115 | } |
||
116 | |||
117 | // if nothing pending its callback time
|
||
118 | if(! --pendingBlobs) {
|
||
119 | callback(bloblessData); |
||
120 | } |
||
121 | }; |
||
122 | |||
123 | fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer
|
||
124 | } else if (isArray(obj)) { // handle array |
||
125 | for (var i = 0; i < obj.length; i++) { |
||
126 | _removeBlobs(obj[i], i, obj); |
||
127 | } |
||
128 | } else if (typeof obj === 'object' && !isBuf(obj)) { // and object |
||
129 | for (var key in obj) { |
||
130 | _removeBlobs(obj[key], key, obj); |
||
131 | } |
||
132 | } |
||
133 | } |
||
134 | |||
135 | var pendingBlobs = 0; |
||
136 | var bloblessData = data;
|
||
137 | _removeBlobs(bloblessData); |
||
138 | if (!pendingBlobs) {
|
||
139 | callback(bloblessData); |
||
140 | } |
||
141 | }; |