57 lines
1.5 KiB
JavaScript
57 lines
1.5 KiB
JavaScript
const { Transform } = require('stream');
|
|
|
|
/**
|
|
* Decodes a Base64 data stream, coming in as a string or Buffer of UTF-8 text, into binary Buffers.
|
|
* @extends Transform
|
|
*/
|
|
module.exports = class Base64Decode extends Transform {
|
|
/**
|
|
* Create a Base64Decode
|
|
*/
|
|
constructor() {
|
|
super({ decodeStrings: false });
|
|
// Any extra chars from the last chunk
|
|
this.extra = '';
|
|
}
|
|
|
|
/**
|
|
* Decodes a Base64 data stream, coming in as a string or Buffer of UTF-8 text, into binary Buffers.
|
|
* @param {Buffer|string} chunk
|
|
* @param encoding
|
|
* @param cb
|
|
* @private
|
|
*/
|
|
_transform(chunk, encoding, cb) {
|
|
// Convert chunk to a string
|
|
chunk = '' + chunk;
|
|
|
|
// Add previous extra and remove any newline characters
|
|
chunk = this.extra + chunk.replace(/(\r\n|\n|\r)/gm, '');
|
|
|
|
// 4 characters represent 3 bytes, so we can only decode in groups of 4 chars
|
|
const remaining = chunk.length % 4;
|
|
|
|
// Store the extra chars for later
|
|
this.extra = chunk.slice(chunk.length - remaining);
|
|
chunk = chunk.slice(0, chunk.length - remaining);
|
|
|
|
// Create the new buffer and push
|
|
const buf = Buffer.from(chunk, 'base64');
|
|
this.push(buf);
|
|
cb();
|
|
}
|
|
|
|
/**
|
|
* Emits 1, 2, or 3 extra characters of base64 data.
|
|
* @param cb
|
|
* @private
|
|
*/
|
|
_flush(cb) {
|
|
if (this.extra.length) {
|
|
this.push(Buffer.from(this.extra, 'base64'));
|
|
}
|
|
|
|
cb();
|
|
}
|
|
};
|