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