All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.code.or.net.impl.EventInputStream Maven / Gradle / Ivy

There is a newer version: 1.6.1-PRE2
Show newest version
package com.google.code.or.net.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.zip.CRC32;

import com.google.code.or.binlog.impl.event.BinlogEventV4HeaderImpl;
import com.google.code.or.common.util.MySQLConstants;
import com.google.code.or.io.CRCException;
import com.google.code.or.io.XInputStream;
import com.google.code.or.io.impl.XInputStreamImpl;
import com.google.code.or.net.Packet;
import com.google.code.or.net.TransportInputStream;
import com.google.code.or.net.impl.packet.EOFPacket;
import com.google.code.or.net.impl.packet.ErrorPacket;
import com.google.code.or.net.impl.packet.OKPacket;

public class EventInputStream extends XInputStreamImpl implements XInputStream {
	private final XInputStream dataStream;
	private boolean checksumEnabled = false;
	private CRC32 crc = null;

	public EventInputStream(XInputStream is) {
		super((InputStream) is);
		this.dataStream = is;
	}

	public BinlogEventV4HeaderImpl getNextBinlogHeader() throws IOException {
		final BinlogEventV4HeaderImpl header = new BinlogEventV4HeaderImpl();

		this.setReadLimit(0);

		if ( isChecksumEnabled() ) {
			crc = new CRC32();
		} else
			crc = null;


		header.setTimestamp(readLong(4) * 1000L);
		header.setEventType(readInt(1));
		header.setServerId(readLong(4));
		header.setEventLength(readInt(4));

		// setup the total event length; this is different than setReadLimit(),
		// as setReadLimit refers to *packet* length.
		long eventLimit = header.getEventLength() - 13;
		if ( isChecksumEnabled() && header.getEventType() != MySQLConstants.FORMAT_DESCRIPTION_EVENT )
			eventLimit -= 4;

		// TODO fixme re: int overflow
		this.setReadLimit((int) eventLimit);

		header.setNextPosition(readLong(4));
		header.setFlags(readInt(2));
		header.setTimestampOfReceipt(System.currentTimeMillis());

		return header;
	}

	public boolean isChecksumEnabled() {
		return checksumEnabled;
	}

	public void setChecksumEnabled(boolean checksumEnabled) {
		this.checksumEnabled = checksumEnabled;
	}



	public void finishEvent(BinlogEventV4HeaderImpl header) throws IOException {
		// Ensure the packet boundary
		if(this.available() != 0) {
			throw new RuntimeException("assertion failed!  We left " + this.available() +
					" unconsumed bytes in the buffer for event: " + header);
		}

		if ( isChecksumEnabled() && header.getEventType() != MySQLConstants.FORMAT_DESCRIPTION_EVENT) {
			long calculatedCRC = crc.getValue();
			this.setReadLimit(0);
			Long checksum = this.readLong(4);
			if ( checksum.longValue() != calculatedCRC ) {
				throw new CRCException(header);
			}
		}
	}

	@Override
	public long skip(final long n) throws IOException {
		if ( !isChecksumEnabled() ) {
			this.readCount += n;
			return dataStream.skip(n);
		} else {
			byte b[] = new byte[(int) n];
			// let read calculate the CRC
			read(b, 0, (int) n);
		}
		return n;

	}

	@Override
	public int read(final byte b[], int off, final int len) throws IOException {
		this.readCount += len;
		int ret = dataStream.read(b, off, len);

		if ( isChecksumEnabled() && crc != null ) {
			crc.update(b, off, len);
		}

		return ret;
	}

	@Override
	public int read() throws IOException {
		int b = dataStream.read();
		this.readCount++;
		if ( isChecksumEnabled() && crc != null )
			crc.update(b);

		return b;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy