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 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 int available()
     throws IOException
 {
     long l = in.length() - in.tell();
     if (l > 0x7fffffffL)
     {
         return 0x7fffffff;
     } else
     {
         return (int)l;
     }
 }
 public static DataFileReader openReader(SeekableInput seekableinput, DatumReader datumreader, DataFileStream.Header header, boolean flag)
     throws IOException
 {
     datumreader = new DataFileReader(seekableinput, datumreader, header);
     if (flag)
     {
         datumreader.sync(seekableinput.tell());
         return datumreader;
     } else
     {
         datumreader.seek(seekableinput.tell());
         return datumreader;
     }
 }
 public long skip(long n) throws IOException {
   ensureReadyOnFirstUse();
   long remain = getBytesRemaining();
   if (remain <= 0) return -1;
   n = (int) Math.min(Math.min(remain, (long) n), (long) Integer.MAX_VALUE);
   return streamDataInput.skip(n);
 }
 //
 // Methods from InputStream
 // Since Java does not have multiple inheritance, we have to
 //  explicitly expose InputStream's methods as part of our interface
 //
 public int read() throws IOException {
   ensureReadyOnFirstUse();
   long remain = getBytesRemaining();
   // System.out.println("SICW.read()  remain: " + remain);
   if (remain <= 0) return -1;
   return streamDataInput.read();
 }
 public int read(byte[] buffer, int offset, int length) throws IOException {
   ensureReadyOnFirstUse();
   long remain = getBytesRemaining();
   // System.out.println("SICW.read( "+length+" )  remain: " + remain);
   if (remain <= 0) return -1;
   length = (int) Math.min(Math.min(remain, (long) length), (long) Integer.MAX_VALUE);
   return streamDataInput.read(buffer, offset, length);
 }
 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);
 }
 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 seek(long l)
     throws IOException
 {
     if (l < 0L)
     {
         throw new IOException((new StringBuilder()).append("Illegal seek: ").append(l).toString());
     } else
     {
         in.seek(l);
         return;
     }
 }
 public static FileReader openReader(SeekableInput seekableinput, DatumReader datumreader)
     throws IOException
 {
     if (seekableinput.length() < (long)DataFileConstants.MAGIC.length)
     {
         throw new IOException("Not an Avro data file");
     }
     byte abyte0[] = new byte[DataFileConstants.MAGIC.length];
     seekableinput.seek(0L);
     for (int i = 0; i < abyte0.length; i = seekableinput.read(abyte0, i, abyte0.length - i)) { }
     seekableinput.seek(0L);
     if (Arrays.equals(DataFileConstants.MAGIC, abyte0))
     {
         return new DataFileReader(seekableinput, datumreader);
     }
     if (Arrays.equals(DataFileReader12.MAGIC, abyte0))
     {
         return new DataFileReader12(seekableinput, datumreader);
     } else
     {
         throw new IOException("Not an Avro data file");
     }
 }
 public void dispose() throws IOException {
   beginThreadAccess();
   // System.out.println("SICW.endFinalUse()  About to ... " + this);
   if (takeOwnershipOfStreamDataInput) {
     if (streamDataInput != null) {
       streamDataInput.close();
       endThreadAccess();
       streamDataInput = null;
     }
   } else {
     endCurrentUse(); // In case using code forgot
   }
   // System.out.println("SICW.endFinalUse()  ... Done     " + this);
 }
 public String toString() {
   StringBuilder sb = new StringBuilder();
   sb.append(super.toString());
   sb.append(" ( ");
   sb.append("pos=").append(filePositionOfStreamData).append(", ");
   sb.append("len=").append(lengthOfStreamData).append(", ");
   sb.append("posToRestore=").append(filePositionBeforeUse).append(", ");
   sb.append("own=").append(takeOwnershipOfStreamDataInput).append(", ");
   sb.append("usedYet=").append(usedYet);
   sb.append(" ) ");
   sb.append(": ");
   if (streamDataInput == null) sb.append("null ");
   else sb.append(streamDataInput.toString());
   return sb.toString();
 }
 public long skip(long l)
     throws IOException
 {
     long l1 = in.tell();
     long l2 = in.length() - l1;
     if (l2 > l)
     {
         in.seek(l);
         return in.tell() - l1;
     } else
     {
         in.seek(l2);
         return in.tell() - l1;
     }
 }
 public void endThreadAccess() {
   if (streamDataInput != null) streamDataInput.endThreadAccess();
 }
 public void beginThreadAccess() {
   if (streamDataInput != null) streamDataInput.beginThreadAccess();
 }
 public int read(byte abyte0[], int i, int j)
     throws IOException
 {
     return in.read(abyte0, i, j);
 }
 public void close()
     throws IOException
 {
     in.close();
     super.close();
 }
 public long length()
     throws IOException
 {
     return in.length();
 }
 private long getBytesRemaining() throws IOException {
   long absPos = streamDataInput.getAbsolutePosition();
   if (absPos < filePositionOfStreamData) return -1;
   long end = filePositionOfStreamData + lengthOfStreamData;
   return end - absPos;
 }
 public void seekEnd() throws IOException {
   ensureReadyOnFirstUse();
   streamDataInput.seekAbsolute(filePositionOfStreamData + lengthOfStreamData);
 }
 public long tell()
     throws IOException
 {
     return in.tell();
 }
 public int read(byte abyte0[])
     throws IOException
 {
     return in.read(abyte0, 0, abyte0.length);
 }