프로젝트

일반

사용자정보

통계
| 개정판:

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