summaryrefslogtreecommitdiff
path: root/src/interfaces/jdbc/postgresql/PG_Stream.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/jdbc/postgresql/PG_Stream.java')
-rw-r--r--src/interfaces/jdbc/postgresql/PG_Stream.java309
1 files changed, 309 insertions, 0 deletions
diff --git a/src/interfaces/jdbc/postgresql/PG_Stream.java b/src/interfaces/jdbc/postgresql/PG_Stream.java
new file mode 100644
index 00000000000..3e3350dd10d
--- /dev/null
+++ b/src/interfaces/jdbc/postgresql/PG_Stream.java
@@ -0,0 +1,309 @@
+package postgresql;
+
+import java.io.*;
+import java.lang.*;
+import java.net.*;
+import java.util.*;
+import java.sql.*;
+import postgresql.*;
+
+/**
+ * @version 1.0 15-APR-1997
+ *
+ * This class is used by Connection & PGlobj for communicating with the
+ * backend.
+ *
+ * @see java.sql.Connection
+ */
+// This class handles all the Streamed I/O for a postgresql connection
+public class PG_Stream
+{
+ private Socket connection;
+ private InputStream pg_input;
+ private OutputStream pg_output;
+
+ /**
+ * Constructor: Connect to the PostgreSQL back end and return
+ * a stream connection.
+ *
+ * @param host the hostname to connect to
+ * @param port the port number that the postmaster is sitting on
+ * @exception IOException if an IOException occurs below it.
+ */
+ public PG_Stream(String host, int port) throws IOException
+ {
+ connection = new Socket(host, port);
+ pg_input = connection.getInputStream();
+ pg_output = connection.getOutputStream();
+ }
+
+ /**
+ * Sends a single character to the back end
+ *
+ * @param val the character to be sent
+ * @exception IOException if an I/O error occurs
+ */
+ public void SendChar(int val) throws IOException
+ {
+ //pg_output.write(val);
+ byte b[] = new byte[1];
+ b[0] = (byte)val;
+ pg_output.write(b);
+ }
+
+ /**
+ * Sends an integer to the back end
+ *
+ * @param val the integer to be sent
+ * @param siz the length of the integer in bytes (size of structure)
+ * @exception IOException if an I/O error occurs
+ */
+ public void SendInteger(int val, int siz) throws IOException
+ {
+ byte[] buf = new byte[siz];
+
+ while (siz-- > 0)
+ {
+ buf[siz] = (byte)(val & 0xff);
+ val >>= 8;
+ }
+ Send(buf);
+ }
+
+ /**
+ * Send an array of bytes to the backend
+ *
+ * @param buf The array of bytes to be sent
+ * @exception IOException if an I/O error occurs
+ */
+ public void Send(byte buf[]) throws IOException
+ {
+ pg_output.write(buf);
+ }
+
+ /**
+ * Send an exact array of bytes to the backend - if the length
+ * has not been reached, send nulls until it has.
+ *
+ * @param buf the array of bytes to be sent
+ * @param siz the number of bytes to be sent
+ * @exception IOException if an I/O error occurs
+ */
+ public void Send(byte buf[], int siz) throws IOException
+ {
+ Send(buf,0,siz);
+ }
+
+ /**
+ * Send an exact array of bytes to the backend - if the length
+ * has not been reached, send nulls until it has.
+ *
+ * @param buf the array of bytes to be sent
+ * @param off offset in the array to start sending from
+ * @param siz the number of bytes to be sent
+ * @exception IOException if an I/O error occurs
+ */
+ public void Send(byte buf[], int off, int siz) throws IOException
+ {
+ int i;
+
+ pg_output.write(buf, off, ((buf.length-off) < siz ? (buf.length-off) : siz));
+ if((buf.length-off) < siz)
+ {
+ for (i = buf.length-off ; i < siz ; ++i)
+ {
+ pg_output.write(0);
+ }
+ }
+ }
+
+ /**
+ * Receives a single character from the backend
+ *
+ * @return the character received
+ * @exception SQLException if an I/O Error returns
+ */
+ public int ReceiveChar() throws SQLException
+ {
+ int c = 0;
+
+ try
+ {
+ c = pg_input.read();
+ if (c < 0) throw new IOException("EOF");
+ } catch (IOException e) {
+ throw new SQLException("Error reading from backend: " + e.toString());
+ }
+ return c;
+ }
+
+ /**
+ * Receives an integer from the backend
+ *
+ * @param siz length of the integer in bytes
+ * @return the integer received from the backend
+ * @exception SQLException if an I/O error occurs
+ */
+ public int ReceiveInteger(int siz) throws SQLException
+ {
+ int n = 0;
+
+ try
+ {
+ for (int i = 0 ; i < siz ; i++)
+ {
+ int b = pg_input.read();
+
+ if (b < 0)
+ throw new IOException("EOF");
+ n = n | (b >> (8 * i)) ;
+ }
+ } catch (IOException e) {
+ throw new SQLException("Error reading from backend: " + e.toString());
+ }
+ return n;
+ }
+
+ /**
+ * Receives a null-terminated string from the backend. Maximum of
+ * maxsiz bytes - if we don't see a null, then we assume something
+ * has gone wrong.
+ *
+ * @param maxsiz maximum length of string
+ * @return string from back end
+ * @exception SQLException if an I/O error occurs
+ */
+ public String ReceiveString(int maxsiz) throws SQLException
+ {
+ byte[] rst = new byte[maxsiz];
+ int s = 0;
+
+ try
+ {
+ while (s < maxsiz)
+ {
+ int c = pg_input.read();
+ if (c < 0)
+ throw new IOException("EOF");
+ else if (c == 0)
+ break;
+ else
+ rst[s++] = (byte)c;
+ }
+ if (s >= maxsiz)
+ throw new IOException("Too Much Data");
+ } catch (IOException e) {
+ throw new SQLException("Error reading from backend: " + e.toString());
+ }
+ String v = new String(rst, 0, s);
+ return v;
+ }
+
+ /**
+ * Read a tuple from the back end. A tuple is a two dimensional
+ * array of bytes
+ *
+ * @param nf the number of fields expected
+ * @param bin true if the tuple is a binary tuple
+ * @return null if the current response has no more tuples, otherwise
+ * an array of strings
+ * @exception SQLException if a data I/O error occurs
+ */
+ public byte[][] ReceiveTuple(int nf, boolean bin) throws SQLException
+ {
+ int i, bim = (nf + 7)/8;
+ byte[] bitmask = Receive(bim);
+ byte[][] answer = new byte[nf][0];
+
+ int whichbit = 0x80;
+ int whichbyte = 0;
+
+ for (i = 0 ; i < nf ; ++i)
+ {
+ boolean isNull = ((bitmask[whichbyte] & whichbit) == 0);
+ whichbit >>= 1;
+ if (whichbit == 0)
+ {
+ ++whichbyte;
+ whichbit = 0x80;
+ }
+ if (isNull)
+ answer[i] = null;
+ else
+ {
+ int len = ReceiveInteger(4);
+ if (!bin)
+ len -= 4;
+ if (len < 0)
+ len = 0;
+ answer[i] = Receive(len);
+ }
+ }
+ return answer;
+ }
+
+ /**
+ * Reads in a given number of bytes from the backend
+ *
+ * @param siz number of bytes to read
+ * @return array of bytes received
+ * @exception SQLException if a data I/O error occurs
+ */
+ private byte[] Receive(int siz) throws SQLException
+ {
+ byte[] answer = new byte[siz];
+ int s = 0;
+
+ try
+ {
+ while (s < siz)
+ {
+ int w = pg_input.read(answer, s, siz - s);
+ if (w < 0)
+ throw new IOException("EOF");
+ s += w;
+ }
+ } catch (IOException e) {
+ throw new SQLException("Error reading from backend: " + e.toString());
+ }
+ return answer;
+ }
+
+ /**
+ * Reads in a given number of bytes from the backend
+ *
+ * @param buf buffer to store result
+ * @param off offset in buffer
+ * @param siz number of bytes to read
+ * @exception SQLException if a data I/O error occurs
+ */
+ public void Receive(byte[] b,int off,int siz) throws SQLException
+ {
+ int s = 0;
+
+ try
+ {
+ while (s < siz)
+ {
+ int w = pg_input.read(b, off+s, siz - s);
+ if (w < 0)
+ throw new IOException("EOF");
+ s += w;
+ }
+ } catch (IOException e) {
+ throw new SQLException("Error reading from backend: " + e.toString());
+ }
+ }
+
+ /**
+ * Closes the connection
+ *
+ * @exception IOException if a IO Error occurs
+ */
+ public void close() throws IOException
+ {
+ pg_output.close();
+ pg_input.close();
+ connection.close();
+ }
+}