private void fill ( ) throws IOException { byte [ ] buffer = getBufIfOpen ( ) ; if ( markpos < 0 ) pos = 0 ; /* no mark: throw away the buffer */ else if ( pos >= buffer . length ) /* no room left in buffer */ if ( markpos > 0 ) { /* can throw away early part of the buffer */ int sz = pos - markpos ; System . arraycopy ( buffer , markpos , buffer , 0 , sz ) ; pos = sz ; markpos = 0 ; } else if ( buffer . length >= marklimit ) { markpos = - 1 ; /* buffer got too big, invalidate mark */ pos = 0 ; /* drop buffer contents */ } else if ( buffer . length >= MAX_BUFFER_SIZE ) { throw new OutOfMemoryError ( "Required array size too large" ) ; } else { /* grow buffer */ int nsz = ( pos <= MAX_BUFFER_SIZE - pos ) ? pos * 2 : MAX_BUFFER_SIZE ; if ( nsz > marklimit ) nsz = marklimit ; byte nbuf [ ] = new byte [ nsz ] ; System . arraycopy ( buffer , 0 , nbuf , 0 , pos ) ; if ( ! compareAndSetBuf ( buffer , nbuf ) ) { // Can't replace buf if there was an async close. // Note: This would need to be changed if fill() // is ever made accessible to multiple threads. // But for now, the only way CAS can fail is via close. // assert buf == null; throw new IOException ( "Stream closed" ) ; } buffer = nbuf ; } count = pos ; int n = getInIfOpen ( ) . read ( buffer , pos , buffer . length - pos ) ; if ( n > 0 ) count = n + pos ; }
Fills the buffer with more data taking into account shuffling and other tricks for dealing with marks . Assumes that it is being called by a synchronized method . This method also assumes that all data has already been read in hence pos > count .