1 /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 var bufferBuiltin = process.binding(process.binding.buffer);
18 var util = require('util');
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');
31 function checkOffset(offset, ext, length) {
32 if (offset + ext > length)
33 throw new RangeError('index out of range');
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);
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;
55 throw new TypeError('Bad arguments: Buffer(string|number|Buffer|Array)');
58 this._builtin = new bufferBuiltin(this, this.length);
60 if (util.isString(subject)) {
61 if (!util.isUndefined(encoding) && util.isString(encoding)) {
64 if (this._builtin.hexWrite(subject, 0, this.length) != this.length) {
65 throw new TypeError('Invalid hex string');
74 } else if (util.isBuffer(subject)) {
76 } else if (util.isArray(subject)) {
77 for (var i = 0; i < this.length; ++i) {
78 this._builtin.writeUInt8(subject[i], i);
84 // Buffer.byteLength(string)
85 Buffer.byteLength = function(str, encoding) {
86 var len = bufferBuiltin.byteLength(str);
88 if (!util.isUndefined(encoding) && util.isString(encoding)) {
98 // Buffer.concat(list)
99 Buffer.concat = function(list) {
100 if (!util.isArray(list)) {
101 throw new TypeError('Bad arguments: Buffer.concat([Buffer])');
105 for (var i = 0; i < list.length; ++i) {
106 if (!util.isBuffer(list[i])) {
107 throw new TypeError('Bad arguments: Buffer.concat([Buffer])');
109 length += list[i].length;
112 var buffer = new Buffer(length);
114 for (var i = 0; i < list.length; ++i) {
115 list[i].copy(buffer, pos);
116 pos += list[i].length;
123 // Buffer.isBuffer(object)
124 Buffer.isBuffer = function(object) {
125 return util.isBuffer(object);
129 // buffer.equals(otherBuffer)
130 Buffer.prototype.equals = function(otherBuffer) {
131 if (!util.isBuffer(otherBuffer)) {
132 throw new TypeError('Bad arguments: buffer.equals(Buffer)');
135 return this._builtin.compare(otherBuffer) == 0;
139 // buffer.compare(otherBuffer)
140 Buffer.prototype.compare = function(otherBuffer) {
141 if (!util.isBuffer(otherBuffer)) {
142 throw new TypeError('Bad arguments: buffer.compare(Buffer)');
145 return this._builtin.compare(otherBuffer);
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)');
162 targetStart = util.isUndefined(targetStart) ? 0 : ~~targetStart;
163 sourceStart = util.isUndefined(sourceStart) ? 0 : ~~sourceStart;
164 sourceEnd = util.isUndefined(sourceEnd) ? this.length : ~~ sourceEnd;
166 if ((sourceEnd > sourceStart) && (targetStart < 0)) {
167 throw new RangeError('Attempt to write outside buffer bounds');
170 return this._builtin.copy(target, targetStart, sourceStart, sourceEnd);
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)');
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');
190 var remaining = this.length - offset;
191 length = util.isUndefined(length) ? remaining : ~~length;
193 return this._builtin.write(string, offset, length);
197 // buff.slice([start[, end]])
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;
207 return this._builtin.slice(start, end);
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();
222 start = util.isUndefined(start) ? 0 : ~~start;
223 end = util.isUndefined(end) ? this.length : ~~end;
225 return this._builtin.toString(start, end);
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) {
234 offset = offset >>> 0;
236 checkInt(this, value, offset, 1, 0xff, 0);
237 this._builtin.writeUInt8(value & 0xff, offset);
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) {
247 offset = offset >>> 0;
249 checkInt(this, value, offset, 2, 0xffff, 0);
250 this._builtin.writeUInt8(value & 0xff, offset);
251 this._builtin.writeUInt8((value >>> 8) & 0xff, offset + 1);
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) {
261 offset = offset >>> 0;
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);
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;
278 checkOffset(offset, 1, this.length);
279 return this._builtin.readUInt8(offset);
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;
289 checkOffset(offset, 1, this.length);
290 var val = this._builtin.readUInt8(offset);
291 return !(val & 0x80) ? val : (0xff - val + 1) * -1;
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;
301 checkOffset(offset, 2, this.length);
302 return this._builtin.readUInt8(offset) |
303 (this._builtin.readUInt8(offset + 1) << 8);
308 Buffer.prototype.fill = function(value) {
309 if (util.isNumber(value)) {
311 for (var i = 0; i < this.length; i++) {
312 this._builtin.writeUInt8(value, i);
319 module.exports = Buffer;
320 module.exports.Buffer = Buffer;