protected int refill ( ) throws IOException { UnifiedDataPageX curr = _buffer . getCurrentPage ( ) ; SavePoint sp = _save_points . savePointActiveTop ( ) ; if ( ! can_fill_new_page ( ) ) { // aka: there can be only one! // (and it's used up) return refill_is_eof ( ) ; } if ( sp != null && sp . getEndIdx ( ) == _buffer . getCurrentPageIdx ( ) ) { // also EOF but the case is odd enough to call it out return refill_is_eof ( ) ; } long file_position ; int start_pos = UNREAD_LIMIT ; if ( curr == null ) { file_position = 0 ; start_pos = 0 ; } else { file_position = curr . getFilePosition ( _pos ) ; if ( file_position == 0 ) { // unread before the beginning of file is not allowed, // so we don't have to leave room for it start_pos = 0 ; } } // see if we are re-reading saved buffers int new_idx = _buffer . getNextFilledPageIdx ( ) ; if ( new_idx < 0 ) { // there is no pre-filled page waiting for us, so we need to // read new data on a new page or over our current page curr = _buffer . getCurrentPage ( ) ; boolean needs_new_page = ( curr == null ) ; new_idx = _buffer . getCurrentPageIdx ( ) ; if ( _save_points . isSavePointOpen ( ) ) { new_idx ++ ; needs_new_page = true ; } if ( needs_new_page ) { curr = _buffer . getEmptyPageIdx ( ) ; } // // here we actually read data into our buffers ----- // int read = load ( curr , start_pos , file_position ) ; if ( read < 1 ) { return refill_is_eof ( ) ; } assert ( curr != null && curr . getOffsetOfFilePosition ( file_position ) == start_pos ) ; set_current_page ( new_idx , curr , start_pos ) ; } else { assert ( ! isEOF ( ) ) ; if ( sp != null ) { int endidx = sp . getEndIdx ( ) ; if ( endidx != - 1 && endidx < new_idx /*_buffer.getCurrentPageIdx()*/ ) { return refill_is_eof ( ) ; } } curr = _buffer . getPage ( new_idx ) ; assert ( curr . getStartingFileOffset ( ) == file_position ) ; set_current_page ( new_idx , curr , curr . getStartingOffset ( ) ) ; if ( sp != null && sp . getEndIdx ( ) == new_idx /*_buffer.getCurrentPageIdx()*/ ) { // the last page in the marked range will probably // require a different limit _limit = sp . getEndPos ( ) ; } } assert ( isEOF ( ) ^ ( _limit > 0 ) ) ; // xor: either we're at eof or we have data to read return _limit ; }
the refill method is the key override that is filled in by the various subclasses . It fills either the byte or char array with a block of data from the input source . As this is a virtual function the right version will get called for each source type . Since it is only called once per block and from then on the final method which pulls data from the block can return the value this should be a reasonable performance trade off .