/* * Licensed to the Apache Software Foundation (ASF) under one or more contributor license * agreements. See the NOTICE file distributed with this work for additional information regarding * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.internal.offheap; import java.io.ByteArrayInputStream; import java.io.DataInput; import java.io.DataInputStream; import java.io.IOException; import org.apache.geode.DataSerializer; import org.apache.geode.Instantiator; import org.apache.geode.cache.CacheClosedException; import org.apache.geode.internal.DSCODE; import org.apache.geode.internal.DSFIDFactory; import org.apache.geode.internal.InternalDataSerializer; import org.apache.geode.internal.InternalInstantiator; import org.apache.geode.internal.cache.GemFireCacheImpl; import org.apache.geode.pdx.internal.EnumInfo; import org.apache.geode.pdx.internal.PdxType; /** * Determines the data type of the bytes in an off-heap MemoryBlock. This is used by the tests for * inspection of the off-heap memory. * * @since Geode 1.0 */ public class DataType implements DSCODE { public static final String getDataType(byte[] bytes) { final DataInput in = getDataInput(bytes); byte header = 0; try { header = in.readByte(); } catch (IOException e) { return "IOException: " + e.getMessage(); } try { switch (header) { case DS_FIXED_ID_BYTE: { return "org.apache.geode.internal.DataSerializableFixedID:" + DSFIDFactory.create(in.readByte(), in).getClass().getName(); } case DS_FIXED_ID_SHORT: { return "org.apache.geode.internal.DataSerializableFixedID:" + DSFIDFactory.create(in.readShort(), in).getClass().getName(); } case DS_FIXED_ID_INT: { return "org.apache.geode.internal.DataSerializableFixedID:" + DSFIDFactory.create(in.readInt(), in).getClass().getName(); } case DS_NO_FIXED_ID: return "org.apache.geode.internal.DataSerializableFixedID:" + DataSerializer.readClass(in).getName(); case NULL: return "null"; case NULL_STRING: case STRING: case HUGE_STRING: case STRING_BYTES: case HUGE_STRING_BYTES: return "java.lang.String"; case CLASS: return "java.lang.Class"; case DATE: return "java.util.Date"; case FILE: return "java.io.File"; case INET_ADDRESS: return "java.net.InetAddress"; case BOOLEAN: return "java.lang.Boolean"; case CHARACTER: return "java.lang.Character"; case BYTE: return "java.lang.Byte"; case SHORT: return "java.lang.Short"; case INTEGER: return "java.lang.Integer"; case LONG: return "java.lang.Long"; case FLOAT: return "java.lang.Float"; case DOUBLE: return "java.lang.Double"; case BYTE_ARRAY: return "byte[]"; case ARRAY_OF_BYTE_ARRAYS: return "byte[][]"; case SHORT_ARRAY: return "short[]"; case STRING_ARRAY: return "java.lang.String[]"; case INT_ARRAY: return "int[]"; case LONG_ARRAY: return "long[]"; case FLOAT_ARRAY: return "float[]"; case DOUBLE_ARRAY: return "double[]"; case BOOLEAN_ARRAY: return "boolean[]"; case CHAR_ARRAY: return "char[]"; case OBJECT_ARRAY: return "java.lang.Object[]"; case ARRAY_LIST: return "java.util.ArrayList"; case LINKED_LIST: return "java.util.LinkedList"; case HASH_SET: return "java.util.HashSet"; case LINKED_HASH_SET: return "java.util.LinkedHashSet"; case HASH_MAP: return "java.util.HashMap"; case IDENTITY_HASH_MAP: return "java.util.IdentityHashMap"; case HASH_TABLE: return "java.util.Hashtable"; // ConcurrentHashMap is written as java.io.serializable // case CONCURRENT_HASH_MAP: // return "java.util.concurrent.ConcurrentHashMap"; case PROPERTIES: return "java.util.Properties"; case TIME_UNIT: return "java.util.concurrent.TimeUnit"; case USER_CLASS: byte userClassDSId = in.readByte(); return "DataSerializer: with Id:" + userClassDSId; case USER_CLASS_2: short userClass2DSId = in.readShort(); return "DataSerializer: with Id:" + userClass2DSId; case USER_CLASS_4: int userClass4DSId = in.readInt(); return "DataSerializer: with Id:" + userClass4DSId; case VECTOR: return "java.util.Vector"; case STACK: return "java.util.Stack"; case TREE_MAP: return "java.util.TreeMap"; case TREE_SET: return "java.util.TreeSet"; case BOOLEAN_TYPE: return "java.lang.Boolean.class"; case CHARACTER_TYPE: return "java.lang.Character.class"; case BYTE_TYPE: return "java.lang.Byte.class"; case SHORT_TYPE: return "java.lang.Short.class"; case INTEGER_TYPE: return "java.lang.Integer.class"; case LONG_TYPE: return "java.lang.Long.class"; case FLOAT_TYPE: return "java.lang.Float.class"; case DOUBLE_TYPE: return "java.lang.Double.class"; case VOID_TYPE: return "java.lang.Void.class"; case USER_DATA_SERIALIZABLE: { Instantiator instantiator = InternalInstantiator.getInstantiator(in.readByte()); return "org.apache.geode.Instantiator:" + instantiator.getInstantiatedClass().getName(); } case USER_DATA_SERIALIZABLE_2: { Instantiator instantiator = InternalInstantiator.getInstantiator(in.readShort()); return "org.apache.geode.Instantiator:" + instantiator.getInstantiatedClass().getName(); } case USER_DATA_SERIALIZABLE_4: { Instantiator instantiator = InternalInstantiator.getInstantiator(in.readInt()); return "org.apache.geode.Instantiator:" + instantiator.getInstantiatedClass().getName(); } case DATA_SERIALIZABLE: return "org.apache.geode.DataSerializable:" + DataSerializer.readClass(in).getName(); case SERIALIZABLE: { String name = null; try { Object obj = InternalDataSerializer.basicReadObject(getDataInput(bytes)); name = obj.getClass().getName(); } catch (ClassNotFoundException e) { name = e.getMessage(); } return "java.io.Serializable:" + name; } case PDX: { int typeId = in.readInt(); try { GemFireCacheImpl gfc = GemFireCacheImpl .getForPdx("PDX registry is unavailable because the Cache has been closed."); PdxType pdxType = gfc.getPdxRegistry().getType(typeId); if (pdxType == null) { // fix 52164 return "org.apache.geode.pdx.PdxInstance: unknown id=" + typeId; } return "org.apache.geode.pdx.PdxInstance:" + pdxType.getClassName(); } catch (CacheClosedException e) { return "org.apache.geode.pdx.PdxInstance:PdxRegistryClosed"; } } case PDX_ENUM: { int dsId = in.readByte(); int tmp = InternalDataSerializer.readArrayLength(in); int enumId = (dsId << 24) | (tmp & 0xFFFFFF); try { GemFireCacheImpl gfc = GemFireCacheImpl .getForPdx("PDX registry is unavailable because the Cache has been closed."); EnumInfo enumInfo = gfc.getPdxRegistry().getEnumInfoById(enumId); return "PdxRegistry/java.lang.Enum:" + enumInfo.getClassName(); } catch (CacheClosedException e) { return "PdxRegistry/java.lang.Enum:PdxRegistryClosed"; } } case GEMFIRE_ENUM: { String name = DataSerializer.readString(in); return "java.lang.Enum:" + name; } case PDX_INLINE_ENUM: { String name = DataSerializer.readString(in); return "java.lang.Enum:" + name; } case BIG_INTEGER: return "java.math.BigInteger"; case BIG_DECIMAL: return "java.math.BigDecimal"; case UUID: return "java.util.UUID"; case TIMESTAMP: return "java.sql.Timestamp"; default: } return "Unknown header byte: " + header; } catch (IOException e) { // return "IOException for header byte: " + header; throw new Error(e); } catch (ClassNotFoundException e) { // return "IOException for header byte: " + header; throw new Error(e); } } public static DataInput getDataInput(byte[] bytes) { return new DataInputStream(new ByteArrayInputStream(bytes)); } }