@@ -77,6 +77,42 @@ function convertNPNProtocols(NPNProtocols, out) {
7777 }
7878}
7979
80+
81+ function SlabBuffer ( ) {
82+ this . create ( ) ;
83+ } ;
84+
85+
86+ SlabBuffer . prototype . create = function create ( ) {
87+ this . isFull = false ;
88+ this . pool = new Buffer ( 10 * 1024 * 1024 ) ;
89+ this . offset = 0 ;
90+ this . remaining = this . pool . length ;
91+ } ;
92+
93+
94+ SlabBuffer . prototype . use = function use ( context , fn ) {
95+ if ( this . remaining === 0 ) {
96+ this . isFull = true ;
97+ return 0 ;
98+ }
99+
100+ var bytes = fn . call ( context , this . pool , this . offset , this . remaining ) ;
101+
102+ if ( bytes > 0 ) {
103+ this . offset += bytes ;
104+ this . remaining -= bytes ;
105+ }
106+
107+ assert ( this . remaining >= 0 ) ;
108+
109+ return bytes ;
110+ } ;
111+
112+
113+ var slabBuffer = new SlabBuffer ( ) ;
114+
115+
80116// Base class of both CleartextStream and EncryptedStream
81117function CryptoStream ( pair ) {
82118 Stream . call ( this ) ;
@@ -90,6 +126,7 @@ function CryptoStream(pair) {
90126 this . _pending = [ ] ;
91127 this . _pendingCallbacks = [ ] ;
92128 this . _pendingBytes = 0 ;
129+ this . _buffer = slabBuffer ;
93130}
94131util . inherits ( CryptoStream , Stream ) ;
95132
@@ -339,18 +376,13 @@ CryptoStream.prototype._push = function() {
339376 }
340377
341378 while ( ! this . _paused ) {
342- var chunkBytes = 0 ;
343- if ( ! this . _pool || ( this . _poolStart >= this . _poolEnd ) ) {
344- this . _pool = new Buffer ( 16 * 4096 ) ;
345- this . _poolStart = 0 ;
346- this . _poolEnd = this . _pool . length ;
347- }
348- var start = this . _poolStart ;
379+ var chunkBytes = 0 ,
380+ bytesRead = 0 ,
381+ start = this . _buffer . offset ;
349382
350383 do {
351- chunkBytes = this . _pusher ( this . _pool ,
352- this . _poolStart ,
353- this . _poolEnd - this . _poolStart ) ;
384+ chunkBytes = this . _buffer . use ( this , this . _pusher ) ;
385+ if ( chunkBytes > 0 ) bytesRead += chunkBytes ;
354386
355387 if ( this . pair . ssl && this . pair . ssl . error ) {
356388 this . pair . error ( ) ;
@@ -359,13 +391,12 @@ CryptoStream.prototype._push = function() {
359391
360392 this . pair . maybeInitFinished ( ) ;
361393
362- if ( chunkBytes >= 0 ) {
363- this . _poolStart += chunkBytes ;
364- }
394+ } while ( chunkBytes > 0 && ! this . _buffer . isFull ) ;
365395
366- } while ( chunkBytes > 0 && this . _poolStart < this . _poolEnd ) ;
396+ var pool = this . _buffer . pool ;
367397
368- var bytesRead = this . _poolStart - start ;
398+ // Create new buffer if previous was filled up
399+ if ( this . _buffer . isFull ) this . _buffer . create ( ) ;
369400
370401 assert ( bytesRead >= 0 ) ;
371402
@@ -377,7 +408,7 @@ CryptoStream.prototype._push = function() {
377408 return ;
378409 }
379410
380- var chunk = this . _pool . slice ( start , this . _poolStart ) ;
411+ var chunk = pool . slice ( start , start + bytesRead ) ;
381412
382413 if ( this === this . pair . cleartext ) {
383414 debug ( 'cleartext emit "data" with ' + bytesRead + ' bytes' ) ;
@@ -393,7 +424,7 @@ CryptoStream.prototype._push = function() {
393424 }
394425
395426 // Optimization: emit the original buffer with end points
396- if ( this . ondata ) this . ondata ( this . _pool , start , this . _poolStart ) ;
427+ if ( this . ondata ) this . ondata ( pool , start , start + bytesRead ) ;
397428 }
398429} ;
399430
0 commit comments