1
/*-------------------------------------------------------------------------
4
* This class is used by Connection for communicating with the
7
* Copyright (c) 2003, PostgreSQL Global Development Group
10
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/core/Attic/PGStream.java,v 1.3.2.1 2004/03/29 17:47:47 barry Exp $
12
*-------------------------------------------------------------------------
14
package org.postgresql.core;
16
import java.io.BufferedInputStream;
17
import java.io.BufferedOutputStream;
18
import java.io.InputStream;
19
import java.io.IOException;
20
import java.net.Socket;
22
import org.postgresql.util.PSQLException;
23
import org.postgresql.util.PSQLState;
30
public Socket connection;
31
public InputStream pg_input;
32
public BufferedOutputStream pg_output;
33
private byte[] byte_buf = new byte[8*1024];
36
* Constructor: Connect to the PostgreSQL back end and return
37
* a stream connection.
39
* @param host the hostname to connect to
40
* @param port the port number that the postmaster is sitting on
41
* @exception IOException if an IOException occurs below it.
43
public PGStream(String p_host, int p_port) throws IOException
47
connection = new Socket(host, port);
49
// Submitted by Jason Venner <jason@idiom.com> adds a 10x speed
50
// improvement on FreeBSD machines (caused by a bug in their TCP Stack)
51
connection.setTcpNoDelay(true);
53
// Buffer sizes submitted by Sverre H Huseby <sverrehu@online.no>
54
pg_input = new BufferedInputStream(connection.getInputStream(), 8192);
55
pg_output = new BufferedOutputStream(connection.getOutputStream(), 8192);
59
* Sends a single character to the back end
61
* @param val the character to be sent
62
* @exception IOException if an I/O error occurs
64
public void SendChar(int val) throws IOException
66
pg_output.write((byte)val);
70
* Sends an integer to the back end
72
* @param val the integer to be sent
73
* @param siz the length of the integer in bytes (size of structure)
74
* @exception IOException if an I/O error occurs
76
public void SendInteger(int val, int siz) throws IOException
78
byte[] buf = new byte[siz];
82
buf[siz] = (byte)(val & 0xff);
89
* Sends an integer to the back end
91
* @param val the integer to be sent
92
* @param siz the length of the integer in bytes (size of structure)
93
* @exception IOException if an I/O error occurs
95
public void SendIntegerR(int val, int siz) throws IOException
97
byte[] buf = new byte[siz];
99
for (int i = 0; i < siz; i++)
101
buf[i] = (byte)(val & 0xff);
108
* Send an array of bytes to the backend
110
* @param buf The array of bytes to be sent
111
* @exception IOException if an I/O error occurs
113
public void Send(byte buf[]) throws IOException
115
pg_output.write(buf);
119
* Send an exact array of bytes to the backend - if the length
120
* has not been reached, send nulls until it has.
122
* @param buf the array of bytes to be sent
123
* @param siz the number of bytes to be sent
124
* @exception IOException if an I/O error occurs
126
public void Send(byte buf[], int siz) throws IOException
132
* Send an exact array of bytes to the backend - if the length
133
* has not been reached, send nulls until it has.
135
* @param buf the array of bytes to be sent
136
* @param off offset in the array to start sending from
137
* @param siz the number of bytes to be sent
138
* @exception IOException if an I/O error occurs
140
public void Send(byte buf[], int off, int siz) throws IOException
144
pg_output.write(buf, off, ((buf.length - off) < siz ? (buf.length - off) : siz));
145
if ((buf.length - off) < siz)
147
for (i = buf.length - off ; i < siz ; ++i)
155
* Receives a single character from the backend
157
* @return the character received
158
* @exception SQLException if an I/O Error returns
160
public int ReceiveChar() throws SQLException
168
throw new PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR);
170
catch (IOException e)
172
throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e);
178
* Receives an integer from the backend
180
* @param siz length of the integer in bytes
181
* @return the integer received from the backend
182
* @exception SQLException if an I/O error occurs
184
public int ReceiveInteger(int siz) throws SQLException
190
for (int i = 0 ; i < siz ; i++)
192
int b = pg_input.read();
195
throw new PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR);
196
n = n | (b << (8 * i)) ;
199
catch (IOException e)
201
throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e);
207
* Receives an integer from the backend
209
* @param siz length of the integer in bytes
210
* @return the integer received from the backend
211
* @exception SQLException if an I/O error occurs
213
public int ReceiveIntegerR(int siz) throws SQLException
219
for (int i = 0 ; i < siz ; i++)
221
int b = pg_input.read();
224
throw new PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR);
228
catch (IOException e)
230
throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e);
236
* Receives a null-terminated string from the backend. If we don't see a
237
* null, then we assume something has gone wrong.
239
* @param encoding the charset encoding to use.
240
* @return string from back end
241
* @exception SQLException if an I/O error occurs, or end of file
243
public String ReceiveString(Encoding encoding)
247
byte[] rst = byte_buf;
250
int buflen = rst.length;
251
boolean done = false;
256
int c = pg_input.read();
258
throw new PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR);
271
buflen = (int)(buflen * 2); // 100% bigger
272
byte[] newrst = new byte[buflen];
273
System.arraycopy(rst, 0, newrst, 0, s);
279
catch (IOException e)
281
throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e);
283
return encoding.decode(rst, 0, s);
287
* Read a tuple from the back end. A tuple is a two dimensional
290
* @param nf the number of fields expected
291
* @return null if the current response has no more tuples, otherwise
292
* an array of strings
293
* @exception SQLException if a data I/O error occurs
295
public byte[][] ReceiveTupleV3(int nf) throws SQLException
297
//TODO: use l_msgSize
298
int l_msgSize = ReceiveIntegerR(4);
300
int l_nf = ReceiveIntegerR(2);
301
byte[][] answer = new byte[l_nf][0];
303
for (i = 0 ; i < l_nf ; ++i)
305
int l_size = ReceiveIntegerR(4);
306
boolean isNull = l_size == -1;
311
answer[i] = Receive(l_size);
318
* Read a tuple from the back end. A tuple is a two dimensional
321
* @param nf the number of fields expected
322
* @param bin true if the tuple is a binary tuple
323
* @return null if the current response has no more tuples, otherwise
324
* an array of strings
325
* @exception SQLException if a data I/O error occurs
327
public byte[][] ReceiveTupleV2(int nf, boolean bin) throws SQLException
329
int i, bim = (nf + 7) / 8;
330
byte[] bitmask = Receive(bim);
331
byte[][] answer = new byte[nf][0];
336
for (i = 0 ; i < nf ; ++i)
338
boolean isNull = ((bitmask[whichbyte] & whichbit) == 0);
349
int len = ReceiveIntegerR(4);
354
answer[i] = Receive(len);
361
* Reads in a given number of bytes from the backend
363
* @param siz number of bytes to read
364
* @return array of bytes received
365
* @exception SQLException if a data I/O error occurs
367
public byte[] Receive(int siz) throws SQLException
369
byte[] answer = new byte[siz];
370
Receive(answer, 0, siz);
375
* Reads in a given number of bytes from the backend
377
* @param buf buffer to store result
378
* @param off offset in buffer
379
* @param siz number of bytes to read
380
* @exception SQLException if a data I/O error occurs
382
public void Receive(byte[] b, int off, int siz) throws SQLException
390
int w = pg_input.read(b, off + s, siz - s);
392
throw new PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR);
396
catch (IOException e)
398
throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e);
403
* This flushes any pending output to the backend. It is used primarily
404
* by the Fastpath code.
405
* @exception SQLException if an I/O error occurs
407
public void flush() throws SQLException
413
catch (IOException e)
415
throw new PSQLException("postgresql.stream.flush", PSQLState.COMMUNICATION_ERROR, e);
420
* Closes the connection
422
* @exception IOException if a IO Error occurs
424
public void close() throws IOException