ss: Add serialization logic to state values
authorAlexandre Montplaisir <alexmonthy@efficios.com>
Sun, 10 Apr 2016 22:06:37 +0000 (18:06 -0400)
committerAlexandre Montplaisir <alexmonthy@efficios.com>
Tue, 12 Apr 2016 02:39:55 +0000 (22:39 -0400)
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 <alexmonthy@efficios.com>
Reviewed-on: https://git.eclipse.org/r/70337
Reviewed-by: Hudson CI
Reviewed-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Tested-by: Genevieve Bastien <gbastien+lttng@versatic.net>
statesystem/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/statevalue/StateValueTestBase.java
statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/DoubleStateValue.java
statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/ITmfStateValue.java
statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/IntegerStateValue.java
statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/LongStateValue.java
statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/NullStateValue.java
statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/StringStateValue.java
statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/statevalue/TmfStateValue.java

index 841ecc8589a7ac7e9b51b83ce056155d6c0091e4..16aa794841871131041abbafbd2b50427d85e120 100644 (file)
@@ -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);
+    }
 }
index d53c83c5602495583be8bc9afa09db0752ce3579..71785014da254dcb28e08b9ac4cefda9397222bd 100644 (file)
@@ -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
     // ------------------------------------------------------------------------
index a5a9e864032b954b9f514e29025a61377b1aa48a..490f51e683a09965cf0c7819877adeb4d14e6583 100644 (file)
@@ -24,17 +24,61 @@ public interface ITmfStateValue extends Comparable<ITmfStateValue> {
     /**
      * 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<ITmfStateValue> {
      */
     String unboxStr();
 
+    /**
+     * Serialize this state value into a byte array.
+     *
+     * The format of this array should always be:
+     *
+     * <pre>[type byte][payload]</pre>
+     *
+     * and the type will determine the layout of [payload].
+     *
+     * @return The serialized form of the state value
+     * @since 2.0
+     */
+    byte[] serialize();
+
 }
index 41216f2153ca8395bf771dffd6664ccefe8ed575..54eb5c80308f779570144122d3adf04611d9831e 100644 (file)
@@ -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 {
         }
 
     }
-
 }
index 0770024a133d99979f43d7b0a510abbe2171385f..dae703845a8e4fb271b098cec5be9199e25ae2b5 100644 (file)
@@ -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
     // ------------------------------------------------------------------------
index c71d71c0b65d09eafc986feefd4d45fd23b605c4..d096bcb6c4faeb889f484b4ab5340687b5cf81a3 100644 (file)
@@ -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));
     }
-
 }
index 4e56b8f6efa7186b3e7335c07fb8ec7328af5a9a..635bdea40562426c2d27dd2403aaf0894d34d46a 100644 (file)
@@ -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
     // ------------------------------------------------------------------------
index c724410d21706952447b59424e33a6d8411b5bf1..e781238a12f18c5a4c6f5802102ddbdf6b92d9b7 100644 (file)
@@ -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
      *
This page took 0.030884 seconds and 5 git commands to generate.