// Path: src/main/java/org/lmdbjava/UnsafeAccess.java
// static final Unsafe UNSAFE;


import static io.netty.buffer.PooledByteBufAllocator.DEFAULT;
import static java.lang.Class.forName;
import static org.lmdbjava.UnsafeAccess.UNSAFE;
import java.lang.reflect.Field;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import jnr.ffi.Pointer;
/*-
 * #%L
 * LmdbJava
 * %%
 * Copyright (C) 2016 - 2021 The LmdbJava Open Source Project
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

package org.lmdbjava;




/**
 * A buffer proxy backed by Netty's {@link ByteBuf}.
 *
 * <p>
 * This class requires {@link UnsafeAccess} and netty-buffer must be in the
 * classpath.
 */
public final class ByteBufProxy extends BufferProxy<ByteBuf> {

  /**
   * A proxy for using Netty {@link ByteBuf}. Guaranteed to never be null,
   * although a class initialization exception will occur if an attempt is made
   * to access this field when Netty is unavailable.
   */
  public static final BufferProxy<ByteBuf> PROXY_NETTY = new ByteBufProxy();

  private static final int BUFFER_RETRIES = 10;
  private static final String FIELD_NAME_ADDRESS = "memoryAddress";
  private static final String FIELD_NAME_LENGTH = "length";
  private static final String NAME = "io.netty.buffer.PooledUnsafeDirectByteBuf";
  private final long lengthOffset;
  private final long addressOffset;
  
  private final PooledByteBufAllocator nettyAllocator;

  private ByteBufProxy() {
    this(DEFAULT);
  }

  public ByteBufProxy(final PooledByteBufAllocator allocator) {
    this.nettyAllocator = allocator;

    try {
      final ByteBuf initBuf = this.allocate();
      initBuf.release();
      final Field address = findField(NAME, FIELD_NAME_ADDRESS);
      final Field length = findField(NAME, FIELD_NAME_LENGTH);
// Path: src/main/java/org/lmdbjava/UnsafeAccess.java
// static final Unsafe UNSAFE;


// Path: src/main/java/org/lmdbjava/ByteBufProxy.java
import static io.netty.buffer.PooledByteBufAllocator.DEFAULT;
import static java.lang.Class.forName;
import static org.lmdbjava.UnsafeAccess.UNSAFE;
import java.lang.reflect.Field;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import jnr.ffi.Pointer;

/*-
 * #%L
 * LmdbJava
 * %%
 * Copyright (C) 2016 - 2021 The LmdbJava Open Source Project
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

package org.lmdbjava;




/**
 * A buffer proxy backed by Netty's {@link ByteBuf}.
 *
 * <p>
 * This class requires {@link UnsafeAccess} and netty-buffer must be in the
 * classpath.
 */
public final class ByteBufProxy extends BufferProxy<ByteBuf> {

  /**
   * A proxy for using Netty {@link ByteBuf}. Guaranteed to never be null,
   * although a class initialization exception will occur if an attempt is made
   * to access this field when Netty is unavailable.
   */
  public static final BufferProxy<ByteBuf> PROXY_NETTY = new ByteBufProxy();

  private static final int BUFFER_RETRIES = 10;
  private static final String FIELD_NAME_ADDRESS = "memoryAddress";
  private static final String FIELD_NAME_LENGTH = "length";
  private static final String NAME = "io.netty.buffer.PooledUnsafeDirectByteBuf";
  private final long lengthOffset;
  private final long addressOffset;
  
  private final PooledByteBufAllocator nettyAllocator;

  private ByteBufProxy() {
    this(DEFAULT);
  }

  public ByteBufProxy(final PooledByteBufAllocator allocator) {
    this.nettyAllocator = allocator;

    try {
      final ByteBuf initBuf = this.allocate();
      initBuf.release();
      final Field address = findField(NAME, FIELD_NAME_ADDRESS);
      final Field length = findField(NAME, FIELD_NAME_LENGTH);
      addressOffset = UNSAFE.objectFieldOffset(address);