pgstream.java
来自「PostgreSQL7.4.6 for Linux」· Java 代码 · 共 431 行
JAVA
431 行
/*------------------------------------------------------------------------- * * PGStream.java * This class is used by Connection for communicating with the * backend. * * Copyright (c) 2003, PostgreSQL Global Development Group * * IDENTIFICATION * $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 $ * *------------------------------------------------------------------------- */package org.postgresql.core;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.InputStream;import java.io.IOException;import java.net.Socket;import java.sql.*;import org.postgresql.util.PSQLException;import org.postgresql.util.PSQLState;public class PGStream{ public String host; public int port; public Socket connection; public InputStream pg_input; public BufferedOutputStream pg_output; private byte[] byte_buf = new byte[8*1024]; /* * 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 PGStream(String p_host, int p_port) throws IOException { host = p_host; port = p_port; connection = new Socket(host, port); // Submitted by Jason Venner <jason@idiom.com> adds a 10x speed // improvement on FreeBSD machines (caused by a bug in their TCP Stack) connection.setTcpNoDelay(true); // Buffer sizes submitted by Sverre H Huseby <sverrehu@online.no> pg_input = new BufferedInputStream(connection.getInputStream(), 8192); pg_output = new BufferedOutputStream(connection.getOutputStream(), 8192); } /* * 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((byte)val); } /* * 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); } /* * 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 SendIntegerR(int val, int siz) throws IOException { byte[] buf = new byte[siz]; for (int i = 0; i < siz; i++) { buf[i] = (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 PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR); } catch (IOException e) { throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e); } 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 PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR); n = n | (b << (8 * i)) ; } } catch (IOException e) { throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e); } return n; } /* * 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 ReceiveIntegerR(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 PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR); n = b | (n << 8); } } catch (IOException e) { throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e); } return n; } /* * Receives a null-terminated string from the backend. If we don't see a * null, then we assume something has gone wrong. * * @param encoding the charset encoding to use. * @return string from back end * @exception SQLException if an I/O error occurs, or end of file */ public String ReceiveString(Encoding encoding) throws SQLException { int s = 0; byte[] rst = byte_buf; try { int buflen = rst.length; boolean done = false; while (!done) { while (s < buflen) { int c = pg_input.read(); if (c < 0) throw new PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR); else if (c == 0) { rst[s] = 0; done = true; break; } else { rst[s++] = (byte)c; } if (s >= buflen) { // Grow the buffer buflen = (int)(buflen * 2); // 100% bigger byte[] newrst = new byte[buflen]; System.arraycopy(rst, 0, newrst, 0, s); rst = newrst; } } } } catch (IOException e) { throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e); } return encoding.decode(rst, 0, s); } /* * Read a tuple from the back end. A tuple is a two dimensional * array of bytes * * @param nf the number of fields expected * @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[][] ReceiveTupleV3(int nf) throws SQLException { //TODO: use l_msgSize int l_msgSize = ReceiveIntegerR(4); int i; int l_nf = ReceiveIntegerR(2); byte[][] answer = new byte[l_nf][0]; for (i = 0 ; i < l_nf ; ++i) { int l_size = ReceiveIntegerR(4); boolean isNull = l_size == -1; if (isNull) answer[i] = null; else { answer[i] = Receive(l_size); } } return answer; } /* * 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[][] ReceiveTupleV2(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 = ReceiveIntegerR(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 */ public byte[] Receive(int siz) throws SQLException { byte[] answer = new byte[siz]; Receive(answer, 0, siz); 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 PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR); s += w; } } catch (IOException e) { throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e); } } /* * This flushes any pending output to the backend. It is used primarily * by the Fastpath code. * @exception SQLException if an I/O error occurs */ public void flush() throws SQLException { try { pg_output.flush(); } catch (IOException e) { throw new PSQLException("postgresql.stream.flush", PSQLState.COMMUNICATION_ERROR, e); } } /* * Closes the connection * * @exception IOException if a IO Error occurs */ public void close() throws IOException { pg_output.close(); pg_input.close(); connection.close(); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?