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 
NativeBuffer()36     public NativeBuffer() {
37     }
38 
NativeBuffer(int count)39     public NativeBuffer(int count) {
40         allocate(count * getElementSize());
41         mOwnsData = true;
42     }
43 
mutableCopy()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 
size()59     public int size() {
60         return mSize;
61     }
62 
count()63     public int count() {
64         return (mDataPointer != 0) ? mSize / getElementSize() : 0;
65     }
66 
getElementSize()67     public int getElementSize() {
68         return 1;
69     }
70 
retain()71     public NativeBuffer retain() {
72         if (mAttachedFrame != null) {
73             mAttachedFrame.retain();
74         } else if (mOwnsData) {
75             ++mRefCount;
76         }
77         return this;
78     }
79 
release()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 
isReadOnly()99     public boolean isReadOnly() {
100         return (mAttachedFrame != null) ? mAttachedFrame.isReadOnly() : false;
101     }
102 
103     static {
104         System.loadLibrary("filterfw");
105     }
106 
attachToFrame(Frame frame)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 
assertReadable()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 
assertWritable()120     protected void assertWritable() {
121         if (isReadOnly()) {
122             throw new RuntimeException("Attempting to modify read-only native (structured) data!");
123         }
124     }
125 
allocate(int size)126     private native boolean allocate(int size);
deallocate(boolean ownsData)127     private native boolean deallocate(boolean ownsData);
nativeCopyTo(NativeBuffer buffer)128     private native boolean nativeCopyTo(NativeBuffer buffer);
129 }
130