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);
+ }
}
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;
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
// ------------------------------------------------------------------------
/**
* 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;
+ }
}
/**
*/
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();
+
}
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;
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
// ------------------------------------------------------------------------
}
}
-
}
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;
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
// ------------------------------------------------------------------------
*/
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() {
@Override
public String toString() {
- return value;
+ return STR_VALUE;
+ }
+
+ @Override
+ public byte[] serialize() {
+ return EMPTY_ARRAY;
}
// ------------------------------------------------------------------------
@Override
public String unboxStr() {
- return value;
+ return STR_VALUE;
}
@Override
*/
return -(other.compareTo(this));
}
-
}
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;
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
// ------------------------------------------------------------------------
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;
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
*