Add support for cloning buffers. [closes #1940]

This commit is contained in:
John-David Dalton
2016-02-04 23:55:55 -08:00
parent fc85cac91d
commit 1595651780
2 changed files with 66 additions and 10 deletions

View File

@@ -230,8 +230,8 @@
/** Used to assign default `context` object properties. */
var contextProps = [
'Array', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function',
'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
'Array', 'Buffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_',
'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
@@ -1305,7 +1305,8 @@
);
/** Built-in value references. */
var Reflect = context.Reflect,
var Buffer = moduleExports ? context.Buffer : undefined,
Reflect = context.Reflect,
Symbol = context.Symbol,
Uint8Array = context.Uint8Array,
clearTimeout = context.clearTimeout,
@@ -2250,6 +2251,9 @@
var tag = getTag(value),
isFunc = tag == funcTag || tag == genTag;
if (isBuffer(value)) {
return cloneBuffer(value);
}
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
if (isHostObject(value)) {
return object ? value : {};
@@ -3707,18 +3711,33 @@
}
/**
* Creates a clone of `buffer`.
* Creates a clone of `buffer`.
*
* @private
* @param {ArrayBuffer} buffer The array buffer to clone.
* @returns {ArrayBuffer} Returns the cloned array buffer.
* @param {Buffer} buffer The buffer to clone.
* @returns {Buffer} Returns the cloned buffer.
*/
function cloneBuffer(buffer) {
var Ctor = buffer.constructor,
result = new Ctor(buffer.byteLength),
result = new Ctor(buffer.byteLength);
buffer.copy(result);
return result;
}
/**
* Creates a clone of `arrayBuffer`.
*
* @private
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
* @returns {ArrayBuffer} Returns the cloned array buffer.
*/
function cloneArrayBuffer(arrayBuffer) {
var Ctor = arrayBuffer.constructor,
result = new Ctor(arrayBuffer.byteLength),
view = new Uint8Array(result);
view.set(new Uint8Array(buffer));
view.set(new Uint8Array(arrayBuffer));
return result;
}
@@ -3784,7 +3803,7 @@
var buffer = typedArray.buffer,
Ctor = typedArray.constructor;
return new Ctor(isDeep ? cloneBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length);
return new Ctor(isDeep ? cloneArrayBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length);
}
/**
@@ -4978,7 +4997,7 @@
var Ctor = object.constructor;
switch (tag) {
case arrayBufferTag:
return cloneBuffer(object);
return cloneArrayBuffer(object);
case boolTag:
case dateTag:
@@ -9504,6 +9523,26 @@
(isObjectLike(value) && objectToString.call(value) == boolTag);
}
/**
* Checks if `value` is a buffer.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
* @example
*
* _.isBuffer(new Buffer(2));
* // => true
*
* _.isBuffer(new Uint8Array(2));
* // => false
*/
var isBuffer = !Buffer ? constant(false) : function(value) {
return value instanceof Buffer;
};
/**
* Checks if `value` is classified as a `Date` object.
*

View File

@@ -44,6 +44,7 @@
amd = root.define && define.amd,
argv = root.process && process.argv,
ArrayBuffer = root.ArrayBuffer,
Buffer = root.Buffer,
defineProperty = Object.defineProperty,
document = !phantom && root.document,
body = root.document && root.document.body,
@@ -2538,6 +2539,22 @@
assert.strictEqual(actual.lastIndex, 3);
});
QUnit.test('`_.' + methodName + '` should clone buffers', function(assert) {
assert.expect(3);
if (Buffer) {
var buffer = new Buffer([1, 2, 3]),
actual = func(buffer);
assert.strictEqual(actual.byteLength, buffer.byteLength);
assert.strictEqual(actual.inspect(), buffer.inspect());
assert.notStrictEqual(actual, buffer);
}
else {
skipTest(assert, 3);
}
});
QUnit.test('`_.' + methodName + '` should clone prototype objects', function(assert) {
assert.expect(2);