1 /* 2 * Copyright (C) 2014 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 package android.hardware.camera2.marshal; 17 18 import android.hardware.camera2.utils.TypeReference; 19 20 import java.nio.ByteBuffer; 21 22 import static android.hardware.camera2.marshal.MarshalHelpers.*; 23 import static com.android.internal.util.Preconditions.*; 24 25 /** 26 * Base class to marshal data to/from managed/native metadata byte buffers. 27 * 28 * <p>This class should not be created directly; an instance of it can be obtained 29 * using {@link MarshalQueryable#createMarshaler} for the same type {@code T} if the native type 30 * mapping for {@code T} {@link MarshalQueryable#isTypeMappingSupported supported}.</p> 31 * 32 * @param <T> the compile-time managed type 33 */ 34 public abstract class Marshaler<T> { 35 36 protected final TypeReference<T> mTypeReference; 37 protected final int mNativeType; 38 39 /** 40 * Instantiate a marshaler between a single managed/native type combination. 41 * 42 * <p>This particular managed/native type combination must be supported by 43 * {@link #isTypeMappingSupported}.</p> 44 * 45 * @param query an instance of {@link MarshalQueryable} 46 * @param typeReference the managed type reference 47 * Must be one for which {@link #isTypeMappingSupported} returns {@code true} 48 * @param nativeType the native type, e.g. 49 * {@link android.hardware.camera2.impl.CameraMetadataNative#TYPE_BYTE TYPE_BYTE}. 50 * Must be one for which {@link #isTypeMappingSupported} returns {@code true}. 51 * 52 * @throws NullPointerException if any args were {@code null} 53 * @throws UnsupportedOperationException if the type mapping was not supported 54 */ Marshaler( MarshalQueryable<T> query, TypeReference<T> typeReference, int nativeType)55 protected Marshaler( 56 MarshalQueryable<T> query, TypeReference<T> typeReference, int nativeType) { 57 mTypeReference = checkNotNull(typeReference, "typeReference must not be null"); 58 mNativeType = checkNativeType(nativeType); 59 60 if (!query.isTypeMappingSupported(typeReference, nativeType)) { 61 throw new UnsupportedOperationException( 62 "Unsupported type marshaling for managed type " 63 + typeReference + " and native type " 64 + MarshalHelpers.toStringNativeType(nativeType)); 65 } 66 } 67 68 /** 69 * Marshal the specified object instance (value) into a byte buffer. 70 * 71 * <p>Upon completion, the {@link ByteBuffer#position()} will have advanced by 72 * the {@link #calculateMarshalSize marshal size} of {@code value}.</p> 73 * 74 * @param value the value of type T that we wish to write into the byte buffer 75 * @param buffer the byte buffer into which the marshaled object will be written 76 */ marshal(T value, ByteBuffer buffer)77 public abstract void marshal(T value, ByteBuffer buffer); 78 79 /** 80 * Get the size in bytes for how much space would be required to write this {@code value} 81 * into a byte buffer using the given {@code nativeType}. 82 * 83 * <p>If the size of this {@code T} instance when serialized into a buffer is always constant, 84 * then this method will always return the same value (and particularly, it will return 85 * an equivalent value to {@link #getNativeSize()}.</p> 86 * 87 * <p>Overriding this method is a must when the size is {@link NATIVE_SIZE_DYNAMIC dynamic}.</p> 88 * 89 * @param value the value of type T that we wish to write into the byte buffer 90 * @return the size that would need to be written to the byte buffer 91 */ calculateMarshalSize(T value)92 public int calculateMarshalSize(T value) { 93 int nativeSize = getNativeSize(); 94 95 if (nativeSize == NATIVE_SIZE_DYNAMIC) { 96 throw new AssertionError("Override this function for dynamically-sized objects"); 97 } 98 99 return nativeSize; 100 } 101 102 /** 103 * Unmarshal a new object instance from the byte buffer into its managed type. 104 * 105 * <p>Upon completion, the {@link ByteBuffer#position()} will have advanced by 106 * the {@link #calculateMarshalSize marshal size} of the returned {@code T} instance.</p> 107 * 108 * @param buffer the byte buffer, from which we will read the object 109 * @return a new instance of type T read from the byte buffer 110 */ unmarshal(ByteBuffer buffer)111 public abstract T unmarshal(ByteBuffer buffer); 112 113 /** 114 * Used to denote variable-length data structures. 115 * 116 * <p>If the size is dynamic then we can't know ahead of time how big of a data structure 117 * to preallocate for e.g. arrays, so one object must be unmarshaled at a time.</p> 118 */ 119 public static int NATIVE_SIZE_DYNAMIC = -1; 120 121 /** 122 * How many bytes a single instance of {@code T} will take up if marshalled to/from 123 * {@code nativeType}. 124 * 125 * <p>When unmarshaling data from native to managed, the instance {@code T} is not yet 126 * available. If the native size is always a fixed mapping regardless of the instance of 127 * {@code T} (e.g. if the type is not a container of some sort), it can be used to preallocate 128 * containers for {@code T} to avoid resizing them.</p> 129 * 130 * <p>In particular, the array marshaler takes advantage of this (when size is not dynamic) 131 * to preallocate arrays of the right length when unmarshaling an array {@code T[]}.</p> 132 * 133 * @return a size in bytes, or {@link #NATIVE_SIZE_DYNAMIC} if the size is dynamic 134 */ getNativeSize()135 public abstract int getNativeSize(); 136 137 /** 138 * The type reference for {@code T} for the managed type side of this marshaler. 139 */ getTypeReference()140 public TypeReference<T> getTypeReference() { 141 return mTypeReference; 142 } 143 144 /** The native type corresponding to this marshaler for the native side of this marshaler.*/ getNativeType()145 public int getNativeType() { 146 return mNativeType; 147 } 148 } 149