Upload packaging folder
[platform/upstream/iotjs.git] / tools / src / js / buffer.js
1 /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16
17 var bufferBuiltin = process.binding(process.binding.buffer);
18 var util = require('util');
19
20
21 function checkInt(buffer, value, offset, ext, max, min) {
22   if (!(buffer instanceof Buffer))
23     throw new TypeError('buffer must be a Buffer instance');
24   if (value > max || value < min)
25     throw new TypeError('value is out of bounds');
26   if (offset + ext > buffer.length)
27     throw new RangeError('index out of range');
28 }
29
30
31 function checkOffset(offset, ext, length) {
32   if (offset + ext > length)
33     throw new RangeError('index out of range');
34 }
35
36
37 // Buffer constructor
38 // [1] new Buffer(size)
39 // [2] new Buffer(buffer)
40 // [3] new Buffer(string)
41 // [4] new Buffer(string, encoding)
42 // [5] new Buffer(array)
43 function Buffer(subject, encoding) {
44   if (!util.isBuffer(this)) {
45     return new Buffer(subject);
46   }
47
48   if (util.isNumber(subject)) {
49     this.length = subject > 0 ? subject >>> 0 : 0;
50   } else if (util.isString(subject)) {
51     this.length = Buffer.byteLength(subject, encoding);
52   } else if (util.isBuffer(subject) || util.isArray(subject)) {
53     this.length = subject.length;
54   } else {
55     throw new TypeError('Bad arguments: Buffer(string|number|Buffer|Array)');
56   }
57
58   this._builtin = new bufferBuiltin(this, this.length);
59
60   if (util.isString(subject)) {
61     if (!util.isUndefined(encoding) && util.isString(encoding)) {
62       switch (encoding) {
63         case 'hex':
64           if (this._builtin.hexWrite(subject, 0, this.length) != this.length) {
65             throw new TypeError('Invalid hex string');
66           }
67           break;
68         default:
69           this.write(subject);
70       }
71     } else {
72       this.write(subject);
73     }
74   } else if (util.isBuffer(subject)) {
75     subject.copy(this);
76   } else if (util.isArray(subject)) {
77     for (var i = 0; i < this.length; ++i) {
78       this._builtin.writeUInt8(subject[i], i);
79     }
80   }
81 }
82
83
84 // Buffer.byteLength(string)
85 Buffer.byteLength = function(str, encoding) {
86   var len = bufferBuiltin.byteLength(str);
87
88   if (!util.isUndefined(encoding) && util.isString(encoding)) {
89     switch (encoding) {
90       case 'hex':
91         return len >>> 1;
92     }
93   }
94   return len;
95 };
96
97
98 // Buffer.concat(list)
99 Buffer.concat = function(list) {
100   if (!util.isArray(list)) {
101     throw new TypeError('Bad arguments: Buffer.concat([Buffer])');
102   }
103
104   var length = 0;
105   for (var i = 0; i < list.length; ++i) {
106     if (!util.isBuffer(list[i])) {
107       throw new TypeError('Bad arguments: Buffer.concat([Buffer])');
108     }
109     length += list[i].length;
110   }
111
112   var buffer = new Buffer(length);
113   var pos = 0;
114   for (var i = 0; i < list.length; ++i) {
115     list[i].copy(buffer, pos);
116     pos += list[i].length;
117   }
118
119   return buffer;
120 };
121
122
123 // Buffer.isBuffer(object)
124 Buffer.isBuffer = function(object) {
125   return util.isBuffer(object);
126 };
127
128
129 // buffer.equals(otherBuffer)
130 Buffer.prototype.equals = function(otherBuffer) {
131   if (!util.isBuffer(otherBuffer)) {
132     throw new TypeError('Bad arguments: buffer.equals(Buffer)');
133   }
134
135   return this._builtin.compare(otherBuffer) == 0;
136 };
137
138
139 // buffer.compare(otherBuffer)
140 Buffer.prototype.compare = function(otherBuffer) {
141   if (!util.isBuffer(otherBuffer)) {
142     throw new TypeError('Bad arguments: buffer.compare(Buffer)');
143   }
144
145   return this._builtin.compare(otherBuffer);
146 };
147
148
149 // buffer.copy(target[, targetStart[, sourceStart[, sourceEnd]]])
150 // [1] buffer.copy(target)
151 // [2] buffer.copy(target, targetStart)
152 // [3] buffer.copy(target, targetStart, sourceStart)
153 // [4] buffer.copy(target, targetStart, sourceStart, sourceEnd)
154 // * targetStart - default to 0
155 // * sourceStart - default to 0
156 // * sourceEnd - default to buffer.length
157 Buffer.prototype.copy = function(target, targetStart, sourceStart, sourceEnd) {
158   if (!util.isBuffer(target)) {
159     throw new TypeError('Bad arguments: buff.copy(Buffer)');
160   }
161
162   targetStart = util.isUndefined(targetStart) ? 0 : ~~targetStart;
163   sourceStart = util.isUndefined(sourceStart) ? 0 : ~~sourceStart;
164   sourceEnd = util.isUndefined(sourceEnd) ? this.length : ~~ sourceEnd;
165
166   if ((sourceEnd > sourceStart) && (targetStart < 0)) {
167     throw new RangeError('Attempt to write outside buffer bounds');
168   }
169
170   return this._builtin.copy(target, targetStart, sourceStart, sourceEnd);
171 };
172
173
174 // buffer.write(string[, offset[, length]])
175 // [1] buffer.write(string)
176 // [2] buffer.write(string, offset)
177 // [3] buffer.write(string, offset, length)
178 // * offset - default to 0
179 // * length - default to buffer.length - offset
180 Buffer.prototype.write = function(string, offset, length) {
181   if (!util.isString(string)) {
182     throw new TypeError('Bad arguments: buff.write(string)');
183   }
184
185   offset = util.isUndefined(offset) ? 0 : ~~offset;
186   if (string.length > 0 && (offset < 0 || offset >= this.length)) {
187     throw new RangeError('Attempt to write outside buffer bounds');
188   }
189
190   var remaining = this.length - offset;
191   length = util.isUndefined(length) ? remaining : ~~length;
192
193   return this._builtin.write(string, offset, length);
194 };
195
196
197 // buff.slice([start[, end]])
198 // [1] buff.slice()
199 // [2] buff.slice(start)
200 // [3] buff.slice(start, end)
201 // * start - default to 0
202 // * end - default to buff.length
203 Buffer.prototype.slice = function(start, end) {
204   start = util.isUndefined(start) ? 0 : ~~start;
205   end = util.isUndefined(end) ? this.length : ~~end;
206
207   return this._builtin.slice(start, end);
208 };
209
210
211 // buff.toString([encoding,[,start[, end]]])
212 // [1] buff.toString()
213 // [2] buff.toString(start)
214 // [3] buff.toString(start, end)
215 // [4] buff.toString('hex')
216 // * start - default to 0
217 // * end - default to buff.length
218 Buffer.prototype.toString = function(start, end) {
219   if (util.isString(start) && start === "hex" && util.isUndefined(end)) {
220       return this._builtin.toHexString();
221   }
222   start = util.isUndefined(start) ? 0 : ~~start;
223   end = util.isUndefined(end) ? this.length : ~~end;
224
225   return this._builtin.toString(start, end);
226 };
227
228
229 // buff.writeUInt8(value, offset[,noAssert])
230 // [1] buff.writeUInt8(value, offset)
231 // [2] buff.writeUInt8(value, offset, noAssert)
232 Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
233   value = +value;
234   offset = offset >>> 0;
235   if (!noAssert)
236     checkInt(this, value, offset, 1, 0xff, 0);
237   this._builtin.writeUInt8(value & 0xff, offset);
238   return offset + 1;
239 };
240
241
242 // buff.writeUInt16LE(value, offset[,noAssert])
243 // [1] buff.writeUInt16LE(value, offset)
244 // [2] buff.writeUInt16LE(value, offset, noAssert)
245 Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
246   value = +value;
247   offset = offset >>> 0;
248   if (!noAssert)
249     checkInt(this, value, offset, 2, 0xffff, 0);
250   this._builtin.writeUInt8(value & 0xff, offset);
251   this._builtin.writeUInt8((value >>> 8) & 0xff, offset + 1);
252   return offset + 2;
253 };
254
255
256 // buff.writeUInt32LE(value, offset[,noAssert])
257 // [1] buff.writeUInt32LE(value, offset)
258 // [2] buff.writeUInt32LE(value, offset, noAssert)
259 Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
260   value = +value;
261   offset = offset >>> 0;
262   if (!noAssert)
263     checkInt(this, value, offset, 4, 0xffffffff, 0);
264   this._builtin.writeUInt8((value >>> 24) & 0xff, offset + 3);
265   this._builtin.writeUInt8((value >>> 16) & 0xff, offset + 2);
266   this._builtin.writeUInt8((value >>> 8) & 0xff, offset + 1);
267   this._builtin.writeUInt8(value & 0xff, offset);
268   return offset + 4;
269 };
270
271
272 // buff.readUInt8(offset[,noAssert])
273 // [1] buff.readUInt8(offset)
274 // [2] buff.readUInt8(offset, noAssert)
275 Buffer.prototype.readUInt8 = function(offset, noAssert) {
276   offset = offset >>> 0;
277   if (!noAssert)
278     checkOffset(offset, 1, this.length);
279   return this._builtin.readUInt8(offset);
280 };
281
282
283 // buff.readInt8(offset[,noAssert])
284 // [1] buff.readInt8(offset)
285 // [2] buff.readInt8(offset, noAssert)
286 Buffer.prototype.readInt8 = function(offset, noAssert) {
287   offset = offset >>> 0;
288   if (!noAssert)
289     checkOffset(offset, 1, this.length);
290   var val = this._builtin.readUInt8(offset);
291   return !(val & 0x80) ? val : (0xff - val + 1) * -1;
292 };
293
294
295 // buff.readUInt16LE(offset[,noAssert])
296 // [1] buff.readUInt16LE(offset)
297 // [2] buff.readUInt16LE(offset, noAssert)
298 Buffer.prototype.readUInt16LE = function(offset, noAssert) {
299   offset = offset >>> 0;
300   if (!noAssert)
301     checkOffset(offset, 2, this.length);
302   return this._builtin.readUInt8(offset) |
303          (this._builtin.readUInt8(offset + 1) << 8);
304 };
305
306
307 // buff.fill(value)
308 Buffer.prototype.fill = function(value) {
309   if (util.isNumber(value)) {
310     value = value & 255;
311     for (var i = 0; i < this.length; i++) {
312       this._builtin.writeUInt8(value, i);
313     }
314   }
315   return this;
316 };
317
318
319 module.exports = Buffer;
320 module.exports.Buffer = Buffer;