/** Test we can create an Buffer, then modify the direct bytes in native code. */
  @Test
  public void testCanDirectlyModifyNativeBytes() {
    byte buffer[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    Buffer buf = Buffer.make(null, buffer, 0, buffer.length);
    assertNotNull(buf);
    assertEquals(buf.getBufferSize(), buffer.length);

    // this give us the native bytes
    java.nio.ByteBuffer nativeBytes = buf.getByteBuffer(0, buffer.length);
    assertNotNull(nativeBytes);
    for (int i = 0; i < buffer.length; i++) {
      nativeBytes.put(i, (byte) (9 - buffer[i])); // reverse the order of the integers
    }
    // we can release it.  no "update" method should be required.  It should
    // have modified the underlying C++ bytes.
    nativeBytes = null;

    // now, get a copy of the bytes in the Buffer and make sure
    // the order of bytes was reversed.
    byte outBuffer[] = buf.getByteArray(0, buffer.length);
    assertNotNull(outBuffer);
    assertEquals(outBuffer.length, buffer.length);
    assertNotSame(buf, outBuffer);
    for (int i = 0; i < buffer.length; i++) {
      assertEquals(9 - buffer[i], outBuffer[i]);
    }
  }
 /**
  * This method allocates one large Buffer and then repeatedly creates a java.nio.ByteBuffer to
  * access them
  *
  * <p>If the system is not leaking, the garbage collector will ensure we don't run out of heap
  * space. If we're leaking, bad things will occur.
  */
 @Test
 public void testNoLeakingMemoryOnDirectAccess() {
   Buffer buf = Buffer.make(null, 1024 * 1024); // 1 MB
   assertNotNull(buf);
   for (int i = 0; i < 100000; i++) {
     java.nio.ByteBuffer nativeBytes = buf.getByteBuffer(0, buf.getBufferSize());
     // and we do nothing with the outBytes
     assertEquals(nativeBytes.limit(), buf.getBufferSize());
     nativeBytes = null;
   }
 }
  /**
   * This test makes sure that Humble Video sets the byte order of the returned ByteBuffer to native
   * order
   */
  @Test
  public void testByteOrderIsCorrect() {
    Buffer buf = Buffer.make(null, 1024 * 1024); // 1 MB
    assertNotNull(buf);

    assertEquals(1, buf.getCurrentRefCount());

    java.nio.ByteBuffer jbuf = buf.getByteBuffer(0, buf.getBufferSize());
    assertNotNull(buf);

    // Set 4 bytes that have a pattern that is reversible.  On a big
    // endian machine this is FOO and on a little endian it's BAR
    jbuf.put(0, (byte) 0xFF);
    jbuf.put(1, (byte) 0);
    jbuf.put(2, (byte) 0xFF);
    jbuf.put(3, (byte) 0);

    int bigOrderVal = 0xFF00FF00;
    int littleOrderVal = 0x00FF00FF;
    int expectedVal;
    if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) expectedVal = bigOrderVal;
    else expectedVal = littleOrderVal;
    java.nio.IntBuffer ibuf = jbuf.asIntBuffer();
    assertNotNull(ibuf);

    int val = ibuf.get(0);
    assertEquals(expectedVal, val);

    // now let's try changing byte orders
    jbuf.order(ByteOrder.BIG_ENDIAN);
    ibuf = jbuf.asIntBuffer();
    assertNotNull(ibuf);

    val = ibuf.get(0);
    assertEquals(bigOrderVal, val);

    jbuf.order(ByteOrder.LITTLE_ENDIAN);
    ibuf = jbuf.asIntBuffer();
    assertNotNull(ibuf);

    val = ibuf.get(0);
    assertEquals(littleOrderVal, val);
  }
  /**
   * This is a crazy test to make sure that a direct byte buffer will still be accessible even if
   * the Buffer it came from goes out of scope and is collected.
   */
  @Test(timeout = 60 * 1000)
  public void testDirectByteBufferCanBeAccessedAfterBufferDisappears() {
    Buffer buf = Buffer.make(null, 1024 * 1024); // 1 MB
    assertNotNull(buf);

    assertEquals(1, buf.getCurrentRefCount());

    java.nio.ByteBuffer jbuf = buf.getByteBuffer(0, buf.getBufferSize());
    assertNotNull(buf);

    // now release the reference
    buf.delete();
    buf = null;

    // in versions prior to 1.22, this would have caused a hard
    // crash, but with 1.22 the getByteBuffer should have incremented
    // the native ref count until this java ByteBuffer gets collected
    // and we do a JNIMemoryManager gc.
    jbuf.put(0, (byte) 0xFF);
  }