public static void rawReadData(@NotNull WireIn wireIn, @NotNull ReadMarshallable dataConsumer) {
    final Bytes<?> bytes = wireIn.bytes();
    int header = bytes.readInt();
    assert Wires.isReady(header) && Wires.isData(header);
    final int len = Wires.lengthOf(header);

    long limit0 = bytes.readLimit();
    long limit = bytes.readPosition() + (long) len;
    try {
      bytes.readLimit(limit);
      dataConsumer.readMarshallable(wireIn);
    } finally {
      bytes.readLimit(limit0);
    }
  }
  public static boolean readData(
      @NotNull WireIn wireIn,
      @Nullable ReadMarshallable metaDataConsumer,
      @Nullable ReadMarshallable dataConsumer) {
    final Bytes<?> bytes = wireIn.bytes();
    boolean read = false;
    while (bytes.readRemaining() >= 4) {
      long position = bytes.readPosition();
      int header = bytes.readVolatileInt(position);
      if (!isKnownLength(header)) return read;
      bytes.readSkip(4);
      final boolean ready = Wires.isReady(header);
      final int len = Wires.lengthOf(header);
      if (Wires.isData(header)) {
        if (dataConsumer == null) {
          return false;

        } else {
          ((InternalWireIn) wireIn).setReady(ready);
          bytes.readWithLength(len, b -> dataConsumer.readMarshallable(wireIn));
          return true;
        }
      } else {

        if (metaDataConsumer == null) {
          // skip the header
          bytes.readSkip(len);
        } else {
          // bytes.readWithLength(len, b -> metaDataConsumer.accept(wireIn));
          // inlined to avoid garbage
          if ((long) len > bytes.readRemaining()) throw new BufferUnderflowException();
          long limit0 = bytes.readLimit();
          long limit = bytes.readPosition() + (long) len;
          try {
            bytes.readLimit(limit);
            metaDataConsumer.readMarshallable(wireIn);
          } finally {
            bytes.readLimit(limit0);
            bytes.readPosition(limit);
          }
        }

        if (dataConsumer == null) return true;
        read = true;
      }
    }
    return read;
  }
  public static boolean readData(
      long offset,
      @NotNull WireIn wireIn,
      @Nullable ReadMarshallable metaDataConsumer,
      @Nullable ReadMarshallable dataConsumer) {
    final Bytes bytes = wireIn.bytes();

    long position = bytes.readPosition();
    long limit = bytes.readLimit();
    try {
      bytes.readLimit(bytes.isElastic() ? bytes.capacity() : bytes.realCapacity());
      bytes.readPosition(offset);
      return readData(wireIn, metaDataConsumer, dataConsumer);
    } finally {
      bytes.readLimit(limit);
      bytes.readPosition(position);
    }
  }