package me.xcoding.opencdc.net.connector; import java.io.IOException; import java.io.InputStream; import me.xcoding.opencdc.mysql.protocol.ReadablePacket; import me.xcoding.opencdc.net.packet.generic.EOFPacket; import me.xcoding.opencdc.net.packet.generic.ErrPacket; import me.xcoding.opencdc.net.packet.generic.GenericPacket; import me.xcoding.opencdc.net.packet.generic.OKPacket; /** * FIXME * If a MySQL client or server wants to send data, it: </br> * Splits the data into packets of size (224–1) bytes</br> * Prepends to each chunk a packet header</br> * * @author Teny Zh * @see http://dev.mysql.com/doc/internals/en/overview.html */ public class SocketReader extends ReadablePacket { private final InputStream in; private int limit = 0; private int head = 0, tail = 0; private static final int bufferSize = 8192 << 2; public SocketReader(InputStream in) { super(8192 << 2); this.in = in; this.end = 0; } /** * Binlog Network Stream * @return * @throws IOException */ public ReadablePacket buildPacket() throws IOException { if(end >= tail) { hasMore(); } offset = end; int length = this.readFixedIntT3(); // int sequenceId = this.readFixedIntT1(); end = offset + length; return this; } public GenericPacket getResponsePacket() throws IOException { if(end >= tail) { hasMore(); } offset = end; int length = this.readFixedIntT3(); // int sequenceId = this.readFixedIntT1(); end = offset + length; int header = this.readFixedIntT1(); switch(header) { case 0x0000 : { // OKPacket OKPacket packet = OKPacket.parser(this); return packet; } case 0x00FE : { // EOFPacket EOFPacket packet = EOFPacket.parser(this); return packet; } case 0x00FF : { // ERRPacket ErrPacket packet = ErrPacket.parser(this); return packet; } default : { // throw new xxExcpetion(); } } return null; } public void setLimit(int length) { limit = length + offset; } @Override public boolean hasMore() throws IOException { if(bufferSize - tail < 8192) { System.arraycopy(buffer, offset, buffer, 0, (tail = tail - end)); end = 0; offset = 0; } tail += in.read(buffer, tail, 8192); offset = end; return (tail > head); } @Override public boolean hasNext() { if(offset >= tail) try { return hasMore(); } catch (IOException e) { } return true; } public void position(int position) { this.offset = position; } @Override public int read() throws IOException { return 0; } }