Initial commit
[yaffs-website] / node_modules / iconv-lite / lib / extend-node.js
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 }