java nio ByteBufferAsCharBufferB/L原始碼分析

xushiyu1996818發表於2020-12-02

目錄

簡介

ByteBufferAsCharBufferB

ByteBufferAsCharBufferL


簡介

ByteBufferAsCharBufferB,內部含有一個ByteBuffer和offset。

進行get和put操作時,呼叫ix(position),ix方法返回的是(i << 1) + offset,對應了ByteBuffer裡對應的索引。操作時,呼叫Bits.get/putCharB,從而進行操作。

ByteBufferAsCharBufferB和ByteBufferAsCharBufferL的區別是,一個呼叫Bits.get/putCharB,一個呼叫Bits.get/putCharL

ByteBufferAsCharBufferB


package java.nio;

class ByteBufferAsCharBufferB // package-private
		extends CharBuffer {

	protected final ByteBuffer bb;
	protected final int offset;

	ByteBufferAsCharBufferB(ByteBuffer bb) { // package-private

		super(-1, 0, bb.remaining() >> 1, bb.remaining() >> 1);
		this.bb = bb;
		// enforce limit == capacity
		int cap = this.capacity();
		this.limit(cap);
		int pos = this.position();
		assert (pos <= cap);
		offset = pos;

	}

	ByteBufferAsCharBufferB(ByteBuffer bb, int mark, int pos, int lim, int cap, int off) {

		super(mark, pos, lim, cap);
		this.bb = bb;
		offset = off;

	}

	public CharBuffer slice() {
		int pos = this.position();
		int lim = this.limit();
		assert (pos <= lim);
		int rem = (pos <= lim ? lim - pos : 0);
		int off = (pos << 1) + offset;
		assert (off >= 0);
		return new ByteBufferAsCharBufferB(bb, -1, 0, rem, rem, off);
	}

	public CharBuffer duplicate() {
		return new ByteBufferAsCharBufferB(bb, this.markValue(), this.position(), this.limit(), this.capacity(),
				offset);
	}

	public CharBuffer asReadOnlyBuffer() {

		return new ByteBufferAsCharBufferRB(bb, this.markValue(), this.position(), this.limit(), this.capacity(),
				offset);

	}

	protected int ix(int i) {
		return (i << 1) + offset;
	}

	public char get() {
		return Bits.getCharB(bb, ix(nextGetIndex()));
	}

	public char get(int i) {
		return Bits.getCharB(bb, ix(checkIndex(i)));
	}

	char getUnchecked(int i) {
		return Bits.getCharB(bb, ix(i));
	}

	public CharBuffer put(char x) {

		Bits.putCharB(bb, ix(nextPutIndex()), x);
		return this;

	}

	public CharBuffer put(int i, char x) {

		Bits.putCharB(bb, ix(checkIndex(i)), x);
		return this;

	}

	public CharBuffer compact() {

		int pos = position();
		int lim = limit();
		assert (pos <= lim);
		int rem = (pos <= lim ? lim - pos : 0);

		ByteBuffer db = bb.duplicate();
		db.limit(ix(lim));
		db.position(ix(0));
		ByteBuffer sb = db.slice();
		sb.position(pos << 1);
		sb.compact();
		position(rem);
		limit(capacity());
		discardMark();
		return this;

	}

	public boolean isDirect() {
		return bb.isDirect();
	}

	public boolean isReadOnly() {
		return false;
	}

	public String toString(int start, int end) {
		if ((end > limit()) || (start > end))
			throw new IndexOutOfBoundsException();
		try {
			int len = end - start;
			char[] ca = new char[len];
			CharBuffer cb = CharBuffer.wrap(ca);
			CharBuffer db = this.duplicate();
			db.position(start);
			db.limit(end);
			cb.put(db);
			return new String(ca);
		} catch (StringIndexOutOfBoundsException x) {
			throw new IndexOutOfBoundsException();
		}
	}

	// --- Methods to support CharSequence ---

	public CharBuffer subSequence(int start, int end) {
		int pos = position();
		int lim = limit();
		assert (pos <= lim);
		pos = (pos <= lim ? pos : lim);
		int len = lim - pos;

		if ((start < 0) || (end > len) || (start > end))
			throw new IndexOutOfBoundsException();
		return new ByteBufferAsCharBufferB(bb, -1, pos + start, pos + end, capacity(), offset);
	}

	public ByteOrder order() {

		return ByteOrder.BIG_ENDIAN;

	}

}

ByteBufferAsCharBufferL


package java.nio;

class ByteBufferAsCharBufferL // package-private
		extends CharBuffer {

	protected final ByteBuffer bb;
	protected final int offset;

	ByteBufferAsCharBufferL(ByteBuffer bb) { // package-private

		super(-1, 0, bb.remaining() >> 1, bb.remaining() >> 1);
		this.bb = bb;
		// enforce limit == capacity
		int cap = this.capacity();
		this.limit(cap);
		int pos = this.position();
		assert (pos <= cap);
		offset = pos;

	}

	ByteBufferAsCharBufferL(ByteBuffer bb, int mark, int pos, int lim, int cap, int off) {

		super(mark, pos, lim, cap);
		this.bb = bb;
		offset = off;

	}

	public CharBuffer slice() {
		int pos = this.position();
		int lim = this.limit();
		assert (pos <= lim);
		int rem = (pos <= lim ? lim - pos : 0);
		int off = (pos << 1) + offset;
		assert (off >= 0);
		return new ByteBufferAsCharBufferL(bb, -1, 0, rem, rem, off);
	}

	public CharBuffer duplicate() {
		return new ByteBufferAsCharBufferL(bb, this.markValue(), this.position(), this.limit(), this.capacity(),
				offset);
	}

	public CharBuffer asReadOnlyBuffer() {

		return new ByteBufferAsCharBufferRL(bb, this.markValue(), this.position(), this.limit(), this.capacity(),
				offset);

	}

	protected int ix(int i) {
		return (i << 1) + offset;
	}

	public char get() {
		return Bits.getCharL(bb, ix(nextGetIndex()));
	}

	public char get(int i) {
		return Bits.getCharL(bb, ix(checkIndex(i)));
	}

	char getUnchecked(int i) {
		return Bits.getCharL(bb, ix(i));
	}

	public CharBuffer put(char x) {

		Bits.putCharL(bb, ix(nextPutIndex()), x);
		return this;

	}

	public CharBuffer put(int i, char x) {

		Bits.putCharL(bb, ix(checkIndex(i)), x);
		return this;

	}

	public CharBuffer compact() {

		int pos = position();
		int lim = limit();
		assert (pos <= lim);
		int rem = (pos <= lim ? lim - pos : 0);

		ByteBuffer db = bb.duplicate();
		db.limit(ix(lim));
		db.position(ix(0));
		ByteBuffer sb = db.slice();
		sb.position(pos << 1);
		sb.compact();
		position(rem);
		limit(capacity());
		discardMark();
		return this;

	}

	public boolean isDirect() {
		return bb.isDirect();
	}

	public boolean isReadOnly() {
		return false;
	}

	public String toString(int start, int end) {
		if ((end > limit()) || (start > end))
			throw new IndexOutOfBoundsException();
		try {
			int len = end - start;
			char[] ca = new char[len];
			CharBuffer cb = CharBuffer.wrap(ca);
			CharBuffer db = this.duplicate();
			db.position(start);
			db.limit(end);
			cb.put(db);
			return new String(ca);
		} catch (StringIndexOutOfBoundsException x) {
			throw new IndexOutOfBoundsException();
		}
	}

	// --- Methods to support CharSequence ---

	public CharBuffer subSequence(int start, int end) {
		int pos = position();
		int lim = limit();
		assert (pos <= lim);
		pos = (pos <= lim ? pos : lim);
		int len = lim - pos;

		if ((start < 0) || (end > len) || (start > end))
			throw new IndexOutOfBoundsException();
		return new ByteBufferAsCharBufferL(bb, -1, pos + start, pos + end, capacity(), offset);
	}

	public ByteOrder order() {

		return ByteOrder.LITTLE_ENDIAN;

	}

}

 

相關文章