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.impl;
173c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
183c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.Marshaler;
193c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.MarshalQueryable;
203c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.marshal.MarshalRegistry;
213c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.utils.TypeReference;
223c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.util.Range;
233c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
243c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport java.lang.reflect.Constructor;
253c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport java.lang.reflect.InvocationTargetException;
263c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport java.lang.reflect.ParameterizedType;
273c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport java.lang.reflect.Type;
283c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport java.nio.ByteBuffer;
293c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
303c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin/**
313c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Marshal {@link Range} to/from any native type
323c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */
333c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinpublic class MarshalQueryableRange<T extends Comparable<? super T>>
343c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        implements MarshalQueryable<Range<T>> {
353c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin    private static final int RANGE_COUNT = 2;
363c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
373c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin    private class MarshalerRange extends Marshaler<Range<T>> {
383c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        private final Class<? super Range<T>> mClass;
393c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        private final Constructor<Range<T>> mConstructor;
403c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        /** Marshal the {@code T} inside of {@code Range<T>} */
413c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        private final Marshaler<T> mNestedTypeMarshaler;
423c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
433c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        @SuppressWarnings("unchecked")
443c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        protected MarshalerRange(TypeReference<Range<T>> typeReference,
453c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                int nativeType) {
463c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            super(MarshalQueryableRange.this, typeReference, nativeType);
473c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
483c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            mClass = typeReference.getRawType();
493c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
503c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            /*
513c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin             * Lookup the actual type argument, e.g. Range<Integer> --> Integer
523c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin             * and then get the marshaler for that managed type.
533c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin             */
543c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            ParameterizedType paramType;
553c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            try {
563c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                paramType = (ParameterizedType) typeReference.getType();
573c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            } catch (ClassCastException e) {
583c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                throw new AssertionError("Raw use of Range is not supported", e);
593c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            }
603c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            Type actualTypeArgument = paramType.getActualTypeArguments()[0];
613c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
623c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            TypeReference<?> actualTypeArgToken =
633c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                    TypeReference.createSpecializedTypeReference(actualTypeArgument);
643c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
653c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            mNestedTypeMarshaler = (Marshaler<T>)MarshalRegistry.getMarshaler(
663c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                    actualTypeArgToken, mNativeType);
673c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            try {
683c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                mConstructor = (Constructor<Range<T>>)mClass.getConstructor(
693c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                        Comparable.class, Comparable.class);
703c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            } catch (NoSuchMethodException e) {
713c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                throw new AssertionError(e);
723c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            }
733c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        }
743c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
753c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        @Override
763c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        public void marshal(Range<T> value, ByteBuffer buffer) {
773c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            mNestedTypeMarshaler.marshal(value.getLower(), buffer);
783c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            mNestedTypeMarshaler.marshal(value.getUpper(), buffer);
793c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        }
803c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
813c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        @Override
823c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        public Range<T> unmarshal(ByteBuffer buffer) {
833c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            T lower = mNestedTypeMarshaler.unmarshal(buffer);
843c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            T upper = mNestedTypeMarshaler.unmarshal(buffer);
853c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
863c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            try {
873c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                return mConstructor.newInstance(lower, upper);
883c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            } catch (InstantiationException e) {
893c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                throw new AssertionError(e);
903c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            } catch (IllegalAccessException e) {
913c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                throw new AssertionError(e);
923c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            } catch (IllegalArgumentException e) {
933c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                throw new AssertionError(e);
943c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            } catch (InvocationTargetException e) {
953c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                throw new AssertionError(e);
963c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            }
973c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        }
983c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
993c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        @Override
1003c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        public int getNativeSize() {
1013c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            int nestedSize = mNestedTypeMarshaler.getNativeSize();
1023c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
1033c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            if (nestedSize != NATIVE_SIZE_DYNAMIC) {
1043c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                return nestedSize * RANGE_COUNT;
1053c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            } else {
1063c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                return NATIVE_SIZE_DYNAMIC;
1073c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            }
1083c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        }
1093c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
1103c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        @Override
1113c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        public int calculateMarshalSize(Range<T> value) {
1123c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            int nativeSize = getNativeSize();
1133c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
1143c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            if (nativeSize != NATIVE_SIZE_DYNAMIC) {
1153c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                return nativeSize;
1163c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            } else {
1173c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                int lowerSize = mNestedTypeMarshaler.calculateMarshalSize(value.getLower());
1183c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                int upperSize = mNestedTypeMarshaler.calculateMarshalSize(value.getUpper());
1193c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
1203c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin                return lowerSize + upperSize;
1213c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            }
1223c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        }
1233c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin    }
1243c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
1253c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin    @Override
1263c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin    public Marshaler<Range<T>> createMarshaler(TypeReference<Range<T>> managedType,
1273c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin            int nativeType) {
1283c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        return new MarshalerRange(managedType, nativeType);
1293c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin    }
1303c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
1313c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin    @Override
1323c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin    public boolean isTypeMappingSupported(TypeReference<Range<T>> managedType, int nativeType) {
1333c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin        return (Range.class.equals(managedType.getRawType()));
1343c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin    }
1353c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin
1363c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin}
137