import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+import org.eclipse.tracecompass.statesystem.core.tests.stubs.statevalues.CustomStateValueStub;
import org.junit.Test;
import com.google.common.collect.ImmutableList;
int longQuark = 1;
int doubleQuark = 2;
int strQuark = 3;
+ int customQuark = 4;
+ /* Register custom factory and create a custom state value */
+ CustomStateValueStub.registerFactory();
+ ITmfStateValue customVal = new CustomStateValueStub(10, "a string");
try {
IStateHistoryBackend backend = getBackendForBuilding(startTime);
assertEquals("String interval end time", startTime + timeStep, interval.getEndTime());
assertEquals("String interval value", STR_VAL1, interval.getStateValue());
+ /* Custom state values */
+ backend.insertPastState(startTime, startTime + timeStep, customQuark, customVal);
+ interval = backend.doSingularQuery(startTime, customQuark);
+
+ assertEquals("Custom interval start time", startTime, interval.getStartTime());
+ assertEquals("Custom interval end time", startTime + timeStep, interval.getEndTime());
+ assertEquals("Custom interval value", customVal, interval.getStateValue());
+
/*
* Add other intervals for the int quark and query at different
* times
int longQuark = 1;
int doubleQuark = 2;
int strQuark = 3;
- int nbAttribs = 4;
+ int customQuark = 4;
+ int nbAttribs = 5;
+ /* Register custom factory and create custom state values */
+ CustomStateValueStub.registerFactory();
+ ITmfStateValue customVal = new CustomStateValueStub(10, "a string");
+ ITmfStateValue customVal2 = new CustomStateValueStub(Short.MAX_VALUE, "another string");
try {
IStateHistoryBackend backend = getBackendForBuilding(startTime);
new TmfStateInterval(startTime, startTime + timeStep, longQuark, LONG_VAL1),
new TmfStateInterval(startTime, startTime + timeStep, doubleQuark, DOUBLE_VAL1),
new TmfStateInterval(startTime, startTime + timeStep, strQuark, STR_VAL1),
+ new TmfStateInterval(startTime, startTime + timeStep, customQuark, customVal),
new TmfStateInterval(nextStart, endTime, intQuark, INT_VAL2),
new TmfStateInterval(nextStart, endTime, longQuark, LONG_VAL2),
new TmfStateInterval(nextStart, endTime, doubleQuark, DOUBLE_VAL2),
- new TmfStateInterval(nextStart, endTime, strQuark, STR_VAL2)));
+ new TmfStateInterval(nextStart, endTime, strQuark, STR_VAL2),
+ new TmfStateInterval(nextStart, endTime, customQuark, customVal2)));
backend.finishedBuilding(endTime);
interval = intervals.get(strQuark);
assertNotNull(interval);
assertEquals("String value after read", STR_VAL1, interval.getStateValue());
+ /* Custom */
+ interval = intervals.get(customQuark);
+ assertNotNull(interval);
+ assertEquals("String value after read", customVal, interval.getStateValue());
/* Do a full query at the end and verify the values */
backendQuery.doQuery(intervals, endTime);
interval = intervals.get(strQuark);
assertNotNull(interval);
assertEquals("String value after read", STR_VAL2, interval.getStateValue());
+ /* Custom */
+ interval = intervals.get(customQuark);
+ assertNotNull(interval);
+ assertEquals("String value after read", customVal2, interval.getStateValue());
} catch (TimeRangeException | IOException | StateSystemDisposedException e) {
fail(e.getMessage());
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.tests.statevalue;
+
+import static org.junit.Assert.assertEquals;
+
+import java.nio.ByteBuffer;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.CustomStateValue;
+import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.ISafeByteBufferReader;
+import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.ISafeByteBufferWriter;
+import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.SafeByteBufferFactory;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue.Type;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+import org.eclipse.tracecompass.statesystem.core.tests.stubs.statevalues.CustomStateValueStub;
+import org.junit.Test;
+
+/**
+ * Test the {@link CustomStateValue} class
+ *
+ * @author Geneviève Bastien
+ */
+public class CustomStateValueTest extends StateValueTestBase {
+
+ private static final CustomStateValue VALUE = new CustomStateValueStub(3, "MyString");
+
+ @Override
+ protected @NonNull ITmfStateValue getStateValueFixture() {
+ return VALUE;
+ }
+
+ @Override
+ protected @NonNull Type getStateValueType() {
+ return Type.CUSTOM;
+ }
+
+ /**
+ * Test serialization/unserialization with the factory present
+ */
+ @Test
+ public void testSerialization() {
+ CustomStateValueStub.registerFactory();
+ ByteBuffer buffer = ByteBuffer.allocate(1024);
+ ISafeByteBufferWriter safeBufferWriter = SafeByteBufferFactory.wrapWriter(buffer, VALUE.getSerializedSize());
+ VALUE.serialize(safeBufferWriter);
+
+ // Reset buffer
+ buffer.flip();
+ ISafeByteBufferReader safeBufferReader = SafeByteBufferFactory.wrapReader(buffer, VALUE.getSerializedSize());
+ TmfStateValue read = CustomStateValue.readSerializedValue(safeBufferReader);
+ assertEquals("Custom state value: no factory", VALUE, read);
+ }
+
+ /**
+ * Test serialization/unserialization if no factory is available
+ */
+ @Test
+ public void testNoFactoryAvailable() {
+ CustomStateValueStub.unregisterFactory();
+ ByteBuffer buffer = ByteBuffer.allocate(1024);
+ ISafeByteBufferWriter safeBufferWriter = SafeByteBufferFactory.wrapWriter(buffer, VALUE.getSerializedSize());
+ VALUE.serialize(safeBufferWriter);
+
+ // Reset buffer
+ buffer.flip();
+ ISafeByteBufferReader safeBufferReader = SafeByteBufferFactory.wrapReader(buffer, VALUE.getSerializedSize());
+ TmfStateValue read = CustomStateValue.readSerializedValue(safeBufferReader);
+ assertEquals("Custom state value: no factory", TmfStateValue.nullValue(), read);
+ }
+
+ /**
+ * Test the exception when asking a size too large
+ */
+ @Test(expected = ArrayIndexOutOfBoundsException.class)
+ public void testSerializedTooLarge() {
+ String alphabet = "abcdefghijklmnopqrstuvwxyz";
+ StringBuilder builder = new StringBuilder();
+ while (builder.length() < Short.MAX_VALUE) {
+ builder.append(alphabet);
+ }
+ CustomStateValue sv = new CustomStateValueStub(3, builder.toString());
+ sv.getSerializedSize();
+ }
+
+ /**
+ * Test the illegal argument exception with custom forbidden custom IDs
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testWrongCustomId() {
+ CustomStateValue.registerCustomFactory((byte) 0, CustomStateValueStub.FACTORY);
+ }
+
+ /**
+ * Test the illegal argument exception with custom forbidden custom IDs
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testWrongCustomId2() {
+ CustomStateValue.registerCustomFactory((byte) 20, CustomStateValueStub.FACTORY);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.statesystem.core.tests.stubs.statevalues;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.CustomStateValue;
+import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.ISafeByteBufferWriter;
+import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.SafeByteBufferFactory;
+import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
+
+/**
+ * A custom state value stub containing an integer field and a string.
+ *
+ * Before using this stub in a unit test when there is a need to
+ * serialize/unserialize this class, the factory should be registered by calling
+ * the {@link #registerFactory()} method
+ *
+ * @author Geneviève Bastien
+ */
+public class CustomStateValueStub extends CustomStateValue {
+
+ /**
+ * The factory to rebuild the state value
+ */
+ public static final CustomStateValueFactory FACTORY = (b) -> {
+ int val = b.getInt();
+ String str = b.getString();
+ return new CustomStateValueStub(val, str);
+ };
+
+ /** Custom type ID */
+ private static final byte CUSTOM_TYPE_ID = 87;
+
+ private final int fIntField;
+ private final String fStringField;
+
+ /**
+ * Constructor
+ *
+ * @param val
+ * the integer value
+ * @param str
+ * the string value
+ */
+ public CustomStateValueStub(int val, String str) {
+ fIntField = val;
+ fStringField = str;
+ }
+
+ /**
+ * Registers the factory for this custom state value type
+ */
+ public static void registerFactory() {
+ CustomStateValue.registerCustomFactory(CUSTOM_TYPE_ID, FACTORY);
+ }
+
+ /**
+ * Registers the factory for this custom state value type
+ */
+ public static void unregisterFactory() {
+ CustomStateValue.unregisterCustomFactory(CUSTOM_TYPE_ID);
+ }
+
+ @Override
+ public int compareTo(@Nullable ITmfStateValue o) {
+ if (o == null) {
+ throw new IllegalArgumentException();
+ }
+ if (!(o instanceof CustomStateValueStub)) {
+ throw new StateValueTypeException("Need a TestCustomStateValue object to compare to"); //$NON-NLS-1$
+ }
+ CustomStateValueStub other = (CustomStateValueStub) o;
+ int cmp = Integer.compare(fIntField, other.fIntField);
+ if (cmp == 0) {
+ cmp = fStringField.compareTo(other.fStringField);
+ }
+ return cmp;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object arg0) {
+ if (!(arg0 instanceof CustomStateValueStub)) {
+ return false;
+ }
+ CustomStateValueStub tcsv = (CustomStateValueStub) arg0;
+ return (fIntField == tcsv.fIntField) && fStringField.equals(tcsv.fStringField);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + fIntField;
+ result = prime * result + fStringField.hashCode();
+ return result;
+ }
+
+ @Override
+ protected @NonNull Byte getCustomTypeId() {
+ return CUSTOM_TYPE_ID;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + fIntField + "," + fStringField + "]";
+ }
+
+ @Override
+ protected void serializeValue(@NonNull ISafeByteBufferWriter buffer) {
+ buffer.putInt(fIntField);
+ buffer.putString(fStringField);
+ }
+
+ @Override
+ protected int getSerializedValueSize() {
+ return Integer.BYTES + SafeByteBufferFactory.getStringSizeInBuffer(fStringField);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.eclipse.tracecompass.statesystem.core.tests.stubs.statevalues;
org.eclipse.tracecompass.statesystem.core.exceptions,
org.eclipse.tracecompass.statesystem.core.interval,
org.eclipse.tracecompass.statesystem.core.statevalue
-Import-Package: com.google.common.base,
+Import-Package: com.google.common.annotations;version="15.0.0",
+ com.google.common.base,
com.google.common.collect;version="12.0.0"
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue;
+
+import java.nio.BufferOverflowException;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.statesystem.core.Activator;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * This allows to define custom state values.
+ *
+ * Each sub-class should define a {@link CustomStateValueFactory} that has to be
+ * registered, for example by the analysis using this state value type, through
+ * the
+ * {@link CustomStateValue#registerCustomFactory(byte, CustomStateValueFactory)}
+ * method.
+ *
+ * Note to implementers: These state values are meant to be used in data
+ * structures that save information on objects that varies in time, like a state
+ * system. It will often be made persistent on disk at some point, so it is
+ * suggested to make the child classes immutable.
+ *
+ * Data structures using these custom values will often keep the values in a
+ * transient state before they are sent to be persisted. For persistence, it
+ * will request the size of the value, then write its bytes to a buffer. Once
+ * the size is requested, the value is about to be saved, so it is important
+ * that its value and size do not change after that, as it may get in an
+ * incoherent state, or, worse throw runtime exceptions.
+ *
+ * @author Geneviève Bastien
+ * @since 2.0
+ */
+public abstract class CustomStateValue extends TmfStateValue {
+
+ /* Minimum size of the state value */
+ private static final int MIN_SIZE = Byte.BYTES;
+
+ /**
+ * Custom value factory interface. Each custom state value should have a
+ * corresponding factory to re-create the object from a ByteBuffer
+ */
+ @FunctionalInterface
+ public interface CustomStateValueFactory {
+
+ /**
+ * Get the custom state value from a byte buffer
+ *
+ * @param buffer
+ * the byte buffer
+ * @return the custom state value
+ */
+ CustomStateValue readCustomValue(ISafeByteBufferReader buffer);
+ }
+
+ private static final CustomStateValueFactory[] CUSTOM_FACTORIES = new CustomStateValueFactory[256];
+
+ /**
+ * Register the custom factory that will be reused to create instances of
+ * custom state value objects
+ *
+ * @param customId
+ * The ID of this custom type. For possible values of this ID,
+ * see {@link #getCustomTypeId()}
+ * @param factory
+ * The factory used to create a new custom type object of this ID
+ */
+ public static void registerCustomFactory(byte customId, CustomStateValueFactory factory) {
+ if (customId >= 0 && customId <= 20) {
+ throw new IllegalArgumentException("State value IDs between 0 and 20 are reserved for built-in state value types"); //$NON-NLS-1$
+ }
+ CustomStateValueFactory currentFactory = CUSTOM_FACTORIES[customId - Byte.MIN_VALUE];
+ if (currentFactory == null) {
+ CUSTOM_FACTORIES[customId - Byte.MIN_VALUE] = factory;
+ } else if (currentFactory != factory) {
+ throw new IllegalStateException("Already a custom factory registered for " + Byte.toString(customId)); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Unregisters the custom factory
+ *
+ * @param customId
+ * The ID of this custom type
+ */
+ @VisibleForTesting
+ protected static void unregisterCustomFactory(byte customId) {
+ CUSTOM_FACTORIES[customId - Byte.MIN_VALUE] = null;
+ }
+
+ /**
+ * Get the custom factory for a byte
+ *
+ * @param customId
+ * the custom factory key
+ * @return the custom factory or null if none is registered for the key
+ */
+ public static @Nullable CustomStateValueFactory getCustomFactory(byte customId) {
+ return CUSTOM_FACTORIES[customId - Byte.MIN_VALUE];
+ }
+
+ /**
+ * Read a serialized value (obtained with the
+ * {@link #serialize(ISafeByteBufferWriter)} method) into a real
+ * {@link CustomStateValue} object.
+ *
+ * @param buffer
+ * The byte buffer to read from
+ * @return The state value object
+ */
+ public static TmfStateValue readSerializedValue(ISafeByteBufferReader buffer) {
+ /* the first byte = the custom type id */
+ byte customType = buffer.get();
+ CustomStateValueFactory customFactory = CustomStateValue.getCustomFactory(customType);
+ if (customFactory == null) {
+ Activator.getDefault().logWarning("Custom factory for type " + customType + " does not exist"); //$NON-NLS-1$ //$NON-NLS-2$
+ return TmfStateValue.nullValue();
+ }
+
+ return customFactory.readCustomValue(buffer);
+ }
+
+ /**
+ * Get custom type id. The value should be between {@link Byte#MIN_VALUE}
+ * and {@link Byte#MAX_VALUE}, but not between {@code 0} and {@code 20} that
+ * are reserved for built-in state value types.
+ *
+ * @return the custom type ID
+ */
+ protected abstract Byte getCustomTypeId();
+
+ /**
+ * Serialize this state value into the byte buffer. This method should only
+ * write the payload of the state value and should match what will be read
+ * by the factory when deserializing.
+ *
+ * This serialized value must contain all the payload of the state value
+ *
+ * @param buffer
+ * The ByteBuffer to write the values to
+ */
+ protected abstract void serializeValue(ISafeByteBufferWriter buffer);
+
+ /**
+ * Get the serialized size of this state value. The size must not exceed
+ * {@link Short#MAX_VALUE - MIN_SIZE}, otherwise serialization might throw a
+ * {@link BufferOverflowException}
+ *
+ * @return The serialized size of this state value
+ */
+ protected abstract int getSerializedValueSize();
+
+ /**
+ * Serialize this custom state value into a byte buffer. It calls the
+ * serialization of the state value itself and adds the specific fields to
+ * interpret that byte array.
+ *
+ * The format of the value is [custom type (byte)][payload]
+ *
+ * The total serialized size should never exceed {@link Short#MAX_VALUE}
+ *
+ * @param buffer
+ * The ByteBuffer to write the values to
+ *
+ * @throws BufferOverflowException
+ * If the serialized size of the value ends up larger than the
+ * maximum of {@link Short#MAX_VALUE} and the implementation has
+ * no way of handling it
+ */
+ public final void serialize(ISafeByteBufferWriter buffer) {
+ buffer.put(getCustomTypeId());
+ serializeValue(buffer);
+ }
+
+ /**
+ * Get the serialized size of this state value. This size will be used to
+ * allow the buffer that will be sent to the
+ * {@link #serialize(ISafeByteBufferWriter)} method
+ *
+ * @return The size of the serialized value
+ */
+ public final int getSerializedSize() {
+ int size = getSerializedValueSize();
+ if (size > Short.MAX_VALUE - MIN_SIZE) {
+ throw new ArrayIndexOutOfBoundsException("Serialized state value is larger than the maximum allowed size of " + (Short.MAX_VALUE - MIN_SIZE) + ": " + size); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return size + MIN_SIZE;
+ }
+
+ @Override
+ public final Type getType() {
+ return Type.CUSTOM;
+ }
+
+ @Override
+ public boolean isNull() {
+ return false;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ericsson - Initial API and implementation
+ *******************************************************************************/
+@org.eclipse.jdt.annotation.NonNullByDefault package org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue;
import java.nio.ByteBuffer;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.CustomStateValue;
+import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.ISafeByteBufferReader;
+import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.ISafeByteBufferWriter;
+import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.SafeByteBufferFactory;
import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
*/
return (minSize + sv.unboxStr().getBytes().length + 2);
case CUSTOM:
+ /* Length of serialized value (short) + state value */
+ return (minSize + Short.BYTES + ((CustomStateValue) sv).getSerializedSize());
default:
/*
* It's very important that we know how to write the state value in
* If there was an error reading from the buffer
*/
public static final HTInterval readFrom(ByteBuffer buffer) throws IOException {
- HTInterval interval;
- long intervalStart, intervalEnd;
- int attribute;
TmfStateValue value;
- byte valueType;
- byte array[];
int posStart = buffer.position();
/* Read the Data Section entry */
- intervalStart = buffer.getLong();
- intervalEnd = buffer.getLong();
- attribute = buffer.getInt();
+ long intervalStart = buffer.getLong();
+ long intervalEnd = buffer.getLong();
+ int attribute = buffer.getInt();
/* Read the 'type' of the value, then react accordingly */
- valueType = buffer.get();
+ byte valueType = buffer.get();
switch (valueType) {
case TYPE_NULL:
value = TmfStateValue.newValueInt(buffer.getInt());
break;
- case TYPE_STRING:
+ case TYPE_STRING: {
/* the first byte = the size to read */
int valueSize = buffer.get();
- array = new byte[valueSize];
+ byte[] array = new byte[valueSize];
buffer.get(array);
value = TmfStateValue.newValueString(new String(array));
throw new IOException(errMsg);
}
break;
+ }
case TYPE_LONG:
/* Go read the matching entry in the Strings section of the block */
value = TmfStateValue.newValueDouble(buffer.getDouble());
break;
- case TYPE_CUSTOM:
+ case TYPE_CUSTOM: {
+ short valueSize = buffer.getShort();
+ ISafeByteBufferReader safeBuffer = SafeByteBufferFactory.wrapReader(buffer, valueSize);
+ value = CustomStateValue.readSerializedValue(safeBuffer);
+ break;
+ }
default:
/* Unknown data, better to not make anything up... */
throw new IOException(errMsg);
}
try {
- interval = new HTInterval(intervalStart, intervalEnd, attribute, value, buffer.position() - posStart);
+ return new HTInterval(intervalStart, intervalEnd, attribute, value, buffer.position() - posStart);
} catch (TimeRangeException e) {
throw new IOException(errMsg);
}
- return interval;
}
/**
buffer.putInt(sv.unboxInt());
break;
- case TYPE_STRING:
+ case TYPE_STRING: {
String string = sv.unboxStr();
byte[] strArray = string.getBytes();
buffer.put(strArray);
buffer.put((byte) 0);
break;
+ }
case TYPE_LONG:
buffer.putLong(sv.unboxLong());
buffer.putDouble(sv.unboxDouble());
break;
+ case TYPE_CUSTOM: {
+ int size = ((CustomStateValue) sv).getSerializedSize();
+ buffer.putShort((short) size);
+ ISafeByteBufferWriter safeBuffer = SafeByteBufferFactory.wrapWriter(buffer, size);
+ ((CustomStateValue) sv).serialize(safeBuffer);
+ break;
+ }
+
default:
break;
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ericsson - Initial API and implementation
+ *******************************************************************************/
+@org.eclipse.jdt.annotation.NonNullByDefault package org.eclipse.tracecompass.internal.statesystem.core.statevalue;