All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.android.ddmlib.log.EventContainer Maven / Gradle / Ivy

There is a newer version: 25.3.0
Show newest version
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed 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 com.android.ddmlib.log;

import com.android.ddmlib.log.LogReceiver.LogEntry;

import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Represents an event and its data.
 */
public class EventContainer {

    /**
     * Comparison method for {@link EventContainer#testValue(int, Object, com.android.ddmlib.log.EventContainer.CompareMethod)}
     *
     */
    public enum CompareMethod {
        EQUAL_TO("equals", "=="),
        LESSER_THAN("less than or equals to", "<="),
        LESSER_THAN_STRICT("less than", "<"),
        GREATER_THAN("greater than or equals to", ">="),
        GREATER_THAN_STRICT("greater than", ">"),
        BIT_CHECK("bit check", "&");

        private final String mName;
        private final String mTestString;

        CompareMethod(String name, String testString) {
            mName = name;
            mTestString = testString;
        }

        /**
         * Returns the display string.
         */
        @Override
        public String toString() {
            return mName;
        }

        /**
         * Returns a short string representing the comparison.
         */
        public String testString() {
            return mTestString;
        }
    }


    /**
     * Type for event data.
     */
    public enum EventValueType {
        UNKNOWN(0),
        INT(1),
        LONG(2),
        STRING(3),
        LIST(4),
        TREE(5);

        private static final Pattern STORAGE_PATTERN = Pattern.compile("^(\\d+)@(.*)$"); //$NON-NLS-1$

        private int mValue;

        /**
         * Returns a {@link EventValueType} from an integer value, or null if no match
         * was found.
         * @param value the integer value.
         */
        static EventValueType getEventValueType(int value) {
            for (EventValueType type : values()) {
                if (type.mValue == value) {
                    return type;
                }
            }

            return null;
        }

        /**
         * Returns a storage string for an {@link Object} of type supported by
         * {@link EventValueType}.
         * 

* Strings created by this method can be reloaded with * {@link #getObjectFromStorageString(String)}. *

* NOTE: for now, only {@link #STRING}, {@link #INT}, and {@link #LONG} are supported. * @param object the object to "convert" into a storage string. * @return a string storing the object and its type or null if the type was not recognized. */ public static String getStorageString(Object object) { if (object instanceof String) { return STRING.mValue + "@" + object; //$NON-NLS-1$ } else if (object instanceof Integer) { return INT.mValue + "@" + object.toString(); //$NON-NLS-1$ } else if (object instanceof Long) { return LONG.mValue + "@" + object.toString(); //$NON-NLS-1$ } return null; } /** * Creates an {@link Object} from a storage string created with * {@link #getStorageString(Object)}. * @param value the storage string * @return an {@link Object} or null if the string or type were not recognized. */ public static Object getObjectFromStorageString(String value) { Matcher m = STORAGE_PATTERN.matcher(value); if (m.matches()) { try { EventValueType type = getEventValueType(Integer.parseInt(m.group(1))); if (type == null) { return null; } switch (type) { case STRING: return m.group(2); case INT: return Integer.valueOf(m.group(2)); case LONG: return Long.valueOf(m.group(2)); } } catch (NumberFormatException nfe) { return null; } } return null; } /** * Returns the integer value of the enum. */ public int getValue() { return mValue; } @Override public String toString() { return super.toString().toLowerCase(Locale.US); } EventValueType(int value) { mValue = value; } } public int mTag; public int pid; /* generating process's pid */ public int tid; /* generating process's tid */ public int sec; /* seconds since Epoch */ public int nsec; /* nanoseconds */ private Object mData; /** * Creates an {@link EventContainer} from a {@link LogEntry}. * @param entry the LogEntry from which pid, tid, and time info is copied. * @param tag the event tag value * @param data the data of the EventContainer. */ EventContainer(LogEntry entry, int tag, Object data) { getType(data); mTag = tag; mData = data; pid = entry.pid; tid = entry.tid; sec = entry.sec; nsec = entry.nsec; } /** * Creates an {@link EventContainer} with raw data */ EventContainer(int tag, int pid, int tid, int sec, int nsec, Object data) { getType(data); mTag = tag; mData = data; this.pid = pid; this.tid = tid; this.sec = sec; this.nsec = nsec; } /** * Returns the data as an int. * @throws InvalidTypeException if the data type is not {@link EventValueType#INT}. * @see #getType() */ public final Integer getInt() throws InvalidTypeException { if (getType(mData) == EventValueType.INT) { return (Integer)mData; } throw new InvalidTypeException(); } /** * Returns the data as a long. * @throws InvalidTypeException if the data type is not {@link EventValueType#LONG}. * @see #getType() */ public final Long getLong() throws InvalidTypeException { if (getType(mData) == EventValueType.LONG) { return (Long)mData; } throw new InvalidTypeException(); } /** * Returns the data as a String. * @throws InvalidTypeException if the data type is not {@link EventValueType#STRING}. * @see #getType() */ public final String getString() throws InvalidTypeException { if (getType(mData) == EventValueType.STRING) { return (String)mData; } throw new InvalidTypeException(); } /** * Returns a value by index. The return type is defined by its type. * @param valueIndex the index of the value. If the data is not a list, this is ignored. */ public Object getValue(int valueIndex) { return getValue(mData, valueIndex, true); } /** * Returns a value by index as a double. * @param valueIndex the index of the value. If the data is not a list, this is ignored. * @throws InvalidTypeException if the data type is not {@link EventValueType#INT}, * {@link EventValueType#LONG}, {@link EventValueType#LIST}, or if the item in the * list at index valueIndex is not of type {@link EventValueType#INT} or * {@link EventValueType#LONG}. * @see #getType() */ public double getValueAsDouble(int valueIndex) throws InvalidTypeException { return getValueAsDouble(mData, valueIndex, true); } /** * Returns a value by index as a String. * @param valueIndex the index of the value. If the data is not a list, this is ignored. * @throws InvalidTypeException if the data type is not {@link EventValueType#INT}, * {@link EventValueType#LONG}, {@link EventValueType#STRING}, {@link EventValueType#LIST}, * or if the item in the list at index valueIndex is not of type * {@link EventValueType#INT}, {@link EventValueType#LONG}, or {@link EventValueType#STRING} * @see #getType() */ public String getValueAsString(int valueIndex) throws InvalidTypeException { return getValueAsString(mData, valueIndex, true); } /** * Returns the type of the data. */ public EventValueType getType() { return getType(mData); } /** * Returns the type of an object. */ public final EventValueType getType(Object data) { if (data instanceof Integer) { return EventValueType.INT; } else if (data instanceof Long) { return EventValueType.LONG; } else if (data instanceof String) { return EventValueType.STRING; } else if (data instanceof Object[]) { // loop through the list to see if we have another list Object[] objects = (Object[])data; for (Object obj : objects) { EventValueType type = getType(obj); if (type == EventValueType.LIST || type == EventValueType.TREE) { return EventValueType.TREE; } } return EventValueType.LIST; } return EventValueType.UNKNOWN; } /** * Checks that the index-th value of this event against a provided value. * @param index the index of the value to test * @param value the value to test against * @param compareMethod the method of testing * @return true if the test passed. * @throws InvalidTypeException in case of type mismatch between the value to test and the value * to test against, or if the compare method is incompatible with the type of the values. * @see CompareMethod */ public boolean testValue(int index, Object value, CompareMethod compareMethod) throws InvalidTypeException { EventValueType type = getType(mData); if (index > 0 && type != EventValueType.LIST) { throw new InvalidTypeException(); } Object data = mData; if (type == EventValueType.LIST) { data = ((Object[])mData)[index]; } if (!data.getClass().equals(data.getClass())) { throw new InvalidTypeException(); } switch (compareMethod) { case EQUAL_TO: return data.equals(value); case LESSER_THAN: if (data instanceof Integer) { return (((Integer)data).compareTo((Integer)value) <= 0); } else if (data instanceof Long) { return (((Long)data).compareTo((Long)value) <= 0); } // other types can't use this compare method. throw new InvalidTypeException(); case LESSER_THAN_STRICT: if (data instanceof Integer) { return (((Integer)data).compareTo((Integer)value) < 0); } else if (data instanceof Long) { return (((Long)data).compareTo((Long)value) < 0); } // other types can't use this compare method. throw new InvalidTypeException(); case GREATER_THAN: if (data instanceof Integer) { return (((Integer)data).compareTo((Integer)value) >= 0); } else if (data instanceof Long) { return (((Long)data).compareTo((Long)value) >= 0); } // other types can't use this compare method. throw new InvalidTypeException(); case GREATER_THAN_STRICT: if (data instanceof Integer) { return (((Integer)data).compareTo((Integer)value) > 0); } else if (data instanceof Long) { return (((Long)data).compareTo((Long)value) > 0); } // other types can't use this compare method. throw new InvalidTypeException(); case BIT_CHECK: if (data instanceof Integer) { return ((Integer) data & (Integer) value) != 0; } else if (data instanceof Long) { return ((Long) data & (Long) value) != 0; } // other types can't use this compare method. throw new InvalidTypeException(); default : throw new InvalidTypeException(); } } private Object getValue(Object data, int valueIndex, boolean recursive) { EventValueType type = getType(data); switch (type) { case INT: case LONG: case STRING: return data; case LIST: if (recursive) { Object[] list = (Object[]) data; if (valueIndex >= 0 && valueIndex < list.length) { return getValue(list[valueIndex], valueIndex, false); } } } return null; } private double getValueAsDouble(Object data, int valueIndex, boolean recursive) throws InvalidTypeException { EventValueType type = getType(data); switch (type) { case INT: return ((Integer)data).doubleValue(); case LONG: return ((Long)data).doubleValue(); case STRING: throw new InvalidTypeException(); case LIST: if (recursive) { Object[] list = (Object[]) data; if (valueIndex >= 0 && valueIndex < list.length) { return getValueAsDouble(list[valueIndex], valueIndex, false); } } } throw new InvalidTypeException(); } private String getValueAsString(Object data, int valueIndex, boolean recursive) throws InvalidTypeException { EventValueType type = getType(data); switch (type) { case INT: return data.toString(); case LONG: return data.toString(); case STRING: return (String)data; case LIST: if (recursive) { Object[] list = (Object[]) data; if (valueIndex >= 0 && valueIndex < list.length) { return getValueAsString(list[valueIndex], valueIndex, false); } } else { throw new InvalidTypeException( "getValueAsString() doesn't support EventValueType.TREE"); } } throw new InvalidTypeException( "getValueAsString() unsupported type:" + type); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy