149 lines
6.1 KiB
Java
149 lines
6.1 KiB
Java
/*
|
|
* Copyright (C) 2014 The Android 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.
|
|
*/
|
|
package android.hardware.camera2.marshal;
|
|
|
|
import android.hardware.camera2.utils.TypeReference;
|
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
import static android.hardware.camera2.marshal.MarshalHelpers.*;
|
|
import static com.android.internal.util.Preconditions.*;
|
|
|
|
/**
|
|
* Base class to marshal data to/from managed/native metadata byte buffers.
|
|
*
|
|
* <p>This class should not be created directly; an instance of it can be obtained
|
|
* using {@link MarshalQueryable#createMarshaler} for the same type {@code T} if the native type
|
|
* mapping for {@code T} {@link MarshalQueryable#isTypeMappingSupported supported}.</p>
|
|
*
|
|
* @param <T> the compile-time managed type
|
|
*/
|
|
public abstract class Marshaler<T> {
|
|
|
|
protected final TypeReference<T> mTypeReference;
|
|
protected final int mNativeType;
|
|
|
|
/**
|
|
* Instantiate a marshaler between a single managed/native type combination.
|
|
*
|
|
* <p>This particular managed/native type combination must be supported by
|
|
* {@link #isTypeMappingSupported}.</p>
|
|
*
|
|
* @param query an instance of {@link MarshalQueryable}
|
|
* @param typeReference the managed type reference
|
|
* Must be one for which {@link #isTypeMappingSupported} returns {@code true}
|
|
* @param nativeType the native type, e.g.
|
|
* {@link android.hardware.camera2.impl.CameraMetadataNative#TYPE_BYTE TYPE_BYTE}.
|
|
* Must be one for which {@link #isTypeMappingSupported} returns {@code true}.
|
|
*
|
|
* @throws NullPointerException if any args were {@code null}
|
|
* @throws UnsupportedOperationException if the type mapping was not supported
|
|
*/
|
|
protected Marshaler(
|
|
MarshalQueryable<T> query, TypeReference<T> typeReference, int nativeType) {
|
|
mTypeReference = checkNotNull(typeReference, "typeReference must not be null");
|
|
mNativeType = checkNativeType(nativeType);
|
|
|
|
if (!query.isTypeMappingSupported(typeReference, nativeType)) {
|
|
throw new UnsupportedOperationException(
|
|
"Unsupported type marshaling for managed type "
|
|
+ typeReference + " and native type "
|
|
+ MarshalHelpers.toStringNativeType(nativeType));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Marshal the specified object instance (value) into a byte buffer.
|
|
*
|
|
* <p>Upon completion, the {@link ByteBuffer#position()} will have advanced by
|
|
* the {@link #calculateMarshalSize marshal size} of {@code value}.</p>
|
|
*
|
|
* @param value the value of type T that we wish to write into the byte buffer
|
|
* @param buffer the byte buffer into which the marshaled object will be written
|
|
*/
|
|
public abstract void marshal(T value, ByteBuffer buffer);
|
|
|
|
/**
|
|
* Get the size in bytes for how much space would be required to write this {@code value}
|
|
* into a byte buffer using the given {@code nativeType}.
|
|
*
|
|
* <p>If the size of this {@code T} instance when serialized into a buffer is always constant,
|
|
* then this method will always return the same value (and particularly, it will return
|
|
* an equivalent value to {@link #getNativeSize()}.</p>
|
|
*
|
|
* <p>Overriding this method is a must when the size is {@link NATIVE_SIZE_DYNAMIC dynamic}.</p>
|
|
*
|
|
* @param value the value of type T that we wish to write into the byte buffer
|
|
* @return the size that would need to be written to the byte buffer
|
|
*/
|
|
public int calculateMarshalSize(T value) {
|
|
int nativeSize = getNativeSize();
|
|
|
|
if (nativeSize == NATIVE_SIZE_DYNAMIC) {
|
|
throw new AssertionError("Override this function for dynamically-sized objects");
|
|
}
|
|
|
|
return nativeSize;
|
|
}
|
|
|
|
/**
|
|
* Unmarshal a new object instance from the byte buffer into its managed type.
|
|
*
|
|
* <p>Upon completion, the {@link ByteBuffer#position()} will have advanced by
|
|
* the {@link #calculateMarshalSize marshal size} of the returned {@code T} instance.</p>
|
|
*
|
|
* @param buffer the byte buffer, from which we will read the object
|
|
* @return a new instance of type T read from the byte buffer
|
|
*/
|
|
public abstract T unmarshal(ByteBuffer buffer);
|
|
|
|
/**
|
|
* Used to denote variable-length data structures.
|
|
*
|
|
* <p>If the size is dynamic then we can't know ahead of time how big of a data structure
|
|
* to preallocate for e.g. arrays, so one object must be unmarshaled at a time.</p>
|
|
*/
|
|
public static int NATIVE_SIZE_DYNAMIC = -1;
|
|
|
|
/**
|
|
* How many bytes a single instance of {@code T} will take up if marshalled to/from
|
|
* {@code nativeType}.
|
|
*
|
|
* <p>When unmarshaling data from native to managed, the instance {@code T} is not yet
|
|
* available. If the native size is always a fixed mapping regardless of the instance of
|
|
* {@code T} (e.g. if the type is not a container of some sort), it can be used to preallocate
|
|
* containers for {@code T} to avoid resizing them.</p>
|
|
*
|
|
* <p>In particular, the array marshaler takes advantage of this (when size is not dynamic)
|
|
* to preallocate arrays of the right length when unmarshaling an array {@code T[]}.</p>
|
|
*
|
|
* @return a size in bytes, or {@link #NATIVE_SIZE_DYNAMIC} if the size is dynamic
|
|
*/
|
|
public abstract int getNativeSize();
|
|
|
|
/**
|
|
* The type reference for {@code T} for the managed type side of this marshaler.
|
|
*/
|
|
public TypeReference<T> getTypeReference() {
|
|
return mTypeReference;
|
|
}
|
|
|
|
/** The native type corresponding to this marshaler for the native side of this marshaler.*/
|
|
public int getNativeType() {
|
|
return mNativeType;
|
|
}
|
|
}
|