@Override
  public int read(ByteBuffer dst) throws IOException {
    if (mClosed) {
      throw new ClosedChannelException();
    }
    int maxReadable = dst.remaining();
    int position = dst.position();
    synchronized (this) {
      ByteBuf buf = Unpooled.wrappedBuffer(dst);
      buf.writerIndex(0);
      int bytesRead = mReader.transferTo(buf);
      Preconditions.checkState(bytesRead <= maxReadable, "buffer overflow");
      if (bytesRead > 0) {
        dst.position(position + bytesRead);
      }
      return bytesRead;
    }
  }
@Test
  public void read() throws Exception {
    int headerSize = 1;
    int trailerSize = 1;
    ByteBuffer buffer = ByteBuffer.allocate(DATA_SIZE + headerSize + trailerSize);
    buffer.clear();
    buffer.put((byte) 0x42); // fill with some data so that the position starts with non-zero
    assertEquals(DATA_SIZE, IOUtils.read(mChannel, buffer));
    assertEquals(headerSize + DATA_SIZE, buffer.position());
    buffer.flip();
    assertEquals((byte) 0x42, buffer.get());
    assertTrue(BufferUtils.equalIncreasingByteBuffer(0, DATA_SIZE, buffer.slice()));
  }