git-off

git off handles large files in git repos
git clone https://noulin.net/git/git-off.git
Log | Files | Refs | README

extend-node.js (8513B)


      1 "use strict"
      2 
      3 // == Extend Node primitives to use iconv-lite =================================
      4 
      5 module.exports = function (iconv) {
      6     var original = undefined; // Place to keep original methods.
      7 
      8     // Node authors rewrote Buffer internals to make it compatible with
      9     // Uint8Array and we cannot patch key functions since then.
     10     iconv.supportsNodeEncodingsExtension = !(new Buffer(0) instanceof Uint8Array);
     11 
     12     iconv.extendNodeEncodings = function extendNodeEncodings() {
     13         if (original) return;
     14         original = {};
     15 
     16         if (!iconv.supportsNodeEncodingsExtension) {
     17             console.error("ACTION NEEDED: require('iconv-lite').extendNodeEncodings() is not supported in your version of Node");
     18             console.error("See more info at https://github.com/ashtuchkin/iconv-lite/wiki/Node-v4-compatibility");
     19             return;
     20         }
     21 
     22         var nodeNativeEncodings = {
     23             'hex': true, 'utf8': true, 'utf-8': true, 'ascii': true, 'binary': true, 
     24             'base64': true, 'ucs2': true, 'ucs-2': true, 'utf16le': true, 'utf-16le': true,
     25         };
     26 
     27         Buffer.isNativeEncoding = function(enc) {
     28             return enc && nodeNativeEncodings[enc.toLowerCase()];
     29         }
     30 
     31         // -- SlowBuffer -----------------------------------------------------------
     32         var SlowBuffer = require('buffer').SlowBuffer;
     33 
     34         original.SlowBufferToString = SlowBuffer.prototype.toString;
     35         SlowBuffer.prototype.toString = function(encoding, start, end) {
     36             encoding = String(encoding || 'utf8').toLowerCase();
     37 
     38             // Use native conversion when possible
     39             if (Buffer.isNativeEncoding(encoding))
     40                 return original.SlowBufferToString.call(this, encoding, start, end);
     41 
     42             // Otherwise, use our decoding method.
     43             if (typeof start == 'undefined') start = 0;
     44             if (typeof end == 'undefined') end = this.length;
     45             return iconv.decode(this.slice(start, end), encoding);
     46         }
     47 
     48         original.SlowBufferWrite = SlowBuffer.prototype.write;
     49         SlowBuffer.prototype.write = function(string, offset, length, encoding) {
     50             // Support both (string, offset, length, encoding)
     51             // and the legacy (string, encoding, offset, length)
     52             if (isFinite(offset)) {
     53                 if (!isFinite(length)) {
     54                     encoding = length;
     55                     length = undefined;
     56                 }
     57             } else {  // legacy
     58                 var swap = encoding;
     59                 encoding = offset;
     60                 offset = length;
     61                 length = swap;
     62             }
     63 
     64             offset = +offset || 0;
     65             var remaining = this.length - offset;
     66             if (!length) {
     67                 length = remaining;
     68             } else {
     69                 length = +length;
     70                 if (length > remaining) {
     71                     length = remaining;
     72                 }
     73             }
     74             encoding = String(encoding || 'utf8').toLowerCase();
     75 
     76             // Use native conversion when possible
     77             if (Buffer.isNativeEncoding(encoding))
     78                 return original.SlowBufferWrite.call(this, string, offset, length, encoding);
     79 
     80             if (string.length > 0 && (length < 0 || offset < 0))
     81                 throw new RangeError('attempt to write beyond buffer bounds');
     82 
     83             // Otherwise, use our encoding method.
     84             var buf = iconv.encode(string, encoding);
     85             if (buf.length < length) length = buf.length;
     86             buf.copy(this, offset, 0, length);
     87             return length;
     88         }
     89 
     90         // -- Buffer ---------------------------------------------------------------
     91 
     92         original.BufferIsEncoding = Buffer.isEncoding;
     93         Buffer.isEncoding = function(encoding) {
     94             return Buffer.isNativeEncoding(encoding) || iconv.encodingExists(encoding);
     95         }
     96 
     97         original.BufferByteLength = Buffer.byteLength;
     98         Buffer.byteLength = SlowBuffer.byteLength = function(str, encoding) {
     99             encoding = String(encoding || 'utf8').toLowerCase();
    100 
    101             // Use native conversion when possible
    102             if (Buffer.isNativeEncoding(encoding))
    103                 return original.BufferByteLength.call(this, str, encoding);
    104 
    105             // Slow, I know, but we don't have a better way yet.
    106             return iconv.encode(str, encoding).length;
    107         }
    108 
    109         original.BufferToString = Buffer.prototype.toString;
    110         Buffer.prototype.toString = function(encoding, start, end) {
    111             encoding = String(encoding || 'utf8').toLowerCase();
    112 
    113             // Use native conversion when possible
    114             if (Buffer.isNativeEncoding(encoding))
    115                 return original.BufferToString.call(this, encoding, start, end);
    116 
    117             // Otherwise, use our decoding method.
    118             if (typeof start == 'undefined') start = 0;
    119             if (typeof end == 'undefined') end = this.length;
    120             return iconv.decode(this.slice(start, end), encoding);
    121         }
    122 
    123         original.BufferWrite = Buffer.prototype.write;
    124         Buffer.prototype.write = function(string, offset, length, encoding) {
    125             var _offset = offset, _length = length, _encoding = encoding;
    126             // Support both (string, offset, length, encoding)
    127             // and the legacy (string, encoding, offset, length)
    128             if (isFinite(offset)) {
    129                 if (!isFinite(length)) {
    130                     encoding = length;
    131                     length = undefined;
    132                 }
    133             } else {  // legacy
    134                 var swap = encoding;
    135                 encoding = offset;
    136                 offset = length;
    137                 length = swap;
    138             }
    139 
    140             encoding = String(encoding || 'utf8').toLowerCase();
    141 
    142             // Use native conversion when possible
    143             if (Buffer.isNativeEncoding(encoding))
    144                 return original.BufferWrite.call(this, string, _offset, _length, _encoding);
    145 
    146             offset = +offset || 0;
    147             var remaining = this.length - offset;
    148             if (!length) {
    149                 length = remaining;
    150             } else {
    151                 length = +length;
    152                 if (length > remaining) {
    153                     length = remaining;
    154                 }
    155             }
    156 
    157             if (string.length > 0 && (length < 0 || offset < 0))
    158                 throw new RangeError('attempt to write beyond buffer bounds');
    159 
    160             // Otherwise, use our encoding method.
    161             var buf = iconv.encode(string, encoding);
    162             if (buf.length < length) length = buf.length;
    163             buf.copy(this, offset, 0, length);
    164             return length;
    165 
    166             // TODO: Set _charsWritten.
    167         }
    168 
    169 
    170         // -- Readable -------------------------------------------------------------
    171         if (iconv.supportsStreams) {
    172             var Readable = require('stream').Readable;
    173 
    174             original.ReadableSetEncoding = Readable.prototype.setEncoding;
    175             Readable.prototype.setEncoding = function setEncoding(enc, options) {
    176                 // Use our own decoder, it has the same interface.
    177                 // We cannot use original function as it doesn't handle BOM-s.
    178                 this._readableState.decoder = iconv.getDecoder(enc, options);
    179                 this._readableState.encoding = enc;
    180             }
    181 
    182             Readable.prototype.collect = iconv._collect;
    183         }
    184     }
    185 
    186     // Remove iconv-lite Node primitive extensions.
    187     iconv.undoExtendNodeEncodings = function undoExtendNodeEncodings() {
    188         if (!iconv.supportsNodeEncodingsExtension)
    189             return;
    190         if (!original)
    191             throw new Error("require('iconv-lite').undoExtendNodeEncodings(): Nothing to undo; extendNodeEncodings() is not called.")
    192 
    193         delete Buffer.isNativeEncoding;
    194 
    195         var SlowBuffer = require('buffer').SlowBuffer;
    196 
    197         SlowBuffer.prototype.toString = original.SlowBufferToString;
    198         SlowBuffer.prototype.write = original.SlowBufferWrite;
    199 
    200         Buffer.isEncoding = original.BufferIsEncoding;
    201         Buffer.byteLength = original.BufferByteLength;
    202         Buffer.prototype.toString = original.BufferToString;
    203         Buffer.prototype.write = original.BufferWrite;
    204 
    205         if (iconv.supportsStreams) {
    206             var Readable = require('stream').Readable;
    207 
    208             Readable.prototype.setEncoding = original.ReadableSetEncoding;
    209             delete Readable.prototype.collect;
    210         }
    211 
    212         original = undefined;
    213     }
    214 }