public void seekRelative(long relativeOffset) throws IOException {
   ensureReadyOnFirstUse();
   long pos = streamDataInput.getAbsolutePosition();
   pos += relativeOffset;
   if (pos < filePositionOfStreamData) pos = filePositionOfStreamData;
   // It's alright to seek beyond the end, it's just that read operations will fail
   streamDataInput.seekAbsolute(pos);
 }
 private void endCurrentUse() throws IOException {
   // System.out.println("SICW.endCurrentUse()  About to ... " + this);
   if (usedYet) {
     streamDataInput.seekAbsolute(filePositionBeforeUse);
     usedYet = false;
   }
   endThreadAccess();
   // System.out.println("SICW.endCurrentUse()  ... Done     " + this);
 }
  private void ensureReadyOnFirstUse() throws IOException {
    beginThreadAccess();
    if (usedYet) return;
    usedYet = true;

    // System.out.println("SICW.ensureReadyOnFirstUse()  About to ... " + this);
    filePositionBeforeUse = streamDataInput.getAbsolutePosition();
    streamDataInput.seekAbsolute(filePositionOfStreamData);
    // System.out.println("SICW.ensureReadyOnFirstUse()  ... Done     " + this);
  }
 public void seekAbsolute(long absolutePosition) throws IOException {
   ensureReadyOnFirstUse();
   // The wrapper exists in a different coordinate system,
   //   where its beginning is location 0
   if (absolutePosition < 0L)
     throw new IOException("Attempt to absolutely seek to negative location: " + absolutePosition);
   // It's alright to seek beyond the end, it's just that read operations will fail
   absolutePosition += filePositionOfStreamData;
   streamDataInput.seekAbsolute(absolutePosition);
 }
 public void seekEnd() throws IOException {
   ensureReadyOnFirstUse();
   streamDataInput.seekAbsolute(filePositionOfStreamData + lengthOfStreamData);
 }