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.utils.TypeReference; 213c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.util.Log; 223c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 233c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport java.nio.ByteBuffer; 243c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport java.util.HashMap; 253c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 263c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport static android.hardware.camera2.impl.CameraMetadataNative.*; 273c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport static android.hardware.camera2.marshal.MarshalHelpers.*; 283c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 293c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin/** 303c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Marshal any simple enum (0-arg constructors only) into/from either 313c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * {@code TYPE_BYTE} or {@code TYPE_INT32}. 323c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 333c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * <p>Default values of the enum are mapped to its ordinal; this can be overridden 343c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * by providing a manual value with {@link #registerEnumValues}.</p> 353c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 363c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param <T> the type of {@code Enum} 373c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 383c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinpublic class MarshalQueryableEnum<T extends Enum<T>> implements MarshalQueryable<T> { 393c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 403c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin private static final String TAG = MarshalQueryableEnum.class.getSimpleName(); 41a78791f22af6c6985d186494737468bb19b69540Eino-Ville Talvala private static final boolean DEBUG = false; 423c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 433c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin private static final int UINT8_MIN = 0x0; 443c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin private static final int UINT8_MAX = (1 << Byte.SIZE) - 1; 453c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin private static final int UINT8_MASK = UINT8_MAX; 463c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 473c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin private class MarshalerEnum extends Marshaler<T> { 483c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 493c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin private final Class<T> mClass; 503c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 513c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin @SuppressWarnings("unchecked") 523c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin protected MarshalerEnum(TypeReference<T> typeReference, int nativeType) { 533c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin super(MarshalQueryableEnum.this, typeReference, nativeType); 543c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 553c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin mClass = (Class<T>)typeReference.getRawType(); 563c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 573c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 583c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin @Override 593c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public void marshal(T value, ByteBuffer buffer) { 603c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin int enumValue = getEnumValue(value); 613c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 623c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin if (mNativeType == TYPE_INT32) { 633c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin buffer.putInt(enumValue); 643c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } else if (mNativeType == TYPE_BYTE) { 653c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin if (enumValue < UINT8_MIN || enumValue > UINT8_MAX) { 663c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin throw new UnsupportedOperationException(String.format( 673c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin "Enum value %x too large to fit into unsigned byte", enumValue)); 683c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 693c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin buffer.put((byte)enumValue); 703c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } else { 713c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin throw new AssertionError(); 723c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 733c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 743c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 753c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin @Override 763c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public T unmarshal(ByteBuffer buffer) { 773c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin int enumValue; 783c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 793c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin switch (mNativeType) { 803c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin case TYPE_INT32: 813c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin enumValue = buffer.getInt(); 823c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin break; 833c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin case TYPE_BYTE: 843c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin // get the unsigned byte value; avoid sign extension 853c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin enumValue = buffer.get() & UINT8_MASK; 863c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin break; 873c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin default: 883c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin throw new AssertionError( 893c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin "Unexpected native type; impossible since its not supported"); 903c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 913c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 923c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin return getEnumFromValue(mClass, enumValue); 933c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 943c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 953c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin @Override 963c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public int getNativeSize() { 973c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin return getPrimitiveTypeSize(mNativeType); 983c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 993c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1003c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1013c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin @Override 1023c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public Marshaler<T> createMarshaler(TypeReference<T> managedType, int nativeType) { 1033c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin return new MarshalerEnum(managedType, nativeType); 1043c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1053c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1063c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin @Override 1073c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public boolean isTypeMappingSupported(TypeReference<T> managedType, int nativeType) { 1083c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin if (nativeType == TYPE_INT32 || nativeType == TYPE_BYTE) { 1093c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin if (managedType.getType() instanceof Class<?>) { 1103c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin Class<?> typeClass = (Class<?>)managedType.getType(); 1113c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1123c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin if (typeClass.isEnum()) { 113a78791f22af6c6985d186494737468bb19b69540Eino-Ville Talvala if (DEBUG) { 1143c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin Log.v(TAG, "possible enum detected for " + typeClass); 1153c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1163c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1173c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin // The enum must not take extra arguments 1183c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin try { 1193c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin // match a class like: "public enum Fruits { Apple, Orange; }" 1203c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin typeClass.getDeclaredConstructor(String.class, int.class); 1213c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin return true; 1223c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } catch (NoSuchMethodException e) { 1233c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin // Skip: custom enum with a special constructor e.g. Foo(T), but need Foo() 1243c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin Log.e(TAG, "Can't marshal class " + typeClass + "; no default constructor"); 1253c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } catch (SecurityException e) { 1263c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin // Skip: wouldn't be able to touch the enum anyway 1273c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin Log.e(TAG, "Can't marshal class " + typeClass + "; not accessible"); 1283c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1293c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1303c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1313c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1323c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1333c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin return false; 1343c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1353c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1363c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin @SuppressWarnings("rawtypes") 1373c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin private static final HashMap<Class<? extends Enum>, int[]> sEnumValues = 1383c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin new HashMap<Class<? extends Enum>, int[]>(); 1393c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1403c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin /** 1413c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Register a non-sequential set of values to be used with the marshal/unmarshal functions. 1423c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 1433c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * <p>This enables get/set to correctly marshal the enum into a value that is C-compatible.</p> 1443c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 1453c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param enumType The class for an enum 1463c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param values A list of values mapping to the ordinals of the enum 1473c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 1483c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin public static <T extends Enum<T>> void registerEnumValues(Class<T> enumType, int[] values) { 1493c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin if (enumType.getEnumConstants().length != values.length) { 1503c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin throw new IllegalArgumentException( 1513c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin "Expected values array to be the same size as the enumTypes values " 1523c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin + values.length + " for type " + enumType); 1533c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 154a78791f22af6c6985d186494737468bb19b69540Eino-Ville Talvala if (DEBUG) { 1553c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin Log.v(TAG, "Registered enum values for type " + enumType + " values"); 1563c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1573c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1583c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin sEnumValues.put(enumType, values); 1593c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1603c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1613c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin /** 1623c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Get the numeric value from an enum. 1633c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 1643c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * <p>This is usually the same as the ordinal value for 1653c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * enums that have fully sequential values, although for C-style enums the range of values 1663c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * may not map 1:1.</p> 1673c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 1683c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param enumValue Enum instance 1693c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @return Int guaranteed to be ABI-compatible with the C enum equivalent 1703c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 1713c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin private static <T extends Enum<T>> int getEnumValue(T enumValue) { 1723c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin int[] values; 1733c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin values = sEnumValues.get(enumValue.getClass()); 1743c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1753c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin int ordinal = enumValue.ordinal(); 1763c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin if (values != null) { 1773c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin return values[ordinal]; 1783c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1793c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1803c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin return ordinal; 1813c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 1823c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1833c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin /** 1843c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * Finds the enum corresponding to it's numeric value. Opposite of {@link #getEnumValue} method. 1853c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * 1863c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param enumType Class of the enum we want to find 1873c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @param value The numeric value of the enum 1883c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin * @return An instance of the enum 1893c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin */ 1903c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin private static <T extends Enum<T>> T getEnumFromValue(Class<T> enumType, int value) { 1913c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin int ordinal; 1923c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1933c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin int[] registeredValues = sEnumValues.get(enumType); 1943c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin if (registeredValues != null) { 1953c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin ordinal = -1; 1963c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 1973c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin for (int i = 0; i < registeredValues.length; ++i) { 1983c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin if (registeredValues[i] == value) { 1993c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin ordinal = i; 2003c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin break; 2013c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 2023c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 2033c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } else { 2043c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin ordinal = value; 2053c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 2063c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 2073c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin T[] values = enumType.getEnumConstants(); 2083c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 2093c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin if (ordinal < 0 || ordinal >= values.length) { 2103c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin throw new IllegalArgumentException( 2113c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin String.format( 2123c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin "Argument 'value' (%d) was not a valid enum value for type %s " 2133c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin + "(registered? %b)", 2143c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin value, 2153c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin enumType, (registeredValues != null))); 2163c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 2173c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin 2183c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin return values[ordinal]; 2193c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin } 2203c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkin} 221