tmf : Introduce pattern segment and pattern segment builder
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.analysis.xml.core / src / org / eclipse / tracecompass / tmf / analysis / xml / core / segment / TmfXmlPatternSegment.java
1 /*******************************************************************************
2 * Copyright (c) 2016 Ecole Polytechnique de Montreal, Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 ******************************************************************************/
9 package org.eclipse.tracecompass.tmf.analysis.xml.core.segment;
10
11 import java.io.IOException;
12 import java.io.ObjectInputStream;
13 import java.io.ObjectOutputStream;
14 import java.util.Collections;
15 import java.util.Comparator;
16 import java.util.HashMap;
17 import java.util.Map;
18
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.eclipse.tracecompass.segmentstore.core.ISegment;
22 import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;
23 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
24 import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
25 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
26 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
27
28 import com.google.common.collect.Ordering;
29
30 /**
31 * This class implements an XML Pattern Segment. This type of segment has
32 * content and a default timestamp, which is the start time of the segment.
33 *
34 * @author Jean-Christian Kouame
35 * @since 2.0
36 *
37 */
38 public class TmfXmlPatternSegment implements ISegment {
39
40 /**
41 * The serial version UID
42 */
43 private static final long serialVersionUID = 3556323761465412078L;
44
45 /* 'Byte' equivalent for state values types */
46 private static final byte TYPE_NULL = -1;
47 private static final byte TYPE_INTEGER = 0;
48 private static final byte TYPE_STRING = 1;
49 private static final byte TYPE_LONG = 2;
50
51 private static final @NonNull Comparator<ISegment> COMPARATOR = Ordering
52 .from(SegmentComparators.INTERVAL_START_COMPARATOR)
53 .compound(SegmentComparators.INTERVAL_END_COMPARATOR)
54 /* Kind of lazy, but should work! */
55 .compound(Ordering.usingToString());
56
57 private final int fScale;
58 private final long fStart;
59 private final long fEnd;
60 private final String fSegmentName;
61 private transient Map<@NonNull String, @NonNull ITmfStateValue> fContent;
62
63 /**
64 * Constructs an XML pattern segment
65 *
66 * @param start
67 * Start time of the pattern segment
68 * @param end
69 * End time of the pattern segment
70 * @param scale
71 * Scale of the pattern segment
72 * @param segmentName
73 * Name of the pattern segment
74 * @param fields
75 * Fields of the pattern segment
76 */
77 public TmfXmlPatternSegment(long start, long end, int scale, String segmentName, @NonNull Map<@NonNull String, @NonNull ITmfStateValue> fields) {
78 fStart = start;
79 fEnd = end;
80 fScale = scale;
81 fSegmentName = segmentName;
82 fContent = Collections.unmodifiableMap(fields);
83 }
84
85 /**
86 * Get the start timestamp of the segment
87 *
88 * @return The start timestamp
89 */
90 public @NonNull ITmfTimestamp getTimestampStart() {
91 return new TmfTimestamp(fStart, fScale);
92 }
93
94 /**
95 * Get the end timestamp of this segment
96 *
97 * @return The end timestamp
98 */
99 public @NonNull ITmfTimestamp getTimestampEnd() {
100 return new TmfTimestamp(fEnd, fScale);
101 }
102
103 /**
104 * Get the content of the pattern segment
105 * @return The content
106 */
107 public Map<@NonNull String, @NonNull ITmfStateValue> getContent() {
108 return fContent;
109 }
110
111 /**
112 * Get the name of pattern segment
113 * @return The name
114 */
115 public String getName() {
116 return fSegmentName;
117 }
118
119 /**
120 * Get the timestamp scale of the pattern segment
121 * @return The timestamp scale
122 */
123 public int getScale() {
124 return fScale;
125 }
126
127 @Override
128 public int compareTo(@Nullable ISegment o) {
129 if (o == null) {
130 throw new IllegalArgumentException("Cannot compare to null"); //$NON-NLS-1$
131 }
132 return COMPARATOR.compare(this, o);
133 }
134
135 @Override
136 public long getStart() {
137 return fStart;
138 }
139
140 @Override
141 public long getEnd() {
142 return fEnd;
143 }
144
145 @Override
146 public String toString() {
147 return new StringBuilder(getClass().getSimpleName())
148 .append(", [fTimestampStart=").append(getTimestampStart()) //$NON-NLS-1$
149 .append(", fTimestampEnd=").append(getTimestampEnd()) //$NON-NLS-1$
150 .append(", duration= ").append(getLength()) //$NON-NLS-1$
151 .append(", fName=").append(getName()) //$NON-NLS-1$
152 .append(", fContent=").append(getContent()) //$NON-NLS-1$
153 .append("]").toString(); //$NON-NLS-1$
154 }
155
156 private void writeObject(ObjectOutputStream out) throws IOException {
157 out.defaultWriteObject();
158
159 // Write the number of fields
160 out.writeInt(fContent.size());
161
162 // Write the fields
163 for (Map.Entry<String, ITmfStateValue> entry : fContent.entrySet()) {
164 out.writeInt(entry.getKey().length());
165 out.writeBytes(entry.getKey());
166 final ITmfStateValue value = entry.getValue();
167 final byte type = getByteFromType(value.getType());
168 out.writeByte(type);
169 switch (type) {
170 case TYPE_NULL:
171 break;
172 case TYPE_INTEGER:
173 out.writeInt(value.unboxInt());
174 break;
175 case TYPE_LONG:
176 out.writeLong(value.unboxLong());
177 break;
178 case TYPE_STRING:
179 final @NonNull String string = value.unboxStr();
180 out.writeInt(string.length());
181 out.writeBytes(string);
182 break;
183 default:
184 throw new IOException("Write object failed : Invalid data"); //$NON-NLS-1$
185 }
186 }
187 }
188
189 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
190 in.defaultReadObject();
191 int contentSize = in.readInt();
192
193 final Map<@NonNull String, @NonNull ITmfStateValue> content = new HashMap<>();
194 for (int i = 0; i < contentSize; i++) {
195 int length = in.readInt();
196 byte[] bytes = new byte[length];
197 in.read(bytes, 0, length);
198 String name = new String(bytes);
199
200 Byte type = in.readByte();
201 ITmfStateValue value;
202 switch (type) {
203 case TYPE_NULL:
204 value = TmfStateValue.nullValue();
205 break;
206 case TYPE_INTEGER:
207 value = TmfStateValue.newValueInt(in.readInt());
208 break;
209 case TYPE_LONG:
210 value = TmfStateValue.newValueLong(in.readLong());
211 break;
212 case TYPE_STRING:
213 length = in.readInt();
214 bytes = new byte[length];
215 in.read(bytes, 0, length);
216 value = TmfStateValue.newValueString(new String(bytes));
217 break;
218 default:
219 throw new IOException("Read object failed : Invalid data"); //$NON-NLS-1$
220 }
221 content.put(name, value);
222 }
223 fContent = content;
224 }
225
226 /**
227 * Here we determine how state values "types" are written in the 8-bit field
228 * that indicates the value type in the file.
229 */
230 private static byte getByteFromType(ITmfStateValue.Type type) {
231 switch (type) {
232 case NULL:
233 return TYPE_NULL;
234 case INTEGER:
235 return TYPE_INTEGER;
236 case STRING:
237 return TYPE_STRING;
238 case LONG:
239 return TYPE_LONG;
240 case DOUBLE:
241 default:
242 /* Should not happen if the switch is fully covered */
243 throw new IllegalStateException("Data type " + type + " not supported"); //$NON-NLS-1$ //$NON-NLS-2$
244 }
245 }
246 }
This page took 0.044637 seconds and 5 git commands to generate.