- conn.pg_stream.SendInteger(args[i],4);
-
- if(args[args.length-1]==0)
- conn.pg_stream.Send(buf,off,len);
-
- } catch(Exception e) {
- throw new SQLException("lo_open failed");
- }
- //try {
- if((in = conn.pg_stream.ReceiveChar())!='V') {
- if(in=='E')
- throw new SQLException(conn.pg_stream.ReceiveString(4096));
- throw new SQLException("lobj: expected 'V' from backend, got "+((char)in));
- }
-
- while(true) {
- in = conn.pg_stream.ReceiveChar();
- switch(in)
- {
- case 'G':
- if(buf==null)
- in = conn.pg_stream.ReceiveInteger(4);
- else
- conn.pg_stream.Receive(buf,off,len);
- conn.pg_stream.ReceiveChar();
- return in;
-
- case 'E':
- throw new SQLException("lobj: error - "+conn.pg_stream.ReceiveString(4096));
-
- case 'N':
- conn.pg_stream.ReceiveString(4096);
- break;
-
- case '0':
- return -1;
-
- default:
- throw new SQLException("lobj: protocol error");
- }
- }
- // } catch(IOException ioe) {
- // throw new SQLException("lobj: Network error - "+ioe);
- //}
- }
-
- /**
- * This opens a large object. It returns a handle that is used to
- * access the object.
- */
- public int open(int lobjId,int mode) throws SQLException
- {
- int args[] = new int[2*3];
- args[0] = args[3] = 4;
- args[1] = args[4] = 1;
- args[2] = lobjId;
- args[5] = mode;
-
- int fd = PQfn(getFunc(OPEN),args);
- if(fd<0)
- throw new SQLException("lo_open: no object");
- seek(fd,0);
- return fd;
- }
-
- /**
- * This closes a large object.
- */
- public void close(int fd) throws SQLException
- {
- int args[] = new int[1*3];
- args[0] = 4;
- args[1] = 1;
- args[2] = fd;
-
- // flush/close streams here?
- PQfn(getFunc(CLOSE),args);
- }
-
- /**
- * This reads a block of bytes from the large object
- * @param fd descriptor for an open large object
- * @param buf byte array to write into
- * @param off offset in array
- * @param len number of bytes to read
- */
- public void read(int fd,byte buf[],int off,int len) throws SQLException
- {
- int args[] = new int[2*3];
- args[0] = args[3] = 4;
- args[1] = args[4] = 1;
- args[2] = fd;
- args[5] = len;
-
- PQfn(getFunc(READ),args,buf,off,len);
- }
-
- /**
- * This writes a block of bytes to an open large object
- * @param fd descriptor for an open large object
- * @param buf byte array to write into
- * @param off offset in array
- * @param len number of bytes to read
- */
- public void write(int fd,byte buf[],int off,int len) throws SQLException
- {
- int args[] = new int[2*3];
- args[0] = args[3] = 4;
- args[1] = args[4] = 1;
- args[2] = fd;
- args[5] = 0;
-
- PQfn(getFunc(WRITE),args,buf,off,len);
- }
-
- /**
- * This sets the current read or write location on a large object.
- * @param fd descriptor of an open large object
- * @param off offset in object
- */
- public void seek(int fd,int off) throws SQLException
- {
- int args[] = new int[3*3];
- args[0] = args[3] = args[6] = 4;
- args[1] = args[4] = args[7] = 1;
- args[2] = fd;
- args[5] = off;
- args[8] = 0; // SEEK
-
- PQfn(getFunc(SEEK),args);
- }
-
- /**
- * This creates a new large object.
- *
- * the mode is a bitmask describing different attributes of the new object
- *
- * returns the oid of the large object created.
- */
- public int create(int mode) throws SQLException
- {
- int args[] = new int[1*3];
- args[0] = 4;
- args[1] = 1;
- args[2] = mode;
-
- return PQfn(getFunc(CREATE),args);
- }
-
- /**
- * This returns the current location within the large object
- */
- public int tell(int fd) throws SQLException
- {
- int args[] = new int[1*3];
- args[0] = 4;
- args[1] = 1;
- args[2] = fd;
-
- return PQfn(getFunc(TELL),args);
- }
-
- /**
- * This removes a large object from the database
- */
- public void unlink(int fd) throws SQLException
- {
- int args[] = new int[1*3];
- args[0] = 4;
- args[1] = 1;
- args[2] = fd;
-
- PQfn(getFunc(UNLINK),args);
- }
-
- /**
- * This returns an InputStream based on an object
- */
- public InputStream getInputStream(int fd) throws SQLException
- {
- return (InputStream) new PGlobjInput(this,fd);
- }
-
- /**
- * This returns an OutputStream based on an object
- */
- public OutputStream getOutputStream(int fd) throws SQLException
- {
- return (OutputStream) new PGlobjOutput(this,fd);
- }
-
- /**
- * As yet, the lo_import and lo_export functions are not implemented.
- */
-}
-
-// This class implements an InputStream based on a large object
-//
-// Note: Unlike most InputStreams, this one supports mark()/reset()
-//
-class PGlobjInput extends InputStream
-{
- private PGlobj obj;
- private int fd;
-
- private int mp; // mark position
- private int rl; // read limit
-
- // This creates an Input stream based for a large object
- public PGlobjInput(PGlobj obj,int fd)
- {
- this.obj = obj;
- this.fd = fd;
- }
-
- public int read() throws IOException
- {
- byte b[] = new byte[1];
- read(b,0,1);
- return (int)b[0];
- }
-
- public int read(byte b[],int off,int len) throws IOException
- {
- try {
- obj.read(fd,b,off,len);
- } catch(SQLException e) {
- throw new IOException(e.toString());
- }
- return len;
- }
-
- public long skip(long n) throws IOException
- {
- try {
- int cp = obj.tell(fd);
- obj.seek(fd,cp+(int)n);
- return obj.tell(fd) - cp;
- } catch(SQLException e) {
- throw new IOException(e.toString());
- }
- }
-
- public synchronized void mark(int readLimit)
- {
- try {
- mp = obj.tell(fd);
- rl = readLimit;
- } catch(SQLException e) {
- // We should throw an exception here, but mark() doesn't ;-(
- }
- }
-
- public void reset() throws IOException
- {
- try {
- int cp = obj.tell(fd);
- if((cp-mp)>rl)
- throw new IOException("mark invalidated");
- obj.seek(fd,mp);
- } catch(SQLException e) {
- throw new IOException(e.toString());
- }
- }
-
- public boolean markSupported()
- {
- return true;
- }
-
-
- public void close() throws IOException
- {
- try {
- obj.close(fd);
- } catch(SQLException e) {
- throw new IOException(e.toString());
- }
- }
-}
-
-// This class implements an OutputStream to a large object
-class PGlobjOutput extends OutputStream
-{
- private PGlobj obj;
- private int fd;
-
- // This creates an Input stream based for a large object
- public PGlobjOutput(PGlobj obj,int fd)
- {
- this.obj = obj;
- this.fd = fd;
- }
-
- public void write(int i) throws IOException
- {
- byte b[] = new byte[1];
- b[0] = (byte)i;
- write(b,0,1);
- }
-
- public void write(byte b[],int off,int len) throws IOException
- {
- try {
- obj.write(fd,b,off,len);
- } catch(SQLException e) {
- throw new IOException(e.toString());
- }
- }
-
- public void close() throws IOException
- {
- try {
- obj.close(fd);
- } catch(SQLException e) {
- throw new IOException(e.toString());
- }
- }
-}