You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.9 KiB
92 lines
2.9 KiB
var through = require('through2'); |
|
var equals = require('buffer-equal') |
|
var buffers = { |
|
quote: Buffer('"'), |
|
escapeQuote: Buffer('\\"'), |
|
escapeEscape: Buffer('\\\\'), |
|
escapeB: Buffer('\\b'), |
|
escapeF: Buffer('\\f'), |
|
escapeN: Buffer('\\n'), |
|
escapeR: Buffer('\\r'), |
|
escapeT: Buffer('\\t'), |
|
escapeLineSeparator: Buffer('\\u2028'), |
|
escapeParagraphSeparator: Buffer('\\u2029') |
|
}; |
|
|
|
for (var i = 0; i < 32; i++) { |
|
var s = i.toString(16); |
|
buffers[i] = Buffer('\\u' + Array(5-s.length).join('0') + s); |
|
} |
|
|
|
var codes = { |
|
quote: '"'.charCodeAt(0), |
|
escape: '\\'.charCodeAt(0), |
|
b: '\b'.charCodeAt(0), |
|
f: '\f'.charCodeAt(0), |
|
n: '\n'.charCodeAt(0), |
|
r: '\r'.charCodeAt(0), |
|
t: '\t'.charCodeAt(0) |
|
}; |
|
|
|
var multiByteBuffers = { |
|
lineSeparator: Buffer('\u2028', 'utf8'), |
|
paragraphSeparator: Buffer('\u2029', 'utf8') |
|
}; |
|
var multiByteSeparatorLength = multiByteBuffers.lineSeparator.length; // same for both |
|
var multiByteSeparatorOffset = multiByteSeparatorLength - 1; |
|
var multiByteSeparatorCode = multiByteBuffers.lineSeparator[0]; // same for both |
|
|
|
var map = {}; |
|
map[codes.quote] = buffers.escapeQuote; |
|
map[codes.escape] = buffers.escapeEscape; |
|
map[codes.b] = buffers.escapeB; |
|
map[codes.f] = buffers.escapeF; |
|
map[codes.n] = buffers.escapeN; |
|
map[codes.r] = buffers.escapeR; |
|
map[codes.t] = buffers.escapeT; |
|
|
|
module.exports = function () { |
|
var stream = through(write, end); |
|
stream.push(buffers.quote); |
|
return stream; |
|
|
|
function write (buf, enc, next) { |
|
var offset = 0; |
|
for (var i = 0; i < buf.length; i++) { |
|
var c = buf[i]; |
|
var m = map[c]; |
|
if (m) { |
|
var bufs = [ buf.slice(offset, i), m ]; |
|
this.push(Buffer.concat(bufs)); |
|
offset = i + 1; |
|
} |
|
else if (c < 32) { |
|
var bufs = [ buf.slice(offset, i), buffers[c] ]; |
|
this.push(Buffer.concat(bufs)); |
|
offset = i + 1; |
|
} |
|
else if (c === multiByteSeparatorCode) { |
|
var rawBuf = buf.slice(i, i + multiByteSeparatorLength); |
|
var escapeBuf = null; |
|
if (equals(rawBuf, multiByteBuffers.lineSeparator)) { |
|
escapeBuf = buffers.escapeLineSeparator; |
|
} else if (equals(rawBuf, multiByteBuffers.paragraphSeparator)) { |
|
escapeBuf = buffers.escapeParagraphSeparator; |
|
} |
|
if (escapeBuf) { |
|
var bufs = [ buf.slice(offset, i), escapeBuf ]; |
|
this.push(Buffer.concat(bufs)); |
|
offset = i + multiByteSeparatorLength; |
|
i += multiByteSeparatorOffset |
|
} |
|
} |
|
} |
|
if (offset === 0) this.push(buf) |
|
else this.push(buf.slice(offset)); |
|
next(); |
|
} |
|
function end (next) { |
|
this.push(buffers.quote); |
|
this.push(null); |
|
} |
|
};
|
|
|