Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 
     18 package android.filterfw.core;
     19 
     20 import android.filterfw.core.Frame;
     21 
     22 /**
     23  * @hide
     24  */
     25 public class NativeBuffer {
     26 
     27     // These are set by the native layer
     28     private long mDataPointer = 0;
     29     private int mSize = 0;
     30 
     31     private Frame mAttachedFrame;
     32 
     33     private boolean mOwnsData = false;
     34     private int mRefCount = 1;
     35 
     36     public NativeBuffer() {
     37     }
     38 
     39     public NativeBuffer(int count) {
     40         allocate(count * getElementSize());
     41         mOwnsData = true;
     42     }
     43 
     44     public NativeBuffer mutableCopy() {
     45         NativeBuffer result = null;
     46         try {
     47             Class myClass = getClass();
     48             result = (NativeBuffer)myClass.newInstance();
     49         } catch (Exception e) {
     50             throw new RuntimeException("Unable to allocate a copy of " + getClass() + "! Make " +
     51                                        "sure the class has a default constructor!");
     52         }
     53         if (mSize > 0 && !nativeCopyTo(result)) {
     54             throw new RuntimeException("Failed to copy NativeBuffer to mutable instance!");
     55         }
     56         return result;
     57     }
     58 
     59     public int size() {
     60         return mSize;
     61     }
     62 
     63     public int count() {
     64         return (mDataPointer != 0) ? mSize / getElementSize() : 0;
     65     }
     66 
     67     public int getElementSize() {
     68         return 1;
     69     }
     70 
     71     public NativeBuffer retain() {
     72         if (mAttachedFrame != null) {
     73             mAttachedFrame.retain();
     74         } else if (mOwnsData) {
     75             ++mRefCount;
     76         }
     77         return this;
     78     }
     79 
     80     public NativeBuffer release() {
     81         // Decrement refcount
     82         boolean doDealloc = false;
     83         if (mAttachedFrame != null) {
     84             doDealloc = (mAttachedFrame.release() == null);
     85         } else if (mOwnsData) {
     86             --mRefCount;
     87             doDealloc = (mRefCount == 0);
     88         }
     89 
     90         // Deallocate if necessary
     91         if (doDealloc) {
     92             deallocate(mOwnsData);
     93             return null;
     94         } else {
     95             return this;
     96         }
     97     }
     98 
     99     public boolean isReadOnly() {
    100         return (mAttachedFrame != null) ? mAttachedFrame.isReadOnly() : false;
    101     }
    102 
    103     static {
    104         System.loadLibrary("filterfw");
    105     }
    106 
    107     void attachToFrame(Frame frame) {
    108         // We do not auto-retain. We expect the user to call retain() if they want to hold on to
    109         // the frame.
    110         mAttachedFrame = frame;
    111     }
    112 
    113     protected void assertReadable() {
    114         if (mDataPointer == 0 || mSize == 0
    115         || (mAttachedFrame != null && !mAttachedFrame.hasNativeAllocation())) {
    116             throw new NullPointerException("Attempting to read from null data frame!");
    117         }
    118     }
    119 
    120     protected void assertWritable() {
    121         if (isReadOnly()) {
    122             throw new RuntimeException("Attempting to modify read-only native (structured) data!");
    123         }
    124     }
    125 
    126     private native boolean allocate(int size);
    127     private native boolean deallocate(boolean ownsData);
    128     private native boolean nativeCopyTo(NativeBuffer buffer);
    129 }
    130