From: Alexandre Montplaisir Date: Sun, 10 Apr 2016 22:06:37 +0000 (-0400) Subject: ss: Add serialization logic to state values X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=ce148788289534e20b56d0790a8ad93ce2e6473d;p=deliverable%2Ftracecompass.git ss: Add serialization logic to state values Right now the HTInterval object takes care of state value serialization. This is a bad separation of responsibilities, the state value itself should be the master of its destiny. Implement state value serialization to and from byte arrays. In a second step, the HT can be moved to use that logic instead of its own. Change-Id: I1d3379e0a4d7d82816164ae214838462ab28c5fd Signed-off-by: Alexandre Montplaisir Reviewed-on: https://git.eclipse.org/r/70337 Reviewed-by: Hudson CI Reviewed-by: Genevieve Bastien Tested-by: Genevieve Bastien --- diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/statevalue/StateValueTestBase.java b/statesystem/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/statevalue/StateValueTestBase.java index 841ecc8589..16aa794841 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/statevalue/StateValueTestBase.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/statevalue/StateValueTestBase.java @@ -85,4 +85,18 @@ public abstract class StateValueTestBase { public void testIsNull() { assertFalse(getStateValueFixture().isNull()); } + + /** + * Test state value serialization and deserialization, using + * {@link ITmfStateValue#serialize()} and + * {@link TmfStateValue#readSerializedValue}. + */ + @Test + public void testSerialization() { + ITmfStateValue initialValue = getStateValueFixture(); + byte[] serializedValue = initialValue.serialize(); + ITmfStateValue readValue = TmfStateValue.readSerializedValue(serializedValue); + + assertEquals(initialValue, readValue); + } } diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/DoubleStateValue.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/DoubleStateValue.java index d53c83c560..71785014da 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/DoubleStateValue.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/DoubleStateValue.java @@ -12,6 +12,8 @@ package org.eclipse.tracecompass.statesystem.core.statevalue; +import java.nio.ByteBuffer; + import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; @@ -58,6 +60,14 @@ final class DoubleStateValue extends TmfStateValue { return String.format("%3f", value); //$NON-NLS-1$ } + @Override + public byte[] serialize() { + ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES + Double.BYTES); + buffer.put(getType().getByte()); + buffer.putDouble(value); + return buffer.array(); + } + // ------------------------------------------------------------------------ // Unboxing methods // ------------------------------------------------------------------------ diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/ITmfStateValue.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/ITmfStateValue.java index a5a9e86403..490f51e683 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/ITmfStateValue.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/ITmfStateValue.java @@ -24,17 +24,61 @@ public interface ITmfStateValue extends Comparable { /** * The supported types of state values */ - public enum Type { + enum Type { + /** Null value, for an interval not carrying any information */ - NULL, + NULL((byte) -1), /** 32-bit integer value */ - INTEGER, + INTEGER((byte) 0), /** 64-bit integer value */ - LONG, + LONG((byte) 1), /** IEEE 754 double precision number */ - DOUBLE, + DOUBLE((byte) 2), /** Variable-length string value */ - STRING, + STRING((byte) 3); + + private final byte fTypeByte; + + private Type(byte type) { + fTypeByte = type; + } + + /** + * Get the corresponding Type from its byte representation. + * + * @param type + * The type byte + * @return The corresponding Type enum element + * @throws IllegalArgumentException + * If the type byte is not recognized + * @since 2.0 + */ + public static Type getTypeFromByte(byte type) { + switch (type) { + case -1: + return NULL; + case 0: + return INTEGER; + case 1: + return LONG; + case 2: + return DOUBLE; + case 3: + return STRING; + default: + throw new IllegalArgumentException(); + } + } + + /** + * Get the byte representation of this type. + * + * @return The type byte + * @since 2.0 + */ + public byte getByte() { + return fTypeByte; + } } /** @@ -90,4 +134,18 @@ public interface ITmfStateValue extends Comparable { */ String unboxStr(); + /** + * Serialize this state value into a byte array. + * + * The format of this array should always be: + * + *
[type byte][payload]
+ * + * and the type will determine the layout of [payload]. + * + * @return The serialized form of the state value + * @since 2.0 + */ + byte[] serialize(); + } diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/IntegerStateValue.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/IntegerStateValue.java index 41216f2153..54eb5c8030 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/IntegerStateValue.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/IntegerStateValue.java @@ -12,6 +12,8 @@ package org.eclipse.tracecompass.statesystem.core.statevalue; +import java.nio.ByteBuffer; + import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; @@ -58,6 +60,14 @@ final class IntegerStateValue extends TmfStateValue { return String.format("%3d", value); //$NON-NLS-1$ } + @Override + public byte[] serialize() { + ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES + Integer.BYTES); + buffer.put(getType().getByte()); + buffer.putInt(value); + return buffer.array(); + } + // ------------------------------------------------------------------------ // Unboxing methods // ------------------------------------------------------------------------ @@ -98,5 +108,4 @@ final class IntegerStateValue extends TmfStateValue { } } - } diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/LongStateValue.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/LongStateValue.java index 0770024a13..dae703845a 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/LongStateValue.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/LongStateValue.java @@ -12,6 +12,8 @@ package org.eclipse.tracecompass.statesystem.core.statevalue; +import java.nio.ByteBuffer; + import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; @@ -58,6 +60,14 @@ final class LongStateValue extends TmfStateValue { return String.format("%3d", value); //$NON-NLS-1$ } + @Override + public byte[] serialize() { + ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES + Long.BYTES); + buffer.put(getType().getByte()); + buffer.putLong(value); + return buffer.array(); + } + // ------------------------------------------------------------------------ // Unboxing methods // ------------------------------------------------------------------------ diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/NullStateValue.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/NullStateValue.java index c71d71c0b6..d096bcb6c4 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/NullStateValue.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/NullStateValue.java @@ -25,7 +25,8 @@ import org.eclipse.jdt.annotation.Nullable; */ final class NullStateValue extends TmfStateValue { - private final String value = "nullValue"; //$NON-NLS-1$ + private static final byte[] EMPTY_ARRAY = new byte[0]; + private static final String STR_VALUE = "nullValue"; //$NON-NLS-1$ @Override public Type getType() { @@ -49,7 +50,12 @@ final class NullStateValue extends TmfStateValue { @Override public String toString() { - return value; + return STR_VALUE; + } + + @Override + public byte[] serialize() { + return EMPTY_ARRAY; } // ------------------------------------------------------------------------ @@ -73,7 +79,7 @@ final class NullStateValue extends TmfStateValue { @Override public String unboxStr() { - return value; + return STR_VALUE; } @Override @@ -90,5 +96,4 @@ final class NullStateValue extends TmfStateValue { */ return -(other.compareTo(this)); } - } diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/StringStateValue.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/StringStateValue.java index 4e56b8f6ef..635bdea405 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/StringStateValue.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/StringStateValue.java @@ -12,6 +12,8 @@ package org.eclipse.tracecompass.statesystem.core.statevalue; +import java.nio.ByteBuffer; + import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; @@ -58,6 +60,15 @@ final class StringStateValue extends TmfStateValue { return value; } + @Override + public byte[] serialize() { + byte[] strBytes = value.getBytes(); + ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES + strBytes.length); + buffer.put(getType().getByte()); + buffer.put(strBytes); + return buffer.array(); + } + // ------------------------------------------------------------------------ // Unboxing methods // ------------------------------------------------------------------------ diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/TmfStateValue.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/TmfStateValue.java index c724410d21..e781238a12 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/TmfStateValue.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/TmfStateValue.java @@ -12,6 +12,8 @@ package org.eclipse.tracecompass.statesystem.core.statevalue; +import java.nio.ByteBuffer; + import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.internal.statesystem.core.Activator; import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; @@ -61,6 +63,55 @@ public abstract class TmfStateValue implements ITmfStateValue { return nullValue; } + /** + * Read a serialized value (obtained with the {@link #serialize()} method) + * into a real {@link TmfStateValue} object. + * + * @param array + * The serialized state value + * @return The state value object + * @since 2.0 + */ + public static TmfStateValue readSerializedValue(byte[] array) { + if (array.length == 0) { + /* This represents a null value */ + return nullValue; + } + + ByteBuffer buffer = ByteBuffer.wrap(array); + + byte typeByte = buffer.get(); + Type type = Type.getTypeFromByte(typeByte); + switch (type) { + case NULL: { + /* Should have been an empty array, but we'll accept it anyway */ + return nullValue; + } + case INTEGER: { + int value = buffer.getInt(); + return newValueInt(value); + } + case LONG: { + long value = buffer.getLong(); + return newValueLong(value); + } + case DOUBLE: { + double value = buffer.getDouble(); + return newValueDouble(value); + } + case STRING: { + /* The remaining of the buffer is the string's bytes */ + int size = array.length - 1; + byte[] strBytes = new byte[size]; + buffer.get(strBytes); + String value = new String(strBytes); + return newValueString(value); + } + default: + throw new IllegalArgumentException(); + } + } + /** * Factory constructor for Integer state values *