Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / ws / lib / Receiver.hixie.js
1 /*!
2  * ws: a node.js websocket client
3  * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
4  * MIT Licensed
5  */
6
7 var util = require('util');
8
9 /**
10  * State constants
11  */
12
13 var EMPTY = 0
14   , BODY = 1;
15 var BINARYLENGTH = 2
16   , BINARYBODY = 3;
17
18 /**
19  * Hixie Receiver implementation
20  */
21
22 function Receiver () {
23   this.state = EMPTY;
24   this.buffers = [];
25   this.messageEnd = -1;
26   this.spanLength = 0;
27   this.dead = false;
28
29   this.onerror = function() {};
30   this.ontext = function() {};
31   this.onbinary = function() {};
32   this.onclose = function() {};
33   this.onping = function() {};
34   this.onpong = function() {};
35 }
36
37 module.exports = Receiver;
38
39 /**
40  * Add new data to the parser.
41  *
42  * @api public
43  */
44
45 Receiver.prototype.add = function(data) {
46   var self = this;
47   function doAdd() {
48     if (self.state === EMPTY) {
49       if (data.length == 2 && data[0] == 0xFF && data[1] == 0x00) {
50         self.reset();
51         self.onclose();
52         return;
53       }
54       if (data[0] === 0x80) {
55         self.messageEnd = 0;
56         self.state = BINARYLENGTH;
57         data = data.slice(1);
58       } else {
59
60       if (data[0] !== 0x00) {
61         self.error('payload must start with 0x00 byte', true);
62         return;
63       }
64       data = data.slice(1);
65       self.state = BODY;
66
67       }
68     }
69     if (self.state === BINARYLENGTH) {
70       var i = 0;
71       while ((i < data.length) && (data[i] & 0x80)) {
72         self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f);
73         ++i;
74       }
75       if (i < data.length) {
76         self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f);
77         self.state = BINARYBODY;
78         ++i;
79       }
80       if (i > 0)
81         data = data.slice(i);
82     }
83     if (self.state === BINARYBODY) {
84       var dataleft = self.messageEnd - self.spanLength;
85       if (data.length >= dataleft) {
86         // consume the whole buffer to finish the frame
87         self.buffers.push(data);
88         self.spanLength += dataleft;
89         self.messageEnd = dataleft;
90         return self.parse();
91       }
92       // frame's not done even if we consume it all
93       self.buffers.push(data);
94       self.spanLength += data.length;
95       return;
96     }
97     self.buffers.push(data);
98     if ((self.messageEnd = bufferIndex(data, 0xFF)) != -1) {
99       self.spanLength += self.messageEnd;
100       return self.parse();
101     }
102     else self.spanLength += data.length;
103   }
104   while(data) data = doAdd();
105 };
106
107 /**
108  * Releases all resources used by the receiver.
109  *
110  * @api public
111  */
112
113 Receiver.prototype.cleanup = function() {
114   this.dead = true;
115   this.state = EMPTY;
116   this.buffers = [];
117 };
118
119 /**
120  * Process buffered data.
121  *
122  * @api public
123  */
124
125 Receiver.prototype.parse = function() {
126   var output = new Buffer(this.spanLength);
127   var outputIndex = 0;
128   for (var bi = 0, bl = this.buffers.length; bi < bl - 1; ++bi) {
129     var buffer = this.buffers[bi];
130     buffer.copy(output, outputIndex);
131     outputIndex += buffer.length;
132   }
133   var lastBuffer = this.buffers[this.buffers.length - 1];
134   if (this.messageEnd > 0) lastBuffer.copy(output, outputIndex, 0, this.messageEnd);
135   if (this.state !== BODY) --this.messageEnd;
136   var tail = null;
137   if (this.messageEnd < lastBuffer.length - 1) {
138     tail = lastBuffer.slice(this.messageEnd + 1);
139   }
140   this.reset();
141   this.ontext(output.toString('utf8'));
142   return tail;
143 };
144
145 /**
146  * Handles an error
147  *
148  * @api private
149  */
150
151 Receiver.prototype.error = function (reason, terminate) {
152   this.reset();
153   this.onerror(reason, terminate);
154   return this;
155 };
156
157 /**
158  * Reset parser state
159  *
160  * @api private
161  */
162
163 Receiver.prototype.reset = function (reason) {
164   if (this.dead) return;
165   this.state = EMPTY;
166   this.buffers = [];
167   this.messageEnd = -1;
168   this.spanLength = 0;
169 };
170
171 /**
172  * Internal api
173  */
174
175 function bufferIndex(buffer, byte) {
176   for (var i = 0, l = buffer.length; i < l; ++i) {
177     if (buffer[i] === byte) return i;
178   }
179   return -1;
180 }