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 | }; |