@Override public ByteBuf translateFrame(ByteBuf readBuffer) throws LimitExedeedException, InvalidDataException { while (readBuffer.isReadable()) { switch (status) { case STATUS_H: h = readBuffer.readByte(); status = STATUS_L; break; case STATUS_L: l = readBuffer.readByte(); final int blen = Protocol.order == ByteOrder.BIG_ENDIAN ? (0x0000ff00 & (h << 8)) | (0x000000ff & l) : (0x0000ff00 & (l << 8)) | (0x000000ff & h); if (context != null) { if (blen <= 0 || blen > maxFrameSize) { throw new LimitExedeedException("帧长度非法:" + h + "/" + l + ":" + blen); } } incompleteframe = PooledByteBufAllocator.DEFAULT.buffer(blen + 16 + 2); incompleteframe = incompleteframe.order(Protocol.order); incompleteframe.writeShort(blen); status = STATUS_C; break; case STATUS_C: int len = incompleteframe.writableBytes() - 16; len = len < readBuffer.readableBytes() ? len : readBuffer.readableBytes(); // incompleteframe.writeBytes(readBuffer, len); if (readBuffer.hasMemoryAddress()) { PlatformDependent.copyMemory( readBuffer.memoryAddress() + readBuffer.readerIndex(), incompleteframe.memoryAddress() + incompleteframe.writerIndex(), len); } else if (readBuffer.hasArray()) { PlatformDependent.copyMemory( readBuffer.array(), readBuffer.arrayOffset() + readBuffer.readerIndex(), incompleteframe.memoryAddress() + incompleteframe.writerIndex(), len); } incompleteframe.writerIndex(incompleteframe.writerIndex() + len); readBuffer.readerIndex(readBuffer.readerIndex() + len); if ((incompleteframe.writableBytes() - 16) <= 0) { status = STATUS_H; return incompleteframe; } break; } } return null; }
/** Read bytes into the given {@link ByteBuf} and return the amount. */ private int doReadBytes(ByteBuf byteBuf) throws Exception { int writerIndex = byteBuf.writerIndex(); int localReadAmount; if (byteBuf.hasMemoryAddress()) { localReadAmount = Native.readAddress(fd, byteBuf.memoryAddress(), writerIndex, byteBuf.capacity()); } else { ByteBuffer buf = byteBuf.internalNioBuffer(writerIndex, byteBuf.writableBytes()); localReadAmount = Native.read(fd, buf, buf.position(), buf.limit()); } if (localReadAmount > 0) { byteBuf.writerIndex(writerIndex + localReadAmount); } return localReadAmount; }
/** * Write bytes form the given {@link ByteBuf} to the underlying {@link java.nio.channels.Channel}. * * @param buf the {@link ByteBuf} from which the bytes should be written * @return amount the amount of written bytes */ private int doWriteBytes(ByteBuf buf, int readable) throws Exception { int readerIndex = buf.readerIndex(); int localFlushedAmount; if (buf.nioBufferCount() == 1) { if (buf.hasMemoryAddress()) { localFlushedAmount = Native.writeAddress(fd, buf.memoryAddress(), readerIndex, buf.writerIndex()); } else { ByteBuffer nioBuf = buf.internalNioBuffer(readerIndex, readable); localFlushedAmount = Native.write(fd, nioBuf, nioBuf.position(), nioBuf.limit()); } } else { // backed by more then one buffer, do a gathering write... ByteBuffer[] nioBufs = buf.nioBuffers(); localFlushedAmount = (int) Native.writev(fd, nioBufs, 0, nioBufs.length); } if (localFlushedAmount > 0) { buf.readerIndex(readerIndex + localFlushedAmount); } return localFlushedAmount; }
@Override public boolean hasMemoryAddress() { return buf.hasMemoryAddress(); }