class TransferConnection extends AsyncConnection {

    private static final Logger logger = LoggerFactory.getLogger(TransferConnection.class);

    protected final ByteBuffer packetLengthByteBuffer = ByteBuffer
            .allocate(getPacketLengthByteBufferCapacity());

    public TransferConnection(WritableChannel writableChannel, boolean isServer) {
        super(writableChannel, isServer);
    }

    public DataBufferFactory getDataBufferFactory() {
        return writableChannel.getDataBufferFactory();
    }

    public int getPacketLengthByteBufferCapacity() {
        return 4;
    }

    @Override
    public ByteBuffer getPacketLengthByteBuffer() {
        return packetLengthByteBuffer;
    }

    @Override
    public int getPacketLength() {
        return packetLengthByteBuffer.getInt();
    }

    public TransferOutputStream createTransferOutputStream(Session session) {
        return new TransferOutputStream(session, writableChannel, getDataBufferFactory());
    }

    protected void handleRequest(TransferInputStream in, int packetId, int packetType)
            throws IOException {
        throw DbException.getInternalError("handleRequest");
    }

    protected void handleResponse(TransferInputStream in, int packetId, int status) throws IOException {
        throw DbException.getInternalError("handleResponse");
    }

    protected void addAsyncCallback(int packetId, AsyncCallback<?> ac) {
        throw DbException.getInternalError("addAsyncCallback");
    }

    protected static DbException parseError(TransferInputStream in) {<FILL_FUNCTION_BODY>}

    public void sendError(Session session, int packetId, Throwable t) {
        try {
            SQLException e = DbException.convert(t).getSQLException();
            StringWriter writer = new StringWriter();
            e.printStackTrace(new PrintWriter(writer));
            String trace = writer.toString();
            String message;
            String sql;
            if (e instanceof JdbcSQLException) {
                JdbcSQLException j = (JdbcSQLException) e;
                message = j.getOriginalMessage();
                sql = j.getSQL();
            } else {
                message = e.getMessage();
                sql = null;
            }
            TransferOutputStream out = createTransferOutputStream(session);
            out.writeResponseHeader(packetId, Session.STATUS_ERROR);
            out.writeString(e.getSQLState()).writeString(message).writeString(sql)
                    .writeInt(e.getErrorCode()).writeString(trace).flush();
        } catch (Exception e2) {
            if (session != null)
                session.close();
            else if (writableChannel != null) {
                writableChannel.close();
            }
            logger.error("Failed to send error", e2);
        }
    }

    @Override
    public void handle(NetBuffer buffer) {
        if (!buffer.isOnlyOnePacket()) {
            DbException.throwInternalError("NetBuffer must be OnlyOnePacket");
        }
        try {
            TransferInputStream in = new TransferInputStream(buffer);
            boolean isRequest = in.readByte() == TransferOutputStream.REQUEST;
            int packetId = in.readInt();
            if (isRequest) {
                int packetType = in.readInt();
                handleRequest(in, packetId, packetType);
            } else {
                int status = in.readInt();
                handleResponse(in, packetId, status);
            }
        } catch (Throwable e) {
            if (isServer)
                logger.error("Failed to handle packet", e);
            else
                throw DbException.convert(e);
        }
    }
}

        Throwable t;
        try {
            String sqlState = in.readString();
            String message = in.readString();
            String sql = in.readString();
            int errorCode = in.readInt();
            String stackTrace = in.readString();
            JdbcSQLException s = new JdbcSQLException(message, sql, sqlState, errorCode, null,
                    stackTrace);
            t = s;
            if (errorCode == ErrorCode.CONNECTION_BROKEN_1) {
                IOException e = new IOException(s.toString());
                e.initCause(s);
                t = e;
            }
        } catch (Exception e) {
            t = e;
        }
        return DbException.convert(t);
    
<methods>public void <init>(com.lealone.net.WritableChannel, boolean) ,public void checkClosed() ,public void checkTimeout(long) ,public void close() ,public java.lang.String getHostAndPort() ,public java.net.InetSocketAddress getInetSocketAddress() ,public int getMaxSharedSize() ,public abstract int getPacketLength() ,public abstract java.nio.ByteBuffer getPacketLengthByteBuffer() ,public int getSharedSize() ,public com.lealone.net.WritableChannel getWritableChannel() ,public abstract void handle(com.lealone.net.NetBuffer) ,public void handleException(java.lang.Exception) ,public boolean isClosed() ,public boolean isServer() ,public boolean isShared() ,public void setInetSocketAddress(java.net.InetSocketAddress) <variables>protected boolean closed,protected java.net.InetSocketAddress inetSocketAddress,protected final non-sealed boolean isServer,protected final non-sealed com.lealone.net.WritableChannel writableChannel