Shift-And和Shift-Or ByteBuffer匹配器

两个ByteBuffer的匹配算法java实现,原作者 庄大侠,这边收藏下

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

/**
 * @description
 * @author <a href="[email protected]">junyu</a>
 * @date 2012-9-7下午04:05:05
 */
public class ShiftAndByteBufferMatcher {

	private int[] b;
	private final int mask;

	private final int patternLimit;
	private final int patternPos;
	private final int patternLen;

	public ShiftAndByteBufferMatcher(final ByteBuffer pat) {
		if (pat == null || pat.remaining() == 0) {
			throw new IllegalArgumentException("blank buffer");
		}
		this.patternLimit = pat.limit();
		this.patternPos = pat.position();
		this.patternLen = pat.remaining();
		this.preprocess(pat);
		this.mask = 1 << this.patternLen - 1;
	}

	/**
	 * 预处理
	 * 
	 * @param pat
	 */
	private void preprocess(final ByteBuffer pat) {
		this.b = new int[256];
		for (int i = this.patternPos; i < this.patternLimit; i++) {
			final int p = (pat.get(i)) & 0xFF;
			this.b[p] = this.b[p] | 1 << i;
		}
	}

	public final List<Integer> matchAll(final ByteBuffer buffer) {
		final List<Integer> matches = new ArrayList<Integer>();
		final int bufferLimit = buffer.limit();
		int d = 0;
		for (int pos = buffer.position(); pos < bufferLimit; pos++) {
			d <<= 1;
			d |= 1;
			d &= this.b[(buffer.get(pos)) & 0xFF];
			if ((d & this.mask) != 0) {
				matches.add(pos - this.patternLen + 1);
			}
		}
		return matches;
	}

	public final int matchFirst(final ByteBuffer buffer) {
		if (buffer == null) {
			return -1;
		}
		final int bufferLimit = buffer.limit();
		int d = 0;
		for (int pos = buffer.position(); pos < bufferLimit; pos++) {
			d <<= 1;
			d |= 1;
			d &= this.b[(buffer.get(pos)) & 0xFF];
			if ((d & this.mask) != 0) {
				return pos - this.patternLen + 1;
			}
		}
		return -1;
	}

}


import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

/**
 * @description
 * @author <a href="[email protected]">junyu</a>
 * @date 2012-9-7下午04:05:05
 */
public class ShiftOrByteBufferMatcher {

	private int[] b;
	private int lim;

	private final int patternLen;

	public ShiftOrByteBufferMatcher(final ByteBuffer pat) {
		if (pat == null || pat.remaining() == 0) {
			throw new IllegalArgumentException("blank buffer");
		}
		this.patternLen = pat.remaining();
		this.preprocess(pat);
	}

	/**
	 * 预处理
	 * 
	 * @param pat
	 */
	private void preprocess(final ByteBuffer pat) {
		this.b = new int[256];
		this.lim = 0;
		for (int i = 0; i < 256; i++) {
			this.b[i] = ~0;

		}
		for (int i = 0, j = 1; i < this.patternLen; i++, j <<= 1) {
			this.b[(pat.get(i)) & 0xFF] &= ~j;
			this.lim |= j;
		}
		this.lim = ~(this.lim >> 1);

	}

	public final List<Integer> matchAll(final ByteBuffer buffer) {
		final List<Integer> matches = new ArrayList<Integer>();
		final int bufferLimit = buffer.limit();
		int state = ~0;
		for (int pos = buffer.position(); pos < bufferLimit; pos++) {
			state <<= 1;
			state |= this.b[(buffer.get(pos)) & 0xFF];
			if (state < this.lim) {
				matches.add(pos - this.patternLen + 1);
			}
		}
		return matches;
	}

	public final int matchFirst(final ByteBuffer buffer) {
		if (buffer == null) {
			return -1;
		}
		final int bufferLimit = buffer.limit();
		int state = ~0;
		for (int pos = buffer.position(); pos < bufferLimit; pos++) {
			state = (state <<= 1) | this.b[(buffer.get(pos)) & 0xFF];
			if (state < this.lim) {
				return pos - this.patternLen + 1;
			}
		}
		return -1;
	}
}

你可能感兴趣的:(ByteBuffer)