| 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(); | |
| } | |
| }; | |