ArrayBuffer.prototype.slice shim for IE?

Internet Explorer doesn't implement ArrayBuffer.prototype.slice. Amazingly, they don't plan on implementing it any time soon. As such, are there any shims out there for this function? If not then this shall be the canonical answer on the internet as soon as I or someone else implements one.

Answers


This seems to do the trick. Open to suggestions.

if (!ArrayBuffer.prototype.slice) {
    //Returns a new ArrayBuffer whose contents are a copy of this ArrayBuffer's
    //bytes from `begin`, inclusive, up to `end`, exclusive
    ArrayBuffer.prototype.slice = function (begin, end) {
        //If `begin` is unspecified, Chrome assumes 0, so we do the same
        if (begin === void 0) {
            begin = 0;
        }

        //If `end` is unspecified, the new ArrayBuffer contains all
        //bytes from `begin` to the end of this ArrayBuffer.
        if (end === void 0) {
            end = this.byteLength;
        }

        //Chrome converts the values to integers via flooring
        begin = Math.floor(begin);
        end = Math.floor(end);

        //If either `begin` or `end` is negative, it refers to an
        //index from the end of the array, as opposed to from the beginning.
        if (begin < 0) {
            begin += this.byteLength;
        }
        if (end < 0) {
            end += this.byteLength;
        }

        //The range specified by the `begin` and `end` values is clamped to the 
        //valid index range for the current array.
        begin = Math.min(Math.max(0, begin), this.byteLength);
        end = Math.min(Math.max(0, end), this.byteLength);

        //If the computed length of the new ArrayBuffer would be negative, it 
        //is clamped to zero.
        if (end - begin <= 0) {
            return new ArrayBuffer(0);
        }

        var result = new ArrayBuffer(end - begin);
        var resultBytes = new Uint8Array(result);
        var sourceBytes = new Uint8Array(this, begin, end - begin);

        resultBytes.set(sourceBytes);

        return result;
    };
}

Slightly adapted as per comments version of index.js from ttaubert's Arraybuffer-slice github repo

if (!ArrayBuffer.prototype.slice) {
  ArrayBuffer.prototype.slice = function (begin, end) {
    var len = this.byteLength;
    begin = (begin|0) || 0;
    end = end === (void 0) ? len : (end|0);

    // Handle negative values.
    if (begin < 0) begin = Math.max(begin + len, 0);
    if (end < 0) end = Math.max(end + len, 0);

    if (len === 0 || begin >= len || begin >= end) {
      return new ArrayBuffer(0);
    }

    var length = Math.min(len - begin, end - begin);
    var target = new ArrayBuffer(length);
    var targetArray = new Uint8Array(target);
    targetArray.set(new Uint8Array(this, begin, length));
    return target;
  };
}

Need Your Help

What should be a Perfect Business layer architecture?

c# asp.net design-patterns

While designing my Business layer I got confused that Business logic methods should be made either Static OR Instance OR do I need to implement any Design-Pattern to access the methods?

Haskell -- any easy way to put Data.Dynamic's in a Map?

haskell map dynamictype

I want to map Data.Dynamics to other Data.Dynamics. But, I can't write