13c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin/* 23c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Copyright (C) 2014 The Android Open Source Project 33c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 43c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License"); 53c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * you may not use this file except in compliance with the License. 63c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * You may obtain a copy of the License at 73c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 83c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * http://www.apache.org/licenses/LICENSE-2.0 93c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 103c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Unless required by applicable law or agreed to in writing, software 113c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS, 123c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * See the License for the specific language governing permissions and 143c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * limitations under the License. 153c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 163c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinpackage android.hardware.camera2.marshal; 173c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 183c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.utils.TypeReference; 193c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 203c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport java.nio.ByteBuffer; 213c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 223c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport static android.hardware.camera2.marshal.MarshalHelpers.*; 233c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport static com.android.internal.util.Preconditions.*; 243c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 253c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin/** 263c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Base class to marshal data to/from managed/native metadata byte buffers. 273c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 283c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * <p>This class should not be created directly; an instance of it can be obtained 293c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * using {@link MarshalQueryable#createMarshaler} for the same type {@code T} if the native type 303c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * mapping for {@code T} {@link MarshalQueryable#isTypeMappingSupported supported}.</p> 313c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 323c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param <T> the compile-time managed type 333c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 343c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinpublic abstract class Marshaler<T> { 353c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 363c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin protected final TypeReference<T> mTypeReference; 373c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin protected final int mNativeType; 383c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 393c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin /** 403c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Instantiate a marshaler between a single managed/native type combination. 413c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 423c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * <p>This particular managed/native type combination must be supported by 433c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * {@link #isTypeMappingSupported}.</p> 443c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 453c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param query an instance of {@link MarshalQueryable} 463c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param typeReference the managed type reference 473c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Must be one for which {@link #isTypeMappingSupported} returns {@code true} 483c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param nativeType the native type, e.g. 493c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * {@link android.hardware.camera2.impl.CameraMetadataNative#TYPE_BYTE TYPE_BYTE}. 503c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Must be one for which {@link #isTypeMappingSupported} returns {@code true}. 513c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 523c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @throws NullPointerException if any args were {@code null} 533c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @throws UnsupportedOperationException if the type mapping was not supported 543c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 553c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin protected Marshaler( 563c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin MarshalQueryable<T> query, TypeReference<T> typeReference, int nativeType) { 573c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin mTypeReference = checkNotNull(typeReference, "typeReference must not be null"); 583c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin mNativeType = checkNativeType(nativeType); 593c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 603c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin if (!query.isTypeMappingSupported(typeReference, nativeType)) { 613c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin throw new UnsupportedOperationException( 623c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin "Unsupported type marshaling for managed type " 633c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin + typeReference + " and native type " 643c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin + MarshalHelpers.toStringNativeType(nativeType)); 653c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 663c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 673c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 683c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin /** 693c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Marshal the specified object instance (value) into a byte buffer. 703c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 713c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * <p>Upon completion, the {@link ByteBuffer#position()} will have advanced by 723c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * the {@link #calculateMarshalSize marshal size} of {@code value}.</p> 733c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 743c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param value the value of type T that we wish to write into the byte buffer 753c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param buffer the byte buffer into which the marshaled object will be written 763c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 773c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public abstract void marshal(T value, ByteBuffer buffer); 783c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 793c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin /** 803c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Get the size in bytes for how much space would be required to write this {@code value} 813c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * into a byte buffer using the given {@code nativeType}. 823c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 833c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * <p>If the size of this {@code T} instance when serialized into a buffer is always constant, 843c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * then this method will always return the same value (and particularly, it will return 853c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * an equivalent value to {@link #getNativeSize()}.</p> 863c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 873c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * <p>Overriding this method is a must when the size is {@link NATIVE_SIZE_DYNAMIC dynamic}.</p> 883c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 893c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param value the value of type T that we wish to write into the byte buffer 903c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @return the size that would need to be written to the byte buffer 913c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 923c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public int calculateMarshalSize(T value) { 933c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin int nativeSize = getNativeSize(); 943c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 953c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin if (nativeSize == NATIVE_SIZE_DYNAMIC) { 963c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin throw new AssertionError("Override this function for dynamically-sized objects"); 973c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 983c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 993c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin return nativeSize; 1003c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1013c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1023c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin /** 1033c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Unmarshal a new object instance from the byte buffer into its managed type. 1043c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 1053c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * <p>Upon completion, the {@link ByteBuffer#position()} will have advanced by 1063c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * the {@link #calculateMarshalSize marshal size} of the returned {@code T} instance.</p> 1073c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 1083c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param buffer the byte buffer, from which we will read the object 1093c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @return a new instance of type T read from the byte buffer 1103c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 1113c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public abstract T unmarshal(ByteBuffer buffer); 1123c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1133c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin /** 1143c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Used to denote variable-length data structures. 1153c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 1163c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * <p>If the size is dynamic then we can't know ahead of time how big of a data structure 1173c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * to preallocate for e.g. arrays, so one object must be unmarshaled at a time.</p> 1183c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 1193c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public static int NATIVE_SIZE_DYNAMIC = -1; 1203c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1213c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin /** 1223c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * How many bytes a single instance of {@code T} will take up if marshalled to/from 1233c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * {@code nativeType}. 1243c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 1253c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * <p>When unmarshaling data from native to managed, the instance {@code T} is not yet 1263c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * available. If the native size is always a fixed mapping regardless of the instance of 1273c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * {@code T} (e.g. if the type is not a container of some sort), it can be used to preallocate 1283c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * containers for {@code T} to avoid resizing them.</p> 1293c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 1303c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * <p>In particular, the array marshaler takes advantage of this (when size is not dynamic) 1313c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * to preallocate arrays of the right length when unmarshaling an array {@code T[]}.</p> 1323c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 1333c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @return a size in bytes, or {@link #NATIVE_SIZE_DYNAMIC} if the size is dynamic 1343c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 1353c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public abstract int getNativeSize(); 1363c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1373c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin /** 1383c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * The type reference for {@code T} for the managed type side of this marshaler. 1393c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 1403c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public TypeReference<T> getTypeReference() { 1413c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin return mTypeReference; 1423c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1433c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1443c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin /** The native type corresponding to this marshaler for the native side of this marshaler.*/ 1453c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public int getNativeType() { 1463c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin return mNativeType; 1473c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1483c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin} 149