source: node_modules/nodemailer/lib/base64/index.js@ 2d1ec46

main
Last change on this file since 2d1ec46 was 81bc7da, checked in by Klimentina Efremova <klimentina08642@…>, 3 months ago

Initial commit

  • Property mode set to 100644
File size: 3.7 KB
Line 
1'use strict';
2
3const Transform = require('stream').Transform;
4
5/**
6 * Encodes a Buffer into a base64 encoded string
7 *
8 * @param {Buffer} buffer Buffer to convert
9 * @returns {String} base64 encoded string
10 */
11function encode(buffer) {
12 if (typeof buffer === 'string') {
13 buffer = Buffer.from(buffer, 'utf-8');
14 }
15
16 return buffer.toString('base64');
17}
18
19/**
20 * Adds soft line breaks to a base64 string
21 *
22 * @param {String} str base64 encoded string that might need line wrapping
23 * @param {Number} [lineLength=76] Maximum allowed length for a line
24 * @returns {String} Soft-wrapped base64 encoded string
25 */
26function wrap(str, lineLength) {
27 str = (str || '').toString();
28 lineLength = lineLength || 76;
29
30 if (str.length <= lineLength) {
31 return str;
32 }
33
34 let result = [];
35 let pos = 0;
36 let chunkLength = lineLength * 1024;
37 while (pos < str.length) {
38 let wrappedLines = str
39 .substr(pos, chunkLength)
40 .replace(new RegExp('.{' + lineLength + '}', 'g'), '$&\r\n')
41 .trim();
42 result.push(wrappedLines);
43 pos += chunkLength;
44 }
45
46 return result.join('\r\n').trim();
47}
48
49/**
50 * Creates a transform stream for encoding data to base64 encoding
51 *
52 * @constructor
53 * @param {Object} options Stream options
54 * @param {Number} [options.lineLength=76] Maximum length for lines, set to false to disable wrapping
55 */
56class Encoder extends Transform {
57 constructor(options) {
58 super();
59 // init Transform
60 this.options = options || {};
61
62 if (this.options.lineLength !== false) {
63 this.options.lineLength = this.options.lineLength || 76;
64 }
65
66 this._curLine = '';
67 this._remainingBytes = false;
68
69 this.inputBytes = 0;
70 this.outputBytes = 0;
71 }
72
73 _transform(chunk, encoding, done) {
74 if (encoding !== 'buffer') {
75 chunk = Buffer.from(chunk, encoding);
76 }
77
78 if (!chunk || !chunk.length) {
79 return setImmediate(done);
80 }
81
82 this.inputBytes += chunk.length;
83
84 if (this._remainingBytes && this._remainingBytes.length) {
85 chunk = Buffer.concat([this._remainingBytes, chunk], this._remainingBytes.length + chunk.length);
86 this._remainingBytes = false;
87 }
88
89 if (chunk.length % 3) {
90 this._remainingBytes = chunk.slice(chunk.length - (chunk.length % 3));
91 chunk = chunk.slice(0, chunk.length - (chunk.length % 3));
92 } else {
93 this._remainingBytes = false;
94 }
95
96 let b64 = this._curLine + encode(chunk);
97
98 if (this.options.lineLength) {
99 b64 = wrap(b64, this.options.lineLength);
100
101 // remove last line as it is still most probably incomplete
102 let lastLF = b64.lastIndexOf('\n');
103 if (lastLF < 0) {
104 this._curLine = b64;
105 b64 = '';
106 } else if (lastLF === b64.length - 1) {
107 this._curLine = '';
108 } else {
109 this._curLine = b64.substr(lastLF + 1);
110 b64 = b64.substr(0, lastLF + 1);
111 }
112 }
113
114 if (b64) {
115 this.outputBytes += b64.length;
116 this.push(Buffer.from(b64, 'ascii'));
117 }
118
119 setImmediate(done);
120 }
121
122 _flush(done) {
123 if (this._remainingBytes && this._remainingBytes.length) {
124 this._curLine += encode(this._remainingBytes);
125 }
126
127 if (this._curLine) {
128 this._curLine = wrap(this._curLine, this.options.lineLength);
129 this.outputBytes += this._curLine.length;
130 this.push(this._curLine, 'ascii');
131 this._curLine = '';
132 }
133 done();
134 }
135}
136
137// expose to the world
138module.exports = {
139 encode,
140 wrap,
141 Encoder
142};
Note: See TracBrowser for help on using the repository browser.