Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.runescape.net;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.Socket;
- import com.runescape.GameShell;
- /**
- *
- * @author Ryan Greene
- *
- */
- public class BufferedConnection implements Runnable {
- /**
- * The input stream.
- */
- public InputStream inputStream;
- /**
- * The output stream.
- */
- public OutputStream outputStream;
- /**
- * The socket.
- */
- public Socket socket;
- /**
- * The closing flag.
- */
- public boolean closing;
- /**
- * The game shell.
- */
- public GameShell gameShell;
- /**
- * The buffer.
- */
- public byte buffer[];
- /**
- * The t cycle.
- */
- public int tcycl;
- /**
- * The t number.
- */
- public int tnum;
- /**
- * The writer flag.
- */
- public boolean writer;
- /**
- * The writing flag.
- */
- public boolean writing;
- /**
- * Creates a new buffered connection with the specified socket and game
- * shell.
- *
- * @param socket
- * The socket.
- * @param gameShell
- * The game shell.
- * @throws IOException
- * If an I/O error occurs.
- */
- public BufferedConnection(Socket socket, GameShell gameShell)
- throws IOException {
- closing = false;
- writer = false;
- writing = false;
- this.gameShell = gameShell;
- this.socket = socket;
- this.socket.setSoTimeout(30000);
- this.socket.setTcpNoDelay(true);
- inputStream = socket.getInputStream();
- outputStream = socket.getOutputStream();
- }
- /**
- * Closes this buffered connection and releases any system resources
- * associated with the stream.
- */
- public void close() {
- closing = true;
- try {
- if (inputStream != null) {
- inputStream.close();
- }
- if (outputStream != null) {
- outputStream.close();
- }
- if (socket != null) {
- socket.close();
- }
- } catch (IOException e) {
- System.out.println("Error closing stream");
- }
- writer = false;
- synchronized (this) {
- notify();
- }
- buffer = null;
- }
- /**
- * Reads the next byte of data from the input stream. The value byte is
- * returned as an int in the range 0 to 255. If no byte is available because
- * the end of the stream has been reached, the value -1 is returned. This
- * method blocks until input data is available, the end of the stream is
- * detected, or an exception is thrown. A subclass must provide an
- * implementation of this method.
- *
- * @return The next byte of data, or -1 if the end of the stream is reached.
- * @throws IOException
- * If an I/O error occurs.
- */
- public int read() throws IOException {
- if (closing) {
- return 0;
- } else {
- return inputStream.read();
- }
- }
- /**
- * Returns an estimate of the number of bytes that can be read (or skipped
- * over) from this input stream without blocking by the next invocation of a
- * method for this input stream. The next invocation might be the same
- * thread or another thread. A single read or skip of this many bytes will
- * not block, but may read or skip fewer bytes. Note that while some
- * implementations of InputStream will return the total number of bytes in
- * the stream, many will not. It is never correct to use the return value of
- * this method to allocate a buffer intended to hold all data in this
- * stream.
- *
- * A subclass' implementation of this method may choose to throw an
- * IOException if this input stream has been closed by invoking the close()
- * method.
- *
- * The available method for class InputStream always returns 0.
- *
- * This method should be overridden by subclasses.
- *
- * @return an estimate of the number of bytes that can be read (or skipped
- * over) from this input stream without blocking or 0 when it
- * reaches the end of the input stream.
- * @throws IOException
- * If an I/O error occurs.
- */
- public int available() throws IOException {
- if (closing) {
- return 0;
- } else {
- return inputStream.available();
- }
- }
- /**
- * Reads up to len bytes of data from the input stream into an array of
- * bytes. An attempt is made to read as many as length bytes, but a smaller
- * number may be read. The number of bytes actually read is returned as an
- * integer.
- *
- * @param src
- * The buffer into which the data is read.
- * @param offset
- * The start offset in array b at which the data is written.
- * @param length
- * The maximum number of bytes to read.
- * @throws IOException
- * If an I/O error occurs.
- */
- public void read(byte src[], int offset, int length) throws IOException {
- if (closing) {
- return;
- }
- int bytes;
- for (; length > 0; length -= bytes) {
- bytes = inputStream.read(src, offset, length);
- if (bytes <= 0) {
- throw new IOException("EOF");
- }
- offset += bytes;
- }
- }
- /**
- * Writes length bytes from the specified byte array starting at offset off
- * to this output stream. The general contract for write(src, offset,
- * length) is that some of the bytes in the array b are written to the
- * output stream in order; element src[offset] is the first byte written and
- * b[offset+length-1] is the last byte written by this operation. The write
- * method of OutputStream calls the write method of one argument on each of
- * the bytes to be written out. Subclasses are encouraged to override this
- * method and provide a more efficient implementation.
- *
- * If src is null, a NullPointerException is thrown.
- *
- * If offset is negative, or length is negative, or offset+length is greater
- * than the length of the array src, then an IndexOutOfBoundsException is
- * thrown.
- *
- * @param src
- * The data.
- * @param offset
- * The start offset in the data.
- * @param length
- * The number of bytes to write.
- * @throws IOException
- * If an I/O error occurs.
- */
- public void write(byte src[], int offset, int length) throws IOException {
- if (closing) {
- return;
- }
- if (writing) {
- writing = false;
- throw new IOException("Error in writer thread");
- }
- if (buffer == null) {
- buffer = new byte[5000];
- }
- synchronized (this) {
- for (int pointer = 0; pointer < offset; pointer++) {
- buffer[tnum] = src[pointer + length];
- tnum = (tnum + 1) % 5000;
- if (tnum == (tcycl + 4900) % 5000) {
- throw new IOException("buffer overflow");
- }
- }
- if (!writer) {
- writer = true;
- gameShell.method12(this, 3);
- }
- notify();
- }
- }
- @Override
- public void run() {
- while (writer) {
- int length;
- int offset;
- synchronized (this) {
- if (tnum == tcycl) {
- try {
- wait();
- } catch (InterruptedException e) {
- }
- }
- if (!writer) {
- return;
- }
- offset = tcycl;
- if (tnum >= tcycl) {
- length = tnum - tcycl;
- } else {
- length = 5000 - tcycl;
- }
- }
- if (length > 0) {
- try {
- outputStream.write(buffer, offset, length);
- } catch (IOException e) {
- writing = true;
- }
- tcycl = (tcycl + length) % 5000;
- try {
- if (tnum == tcycl) {
- outputStream.flush();
- }
- } catch (IOException e) {
- writing = true;
- }
- }
- }
- }
- /**
- * Dumps information related to the buffered connection.
- */
- public void dump() {
- try {
- System.out.println("dummy:" + closing);
- System.out.println("tcycl:" + tcycl);
- System.out.println("tnum:" + tnum);
- System.out.println("writer:" + writer);
- System.out.println("ioerror:" + writing);
- System.out.println("available:" + available());
- } catch (IOException e) {
- return;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement