/*------------------------------------------------------------------------- * * BlobInputStream.java * This is an implementation of an InputStream from a large object. * * Copyright (c) 2003, PostgreSQL Global Development Group * * IDENTIFICATION * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/largeobject/BlobInputStream.java,v 1.6 2003/11/29 19:52:11 pgsql Exp $ * *------------------------------------------------------------------------- */ package org.postgresql.largeobject; import java.io.InputStream; import java.io.IOException; import java.sql.SQLException; public class BlobInputStream extends InputStream { /* * The parent LargeObject */ private LargeObject lo; /* * Buffer used to improve performance */ private byte[] buffer; /* * Position within buffer */ private int bpos; /* * The buffer size */ private int bsize; /* * The mark position */ private int mpos = 0; /* * @param lo LargeObject to read from */ public BlobInputStream(LargeObject lo) { this(lo, 1024); } /* * @param lo LargeObject to read from * @param bsize buffer size */ public BlobInputStream(LargeObject lo, int bsize) { this.lo = lo; buffer = null; bpos = 0; this.bsize = bsize; } /* * The minimum required to implement input stream */ public int read() throws java.io.IOException { try { if (buffer == null || bpos >= buffer.length) { buffer = lo.read(bsize); bpos = 0; } // Handle EOF if (bpos >= buffer.length) { return -1; } int ret = (buffer[bpos] & 0x7F); if ((buffer[bpos] &0x80) == 0x80) { ret |= 0x80; } bpos++; return ret; } catch (SQLException se) { throw new IOException(se.toString()); } } /* * Closes this input stream and releases any system resources associated * with the stream. * *
The close
method of InputStream
does
* nothing.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException
{
try
{
lo.close();
lo = null;
}
catch (SQLException se)
{
throw new IOException(se.toString());
}
}
/*
* Marks the current position in this input stream. A subsequent call to
* the reset
method repositions this stream at the last marked
* position so that subsequent reads re-read the same bytes.
*
*
The readlimit
arguments tells this input stream to
* allow that many bytes to be read before the mark position gets
* invalidated.
*
*
The general contract of mark
is that, if the method
* markSupported
returns true
, the stream somehow
* remembers all the bytes read after the call to mark
and
* stands ready to supply those same bytes again if and whenever the method
* reset
is called. However, the stream is not required to
* remember any data at all if more than readlimit
bytes are
* read from the stream before reset
is called.
*
*
The mark
method of InputStream
does
* nothing.
*
* @param readlimit the maximum limit of bytes that can be read before
* the mark position becomes invalid.
* @see java.io.InputStream#reset()
*/
public synchronized void mark(int readlimit)
{
try
{
mpos = lo.tell();
}
catch (SQLException se)
{
//throw new IOException(se.toString());
}
}
/*
* Repositions this stream to the position at the time the
* mark
method was last called on this input stream.
* NB: If mark is not called we move to the begining.
* @see java.io.InputStream#mark(int)
* @see java.io.IOException
*/
public synchronized void reset()
throws IOException
{
try
{
lo.seek(mpos);
}
catch (SQLException se)
{
throw new IOException(se.toString());
}
}
/*
* Tests if this input stream supports the mark
and
* reset
methods. The markSupported
method of
* InputStream
returns false
.
*
* @return true
if this true type supports the mark and reset
* method; false
otherwise.
* @see java.io.InputStream#mark(int)
* @see java.io.InputStream#reset()
*/
public boolean markSupported()
{
return true;
}
}