UNPKG

4.95 kBJavaScriptView Raw
1"use strict";
2// Copyright (C) 2011-2015 John Hewson
3//
4// Permission is hereby granted, free of charge, to any person obtaining a copy
5// of this software and associated documentation files (the "Software"), to
6// deal in the Software without restriction, including without limitation the
7// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8// sell copies of the Software, and to permit persons to whom the Software is
9// furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20// IN THE SOFTWARE.
21Object.defineProperty(exports, "__esModule", { value: true });
22var stream = require('stream'), util = require('util');
23// convinience API
24function byline(readStream, options) {
25 return module.exports.createStream(readStream, options);
26}
27exports.default = byline;
28// basic API
29module.exports.createStream = function (readStream, options) {
30 if (readStream) {
31 return createLineStream(readStream, options);
32 }
33 else {
34 return new LineStream(options);
35 }
36};
37function createLineStream(readStream, options) {
38 if (!readStream) {
39 throw new Error('expected readStream');
40 }
41 if (!readStream.readable) {
42 throw new Error('readStream must be readable');
43 }
44 var ls = new LineStream(options);
45 readStream.pipe(ls);
46 return ls;
47}
48exports.createLineStream = createLineStream;
49//
50// using the new node v0.10 "streams2" API
51//
52module.exports.LineStream = LineStream;
53function LineStream(options) {
54 stream.Transform.call(this, options);
55 options = options || {};
56 // use objectMode to stop the output from being buffered
57 // which re-concatanates the lines, just without newlines.
58 this._readableState.objectMode = true;
59 this._lineBuffer = [];
60 this._keepEmptyLines = options.keepEmptyLines || false;
61 this._lastChunkEndedWithCR = false;
62 // take the source's encoding if we don't have one
63 this.on('pipe', function (src) {
64 if (!this.encoding) {
65 // but we can't do this for old-style streams
66 if (src instanceof stream.Readable) {
67 this.encoding = src._readableState.encoding;
68 }
69 }
70 });
71}
72util.inherits(LineStream, stream.Transform);
73LineStream.prototype._transform = function (chunk, encoding, done) {
74 // decode binary chunks as UTF-8
75 encoding = encoding || 'utf8';
76 if (Buffer.isBuffer(chunk)) {
77 if (encoding == 'buffer') {
78 chunk = chunk.toString(); // utf8
79 encoding = 'utf8';
80 }
81 else {
82 chunk = chunk.toString(encoding);
83 }
84 }
85 this._chunkEncoding = encoding;
86 var lines = chunk.split(/\r\n|\r|\n/g);
87 // don't split CRLF which spans chunks
88 if (this._lastChunkEndedWithCR && chunk[0] == '\n') {
89 lines.shift();
90 }
91 if (this._lineBuffer.length > 0) {
92 this._lineBuffer[this._lineBuffer.length - 1] += lines[0];
93 lines.shift();
94 }
95 this._lastChunkEndedWithCR = chunk[chunk.length - 1] == '\r';
96 this._lineBuffer = this._lineBuffer.concat(lines);
97 this._pushBuffer(encoding, 1, done);
98};
99LineStream.prototype._pushBuffer = function (encoding, keep, done) {
100 // always buffer the last (possibly partial) line
101 while (this._lineBuffer.length > keep) {
102 var line = this._lineBuffer.shift();
103 // skip empty lines
104 if (this._keepEmptyLines || line.length > 0) {
105 if (!this.push(this._reencode(line, encoding))) {
106 // when the high-water mark is reached, defer pushes until the next tick
107 var self = this;
108 setImmediate(function () {
109 self._pushBuffer(encoding, keep, done);
110 });
111 return;
112 }
113 }
114 }
115 done();
116};
117LineStream.prototype._flush = function (done) {
118 this._pushBuffer(this._chunkEncoding, 0, done);
119};
120// see Readable::push
121LineStream.prototype._reencode = function (line, chunkEncoding) {
122 if (this.encoding && this.encoding != chunkEncoding) {
123 return Buffer.from(line, chunkEncoding).toString(this.encoding);
124 }
125 else if (this.encoding) {
126 // this should be the most common case, i.e. we're using an encoded source stream
127 return line;
128 }
129 else {
130 return Buffer.from(line, chunkEncoding);
131 }
132};
133//# sourceMappingURL=byline.js.map
\No newline at end of file