1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23const common = require('../common'); 24const assert = require('assert'); 25const R = require('_stream_readable'); 26 27class TestReader extends R { 28 constructor(n, opts) { 29 super(opts); 30 this.pos = 0; 31 this.len = n || 100; 32 } 33 34 _read(n) { 35 setTimeout(() => { 36 if (this.pos >= this.len) { 37 // Double push(null) to test eos handling 38 this.push(null); 39 return this.push(null); 40 } 41 42 n = Math.min(n, this.len - this.pos); 43 if (n <= 0) { 44 // Double push(null) to test eos handling 45 this.push(null); 46 return this.push(null); 47 } 48 49 this.pos += n; 50 const ret = Buffer.alloc(n, 'a'); 51 52 return this.push(ret); 53 }, 1); 54 } 55} 56 57{ 58 // Verify utf8 encoding 59 const tr = new TestReader(100); 60 tr.setEncoding('utf8'); 61 const out = []; 62 const expect = 63 [ 'aaaaaaaaaa', 64 'aaaaaaaaaa', 65 'aaaaaaaaaa', 66 'aaaaaaaaaa', 67 'aaaaaaaaaa', 68 'aaaaaaaaaa', 69 'aaaaaaaaaa', 70 'aaaaaaaaaa', 71 'aaaaaaaaaa', 72 'aaaaaaaaaa' ]; 73 74 tr.on('readable', function flow() { 75 let chunk; 76 while (null !== (chunk = tr.read(10))) 77 out.push(chunk); 78 }); 79 80 tr.on('end', common.mustCall(function() { 81 assert.deepStrictEqual(out, expect); 82 })); 83} 84 85 86{ 87 // Verify hex encoding 88 const tr = new TestReader(100); 89 tr.setEncoding('hex'); 90 const out = []; 91 const expect = 92 [ '6161616161', 93 '6161616161', 94 '6161616161', 95 '6161616161', 96 '6161616161', 97 '6161616161', 98 '6161616161', 99 '6161616161', 100 '6161616161', 101 '6161616161', 102 '6161616161', 103 '6161616161', 104 '6161616161', 105 '6161616161', 106 '6161616161', 107 '6161616161', 108 '6161616161', 109 '6161616161', 110 '6161616161', 111 '6161616161' ]; 112 113 tr.on('readable', function flow() { 114 let chunk; 115 while (null !== (chunk = tr.read(10))) 116 out.push(chunk); 117 }); 118 119 tr.on('end', common.mustCall(function() { 120 assert.deepStrictEqual(out, expect); 121 })); 122} 123 124{ 125 // Verify hex encoding with read(13) 126 const tr = new TestReader(100); 127 tr.setEncoding('hex'); 128 const out = []; 129 const expect = 130 [ '6161616161616', 131 '1616161616161', 132 '6161616161616', 133 '1616161616161', 134 '6161616161616', 135 '1616161616161', 136 '6161616161616', 137 '1616161616161', 138 '6161616161616', 139 '1616161616161', 140 '6161616161616', 141 '1616161616161', 142 '6161616161616', 143 '1616161616161', 144 '6161616161616', 145 '16161' ]; 146 147 tr.on('readable', function flow() { 148 let chunk; 149 while (null !== (chunk = tr.read(13))) 150 out.push(chunk); 151 }); 152 153 tr.on('end', common.mustCall(function() { 154 assert.deepStrictEqual(out, expect); 155 })); 156} 157 158{ 159 // Verify base64 encoding 160 const tr = new TestReader(100); 161 tr.setEncoding('base64'); 162 const out = []; 163 const expect = 164 [ 'YWFhYWFhYW', 165 'FhYWFhYWFh', 166 'YWFhYWFhYW', 167 'FhYWFhYWFh', 168 'YWFhYWFhYW', 169 'FhYWFhYWFh', 170 'YWFhYWFhYW', 171 'FhYWFhYWFh', 172 'YWFhYWFhYW', 173 'FhYWFhYWFh', 174 'YWFhYWFhYW', 175 'FhYWFhYWFh', 176 'YWFhYWFhYW', 177 'FhYQ==' ]; 178 179 tr.on('readable', function flow() { 180 let chunk; 181 while (null !== (chunk = tr.read(10))) 182 out.push(chunk); 183 }); 184 185 tr.on('end', common.mustCall(function() { 186 assert.deepStrictEqual(out, expect); 187 })); 188} 189 190{ 191 // Verify utf8 encoding 192 const tr = new TestReader(100, { encoding: 'utf8' }); 193 const out = []; 194 const expect = 195 [ 'aaaaaaaaaa', 196 'aaaaaaaaaa', 197 'aaaaaaaaaa', 198 'aaaaaaaaaa', 199 'aaaaaaaaaa', 200 'aaaaaaaaaa', 201 'aaaaaaaaaa', 202 'aaaaaaaaaa', 203 'aaaaaaaaaa', 204 'aaaaaaaaaa' ]; 205 206 tr.on('readable', function flow() { 207 let chunk; 208 while (null !== (chunk = tr.read(10))) 209 out.push(chunk); 210 }); 211 212 tr.on('end', common.mustCall(function() { 213 assert.deepStrictEqual(out, expect); 214 })); 215} 216 217 218{ 219 // Verify hex encoding 220 const tr = new TestReader(100, { encoding: 'hex' }); 221 const out = []; 222 const expect = 223 [ '6161616161', 224 '6161616161', 225 '6161616161', 226 '6161616161', 227 '6161616161', 228 '6161616161', 229 '6161616161', 230 '6161616161', 231 '6161616161', 232 '6161616161', 233 '6161616161', 234 '6161616161', 235 '6161616161', 236 '6161616161', 237 '6161616161', 238 '6161616161', 239 '6161616161', 240 '6161616161', 241 '6161616161', 242 '6161616161' ]; 243 244 tr.on('readable', function flow() { 245 let chunk; 246 while (null !== (chunk = tr.read(10))) 247 out.push(chunk); 248 }); 249 250 tr.on('end', common.mustCall(function() { 251 assert.deepStrictEqual(out, expect); 252 })); 253} 254 255{ 256 // Verify hex encoding with read(13) 257 const tr = new TestReader(100, { encoding: 'hex' }); 258 const out = []; 259 const expect = 260 [ '6161616161616', 261 '1616161616161', 262 '6161616161616', 263 '1616161616161', 264 '6161616161616', 265 '1616161616161', 266 '6161616161616', 267 '1616161616161', 268 '6161616161616', 269 '1616161616161', 270 '6161616161616', 271 '1616161616161', 272 '6161616161616', 273 '1616161616161', 274 '6161616161616', 275 '16161' ]; 276 277 tr.on('readable', function flow() { 278 let chunk; 279 while (null !== (chunk = tr.read(13))) 280 out.push(chunk); 281 }); 282 283 tr.on('end', common.mustCall(function() { 284 assert.deepStrictEqual(out, expect); 285 })); 286} 287 288{ 289 // Verify base64 encoding 290 const tr = new TestReader(100, { encoding: 'base64' }); 291 const out = []; 292 const expect = 293 [ 'YWFhYWFhYW', 294 'FhYWFhYWFh', 295 'YWFhYWFhYW', 296 'FhYWFhYWFh', 297 'YWFhYWFhYW', 298 'FhYWFhYWFh', 299 'YWFhYWFhYW', 300 'FhYWFhYWFh', 301 'YWFhYWFhYW', 302 'FhYWFhYWFh', 303 'YWFhYWFhYW', 304 'FhYWFhYWFh', 305 'YWFhYWFhYW', 306 'FhYQ==' ]; 307 308 tr.on('readable', function flow() { 309 let chunk; 310 while (null !== (chunk = tr.read(10))) 311 out.push(chunk); 312 }); 313 314 tr.on('end', common.mustCall(function() { 315 assert.deepStrictEqual(out, expect); 316 })); 317} 318 319{ 320 // Verify chaining behavior 321 const tr = new TestReader(100); 322 assert.deepStrictEqual(tr.setEncoding('utf8'), tr); 323} 324