Implemented RegexBlockStream
parent
fa8d630283
commit
d11aac5599
@ -0,0 +1,65 @@
|
|||||||
|
const { Transform } = require('stream')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches whole blocks as regex and passes them on
|
||||||
|
*/
|
||||||
|
class RegexBlockStream extends Transform{
|
||||||
|
matcher;
|
||||||
|
withholdLastBlock;
|
||||||
|
matchAllOnFlush;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {RegExp} matcher Block-match - WARNING: It should match a clean-block (including e.g. newline)! Otherwise buffer will get dirty and use more and more ressources.
|
||||||
|
* @param {boolean} withholdLastBlock When true, the last matches block will not be submitted to prevent submitting incomplete blocks.
|
||||||
|
* @param {boolean} matchAllOnFlush (Only in combination with withholdLastBlock) When enabled, the buffer will be matched on last time on _flush (stream deconstruction) and write any, also incomplete, blocks
|
||||||
|
*/
|
||||||
|
constructor(matcher, withholdLastBlock = true, matchAllOnFlush = false){
|
||||||
|
super({
|
||||||
|
readableObjectMode: true,
|
||||||
|
writableObjectMode: true
|
||||||
|
});
|
||||||
|
|
||||||
|
this.matcher = matcher;
|
||||||
|
this.withholdLastBlock = withholdLastBlock;
|
||||||
|
this.matchAllOnFlush = matchAllOnFlush;
|
||||||
|
|
||||||
|
this._buffer = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
_transform(chunk, encoding, next){
|
||||||
|
chunk = this._buffer + chunk; // Add previous buffer to current chunk
|
||||||
|
|
||||||
|
let matches = chunk.match(this.matcher); // Match
|
||||||
|
if(matches){
|
||||||
|
if(this.withholdLastBlock) matches.pop(); // Remove last if we want to withhold it
|
||||||
|
chunk = this._writeMatches(chunk, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._buffer = chunk; // Store remaining data in buffer
|
||||||
|
next(); // Get next chunk
|
||||||
|
}
|
||||||
|
|
||||||
|
_writeMatches(matches, chunk = null){
|
||||||
|
if(matches){
|
||||||
|
matches.forEach((match) => {
|
||||||
|
this.push(match); // Write match to stream
|
||||||
|
if(chunk) chunk = chunk.replace(match, ''); // Remove match from chunks
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(chunk) return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
_flush(next){
|
||||||
|
if(matchAllOnFlush){ // When requested, we'll match one last time over the remaining buffer
|
||||||
|
let matches = this._buffer.match(this.matcher); // Match remaining buffer
|
||||||
|
_writeMatches(this._buffer); // Write matches including last element
|
||||||
|
}
|
||||||
|
|
||||||
|
next(); // Tell system we are done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specify exports
|
||||||
|
module.exports = {
|
||||||
|
RegexBlockStream
|
||||||
|
};
|
Loading…
Reference in New Issue