/** * Compares the two specified buffers as described in {@link * ChannelBuffer#compareTo(ChannelBuffer)}. This method is useful when implementing a new buffer * type. */ public static int compare(ChannelBuffer bufferA, ChannelBuffer bufferB) { final int aLen = bufferA.readableBytes(); final int bLen = bufferB.readableBytes(); final int minLength = Math.min(aLen, bLen); final int uintCount = minLength >>> 2; final int byteCount = minLength & 3; int aIndex = bufferA.readerIndex(); int bIndex = bufferB.readerIndex(); if (bufferA.order() == bufferB.order()) { for (int i = uintCount; i > 0; i--) { long va = bufferA.getUnsignedInt(aIndex); long vb = bufferB.getUnsignedInt(bIndex); if (va > vb) { return 1; } else if (va < vb) { return -1; } aIndex += 4; bIndex += 4; } } else { for (int i = uintCount; i > 0; i--) { long va = bufferA.getUnsignedInt(aIndex); long vb = swapInt(bufferB.getInt(bIndex)) & 0xFFFFFFFFL; if (va > vb) { return 1; } else if (va < vb) { return -1; } aIndex += 4; bIndex += 4; } } for (int i = byteCount; i > 0; i--) { short va = bufferA.getUnsignedByte(aIndex); short vb = bufferB.getUnsignedByte(bIndex); if (va > vb) { return 1; } else if (va < vb) { return -1; } aIndex++; bIndex++; } return aLen - bLen; }
/** * Calculates the hash code of the specified buffer. This method is useful when implementing a new * buffer type. */ public static int hashCode(ChannelBuffer buffer) { final int aLen = buffer.readableBytes(); final int intCount = aLen >>> 2; final int byteCount = aLen & 3; int hashCode = 1; int arrayIndex = buffer.readerIndex(); if (buffer.order() == BIG_ENDIAN) { for (int i = intCount; i > 0; i--) { hashCode = 31 * hashCode + buffer.getInt(arrayIndex); arrayIndex += 4; } } else { for (int i = intCount; i > 0; i--) { hashCode = 31 * hashCode + swapInt(buffer.getInt(arrayIndex)); arrayIndex += 4; } } for (int i = byteCount; i > 0; i--) { hashCode = 31 * hashCode + buffer.getByte(arrayIndex++); } if (hashCode == 0) { hashCode = 1; } return hashCode; }
/** * Returns {@code true} if and only if the two specified buffers are identical to each other as * described in {@code ChannelBuffer#equals(Object)}. This method is useful when implementing a * new buffer type. */ public static boolean equals(ChannelBuffer bufferA, ChannelBuffer bufferB) { final int aLen = bufferA.readableBytes(); if (aLen != bufferB.readableBytes()) { return false; } final int longCount = aLen >>> 3; final int byteCount = aLen & 7; int aIndex = bufferA.readerIndex(); int bIndex = bufferB.readerIndex(); if (bufferA.order() == bufferB.order()) { for (int i = longCount; i > 0; i--) { if (bufferA.getLong(aIndex) != bufferB.getLong(bIndex)) { return false; } aIndex += 8; bIndex += 8; } } else { for (int i = longCount; i > 0; i--) { if (bufferA.getLong(aIndex) != swapLong(bufferB.getLong(bIndex))) { return false; } aIndex += 8; bIndex += 8; } } for (int i = byteCount; i > 0; i--) { if (bufferA.getByte(aIndex) != bufferB.getByte(bIndex)) { return false; } aIndex++; bIndex++; } return true; }
/** * Creates a new composite buffer which wraps the readable bytes of the specified buffers without * copying them. A modification on the content of the specified buffers will be visible to the * returned buffer. * * @throws IllegalArgumentException if the specified buffers' endianness are different from each * other */ public static ChannelBuffer wrappedBuffer(ChannelBuffer... buffers) { switch (buffers.length) { case 0: break; case 1: if (buffers[0].readable()) { return wrappedBuffer(buffers[0]); } break; default: ByteOrder order = null; final List<ChannelBuffer> components = new ArrayList<ChannelBuffer>(buffers.length); for (ChannelBuffer c : buffers) { if (c == null) { break; } if (c.readable()) { if (order != null) { if (!order.equals(c.order())) { throw new IllegalArgumentException("inconsistent byte order"); } } else { order = c.order(); } if (c instanceof CompositeChannelBuffer) { // Expand nested composition. components.addAll( ((CompositeChannelBuffer) c).decompose(c.readerIndex(), c.readableBytes())); } else { // An ordinary buffer (non-composite) components.add(c.slice()); } } } return compositeBuffer(order, components); } return EMPTY_BUFFER; }
public ByteOrder order() { return buffer.order(); }