second
[josuexyz/.git] / node_modules / iconv-lite / lib / streams.js
1 "use strict";
2
3 var Buffer = require("buffer").Buffer,
4     Transform = require("stream").Transform;
5
6
7 // == Exports ==================================================================
8 module.exports = function(iconv) {
9     
10     // Additional Public API.
11     iconv.encodeStream = function encodeStream(encoding, options) {
12         return new IconvLiteEncoderStream(iconv.getEncoder(encoding, options), options);
13     }
14
15     iconv.decodeStream = function decodeStream(encoding, options) {
16         return new IconvLiteDecoderStream(iconv.getDecoder(encoding, options), options);
17     }
18
19     iconv.supportsStreams = true;
20
21
22     // Not published yet.
23     iconv.IconvLiteEncoderStream = IconvLiteEncoderStream;
24     iconv.IconvLiteDecoderStream = IconvLiteDecoderStream;
25     iconv._collect = IconvLiteDecoderStream.prototype.collect;
26 };
27
28
29 // == Encoder stream =======================================================
30 function IconvLiteEncoderStream(conv, options) {
31     this.conv = conv;
32     options = options || {};
33     options.decodeStrings = false; // We accept only strings, so we don't need to decode them.
34     Transform.call(this, options);
35 }
36
37 IconvLiteEncoderStream.prototype = Object.create(Transform.prototype, {
38     constructor: { value: IconvLiteEncoderStream }
39 });
40
41 IconvLiteEncoderStream.prototype._transform = function(chunk, encoding, done) {
42     if (typeof chunk != 'string')
43         return done(new Error("Iconv encoding stream needs strings as its input."));
44     try {
45         var res = this.conv.write(chunk);
46         if (res && res.length) this.push(res);
47         done();
48     }
49     catch (e) {
50         done(e);
51     }
52 }
53
54 IconvLiteEncoderStream.prototype._flush = function(done) {
55     try {
56         var res = this.conv.end();
57         if (res && res.length) this.push(res);
58         done();
59     }
60     catch (e) {
61         done(e);
62     }
63 }
64
65 IconvLiteEncoderStream.prototype.collect = function(cb) {
66     var chunks = [];
67     this.on('error', cb);
68     this.on('data', function(chunk) { chunks.push(chunk); });
69     this.on('end', function() {
70         cb(null, Buffer.concat(chunks));
71     });
72     return this;
73 }
74
75
76 // == Decoder stream =======================================================
77 function IconvLiteDecoderStream(conv, options) {
78     this.conv = conv;
79     options = options || {};
80     options.encoding = this.encoding = 'utf8'; // We output strings.
81     Transform.call(this, options);
82 }
83
84 IconvLiteDecoderStream.prototype = Object.create(Transform.prototype, {
85     constructor: { value: IconvLiteDecoderStream }
86 });
87
88 IconvLiteDecoderStream.prototype._transform = function(chunk, encoding, done) {
89     if (!Buffer.isBuffer(chunk))
90         return done(new Error("Iconv decoding stream needs buffers as its input."));
91     try {
92         var res = this.conv.write(chunk);
93         if (res && res.length) this.push(res, this.encoding);
94         done();
95     }
96     catch (e) {
97         done(e);
98     }
99 }
100
101 IconvLiteDecoderStream.prototype._flush = function(done) {
102     try {
103         var res = this.conv.end();
104         if (res && res.length) this.push(res, this.encoding);                
105         done();
106     }
107     catch (e) {
108         done(e);
109     }
110 }
111
112 IconvLiteDecoderStream.prototype.collect = function(cb) {
113     var res = '';
114     this.on('error', cb);
115     this.on('data', function(chunk) { res += chunk; });
116     this.on('end', function() {
117         cb(null, res);
118     });
119     return this;
120 }
121