package com.litl.leveldb;

import java.io.Closeable;
import java.util.concurrent.atomic.AtomicInteger;

abstract class NativeObject implements Closeable {
    protected long mPtr;
    private AtomicInteger mRefCount = new AtomicInteger();

    protected NativeObject() {
        // The Java wrapper counts as one reference, will
        // be released when closed
        ref();
    }

    protected NativeObject(long ptr) {
        this();

        if (ptr == 0) {
            throw new OutOfMemoryError("Failed to allocate native object");
        }

        mPtr = ptr;
    }

    protected long getPtr() {
        return mPtr;
    }

    protected void assertOpen(String message) {
        if (mPtr == 0) {
            throw new IllegalStateException(message);
        }
    }

    void ref() {
        mRefCount.incrementAndGet();
    }

    void unref() {
        if (mRefCount.decrementAndGet() == 0) {
            closeNativeObject(mPtr);
            mPtr = 0;
        }
    }

    protected abstract void closeNativeObject(long ptr);

    @Override
    public void close() {
        unref();
    }
}

@@ -97,16 +97,42 @@
 teger;%0A%0A
+import android.util.Log;%0A%0A
 abstract
@@ -174,16 +174,90 @@
 eable %7B%0A
+    private static final String TAG = NativeObject.class.getSimpleName();%0A
     prot
@@ -1199,11 +1199,375 @@
 );%0A    %7D
+%0A%0A    @Override%0A    protected void finalize() throws Throwable %7B%0A        if (mPtr != 0) %7B%0A            Log.w(TAG,%0A                    %22NativeObject %22%0A                            + getClass().getSimpleName()%0A                            + %22 was finalized before native resource was closed, did you forget to call close()?%22);%0A        %7D%0A%0A        super.finalize();%0A    %7D
 %0A%7D%0A

Add a warning if resources are leaked.