All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.postgresql.largeobject.BlobInputStream Maven / Gradle / Ivy

There is a newer version: 42.7.4
Show newest version
/*
 * Copyright (c) 2003, PostgreSQL Global Development Group
 * See the LICENSE file in the project root for more information.
 */

package org.postgresql.largeobject;

import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;

/**
 * This is an implementation of an InputStream from a large object.
 */
public class BlobInputStream extends InputStream {
  /**
   * The parent LargeObject
   */
  private LargeObject lo;

  /**
   * The absolute position
   */
  private long apos;

  /**
   * 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;

  /**
   * The limit
   */
  private long limit = -1;

  /**
   * @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, bsize, -1);
  }

  /**
   * @param lo LargeObject to read from
   * @param bsize buffer size
   * @param limit max number of bytes to read
   */
  public BlobInputStream(LargeObject lo, int bsize, long limit) {
    this.lo = lo;
    buffer = null;
    bpos = 0;
    apos = 0;
    this.bsize = bsize;
    this.limit = limit;
  }

  /**
   * The minimum required to implement input stream
   */
  public int read() throws java.io.IOException {
    checkClosed();
    try {
      if (limit > 0 && apos >= limit) {
        return -1;
      }
      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++;
      apos++;

      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. * * @throws IOException if an I/O error occurs. */ public void close() throws IOException { if (lo != null) { 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. * *

* Marking a closed stream should not have any effect on the stream. * * @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) { // Can't throw this because mark API doesn't allow it. // 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 { checkClosed(); 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; } private void checkClosed() throws IOException { if (lo == null) { throw new IOException("BlobOutputStream is closed"); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy