Merge "camera2: Avoid boxing primitives while unmarshalling primitive arrays."
This commit is contained in:
committed by
Android (Google) Code Review
commit
36ad891fe0
@@ -94,6 +94,40 @@ public final class MarshalHelpers {
|
||||
"'; expected a metadata primitive class");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not {@code klass} is one of the unboxed primitive classes.
|
||||
*
|
||||
* <p>The following types (whether boxed or unboxed) are considered primitive:
|
||||
* <ul>
|
||||
* <li>byte
|
||||
* <li>int
|
||||
* <li>float
|
||||
* <li>double
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @param klass a {@link Class} instance; using {@code null} will return {@code false}
|
||||
* @return {@code true} if primitive, {@code false} otherwise
|
||||
*/
|
||||
public static boolean isUnwrappedPrimitiveClass(Class<?> klass) {
|
||||
if (klass == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (klass == byte.class) {
|
||||
return true;
|
||||
} else if (klass == int.class) {
|
||||
return true;
|
||||
} else if (klass == float.class) {
|
||||
return true;
|
||||
} else if (klass == long.class) {
|
||||
return true;
|
||||
} else if (klass == double.class) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not {@code klass} is one of the metadata-primitive classes.
|
||||
*
|
||||
@@ -218,6 +252,32 @@ public final class MarshalHelpers {
|
||||
throw new UnsupportedOperationException("Unknown nativeType " + nativeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unboxed primitive type corresponding to nativeType
|
||||
*
|
||||
* @param nativeType the native type (RATIONAL not included)
|
||||
*
|
||||
* @return the native type class
|
||||
*
|
||||
* @throws UnsupportedOperationException if the native type was invalid
|
||||
*/
|
||||
public static Class<?> getPrimitiveTypeClass(int nativeType) {
|
||||
switch (nativeType) {
|
||||
case TYPE_BYTE:
|
||||
return byte.class;
|
||||
case TYPE_INT32:
|
||||
return int.class;
|
||||
case TYPE_FLOAT:
|
||||
return float.class;
|
||||
case TYPE_INT64:
|
||||
return long.class;
|
||||
case TYPE_DOUBLE:
|
||||
return double.class;
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Unknown nativeType " + nativeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the expected and actual native types are equal.
|
||||
*
|
||||
|
||||
@@ -21,6 +21,9 @@ import android.hardware.camera2.marshal.MarshalRegistry;
|
||||
import android.hardware.camera2.utils.TypeReference;
|
||||
import android.util.Log;
|
||||
|
||||
import static android.hardware.camera2.marshal.MarshalHelpers.isUnwrappedPrimitiveClass;
|
||||
import static android.hardware.camera2.marshal.MarshalHelpers.getPrimitiveTypeClass;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
@@ -41,6 +44,62 @@ public class MarshalQueryableArray<T> implements MarshalQueryable<T> {
|
||||
private static final String TAG = MarshalQueryableArray.class.getSimpleName();
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static interface PrimitiveArrayFiller {
|
||||
public void fillPosition(Object arr, int index, ByteBuffer buffer);
|
||||
static PrimitiveArrayFiller getPrimitiveArrayFiller(Class<?> componentType) {
|
||||
if (componentType == int.class) {
|
||||
return new PrimitiveArrayFiller() {
|
||||
@Override
|
||||
public void fillPosition(Object arr, int index, ByteBuffer buffer) {
|
||||
int i = buffer.getInt();
|
||||
Array.setInt(arr, index, i);
|
||||
}
|
||||
};
|
||||
} else if (componentType == float.class) {
|
||||
return new PrimitiveArrayFiller() {
|
||||
@Override
|
||||
public void fillPosition(Object arr, int index, ByteBuffer buffer) {
|
||||
float i = buffer.getFloat();
|
||||
Array.setFloat(arr, index, i);
|
||||
}
|
||||
};
|
||||
} else if (componentType == long.class) {
|
||||
return new PrimitiveArrayFiller() {
|
||||
@Override
|
||||
public void fillPosition(Object arr, int index, ByteBuffer buffer) {
|
||||
long i = buffer.getLong();
|
||||
Array.setLong(arr, index, i);
|
||||
}
|
||||
};
|
||||
} else if (componentType == double.class) {
|
||||
return new PrimitiveArrayFiller() {
|
||||
@Override
|
||||
public void fillPosition(Object arr, int index, ByteBuffer buffer) {
|
||||
double i = buffer.getDouble();
|
||||
Array.setDouble(arr, index, i);
|
||||
}
|
||||
};
|
||||
} else if (componentType == byte.class) {
|
||||
return new PrimitiveArrayFiller() {
|
||||
@Override
|
||||
public void fillPosition(Object arr, int index, ByteBuffer buffer) {
|
||||
byte i = buffer.get();
|
||||
Array.setByte(arr, index, i);
|
||||
}
|
||||
};
|
||||
}
|
||||
throw new UnsupportedOperationException("PrimitiveArrayFiller of type "
|
||||
+ componentType.getName() + " not supported");
|
||||
}
|
||||
};
|
||||
|
||||
static void unmarshalPrimitiveArray(Object arr, int size, ByteBuffer buffer,
|
||||
PrimitiveArrayFiller filler) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
filler.fillPosition(arr, i, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private class MarshalerArray extends Marshaler<T> {
|
||||
private final Class<T> mClass;
|
||||
private final Marshaler<?> mComponentMarshaler;
|
||||
@@ -89,9 +148,15 @@ public class MarshalQueryableArray<T> implements MarshalQueryable<T> {
|
||||
}
|
||||
|
||||
array = Array.newInstance(mComponentClass, arraySize);
|
||||
for (int i = 0; i < arraySize; ++i) {
|
||||
Object elem = mComponentMarshaler.unmarshal(buffer);
|
||||
Array.set(array, i, elem);
|
||||
if (isUnwrappedPrimitiveClass(mComponentClass) &&
|
||||
mComponentClass == getPrimitiveTypeClass(mNativeType)) {
|
||||
unmarshalPrimitiveArray(array, arraySize, buffer,
|
||||
PrimitiveArrayFiller.getPrimitiveArrayFiller(mComponentClass));
|
||||
} else {
|
||||
for (int i = 0; i < arraySize; ++i) {
|
||||
Object elem = mComponentMarshaler.unmarshal(buffer);
|
||||
Array.set(array, i, elem);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Dynamic size, use an array list.
|
||||
|
||||
Reference in New Issue
Block a user