public int readUByte() {
   checkAvaliable(1);
   int result = _currentBlock.readUByte();
   _current_offset++;
   if (_currentBlock.available() < 1) {
     _currentBlock = getDataInputBlock(_current_offset);
   }
   return result;
 }
 public long readLong() {
   checkAvaliable(SIZE_LONG);
   int blockAvailable = _currentBlock.available();
   long result;
   if (blockAvailable > SIZE_LONG) {
     result = _currentBlock.readLongLE();
   } else {
     DataInputBlock nextBlock = getDataInputBlock(_current_offset + blockAvailable);
     if (blockAvailable == SIZE_LONG) {
       result = _currentBlock.readLongLE();
     } else {
       result = nextBlock.readLongLE(_currentBlock, blockAvailable);
     }
     _currentBlock = nextBlock;
   }
   _current_offset += SIZE_LONG;
   return result;
 }
 public int readUShort() {
   checkAvaliable(SIZE_SHORT);
   int blockAvailable = _currentBlock.available();
   int result;
   if (blockAvailable > SIZE_SHORT) {
     result = _currentBlock.readUShortLE();
   } else {
     DataInputBlock nextBlock = getDataInputBlock(_current_offset + blockAvailable);
     if (blockAvailable == SIZE_SHORT) {
       result = _currentBlock.readUShortLE();
     } else {
       result = nextBlock.readUShortLE(_currentBlock);
     }
     _currentBlock = nextBlock;
   }
   _current_offset += SIZE_SHORT;
   return result;
 }
 public void readFully(byte[] buf, int off, int len) {
   checkAvaliable(len);
   int blockAvailable = _currentBlock.available();
   if (blockAvailable > len) {
     _currentBlock.readFully(buf, off, len);
     _current_offset += len;
     return;
   }
   // else read big amount in chunks
   int remaining = len;
   int writePos = off;
   while (remaining > 0) {
     boolean blockIsExpiring = remaining >= blockAvailable;
     int reqSize;
     if (blockIsExpiring) {
       reqSize = blockAvailable;
     } else {
       reqSize = remaining;
     }
     _currentBlock.readFully(buf, writePos, reqSize);
     remaining -= reqSize;
     writePos += reqSize;
     _current_offset += reqSize;
     if (blockIsExpiring) {
       if (_current_offset == _document_size) {
         if (remaining > 0) {
           throw new IllegalStateException("reached end of document stream unexpectedly");
         }
         _currentBlock = null;
         break;
       }
       _currentBlock = getDataInputBlock(_current_offset);
       blockAvailable = _currentBlock.available();
     }
   }
 }