1 /*******************************************************************************
2 * Copyright (c) 2011, 2015 Ericsson, Ecole Polytechnique de Montreal and others
4 * All rights reserved. This program and the accompanying materials are made
5 * 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
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 * Contributors: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.internal
.ctf
.core
.trace
;
15 import java
.util
.HashMap
;
17 import java
.util
.regex
.Matcher
;
18 import java
.util
.regex
.Pattern
;
20 import org
.eclipse
.tracecompass
.ctf
.core
.CTFStrings
;
21 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.EnumDefinition
;
22 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.FloatDefinition
;
23 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.IDefinition
;
24 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.IntegerDefinition
;
25 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.SimpleDatatypeDefinition
;
26 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.StringDefinition
;
27 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.StructDefinition
;
28 import org
.eclipse
.tracecompass
.ctf
.core
.trace
.ICTFPacketDescriptor
;
29 import org
.eclipse
.tracecompass
.ctf
.core
.trace
.IPacketReader
;
32 * <b><u>StreamInputPacketIndexEntry</u></b>
34 * Represents an entry in the index of event packets.
36 public class StreamInputPacketIndexEntry
implements ICTFPacketDescriptor
{
38 private static final Pattern NUMBER_PATTERN
= Pattern
.compile("\\D*(\\d+)"); //$NON-NLS-1$
40 // ------------------------------------------------------------------------
42 // ------------------------------------------------------------------------
45 * Position of the start of the packet header in the file, in bits
47 private final long fOffsetBits
;
50 * Position of the start of the packet header in the file, in bytes
52 private final long fOffsetBytes
;
55 * Packet size, in bits
57 private final long fPacketSizeBits
;
60 * Content size, in bits
62 private final long fContentSizeBits
;
67 private final long fTimestampBegin
;
72 private final long fTimestampEnd
;
75 * How many lost events are there?
77 private final long fLostEvents
;
80 * Which target is being traced
82 private final String fTarget
;
83 private final long fTargetID
;
86 * Attributes of this index entry
88 private final Map
<String
, Object
> fAttributes
= new HashMap
<>();
90 private final long fEndPacketHeaderBits
;
92 // ------------------------------------------------------------------------
94 // ------------------------------------------------------------------------
97 * Constructs an index entry.
99 * @param dataOffsetBits
100 * offset in the file for the start of data in bits
101 * @param fileSizeBytes
102 * number of bytes in a file
107 public StreamInputPacketIndexEntry(long dataOffsetBits
, long fileSizeBytes
) {
108 fContentSizeBits
= (fileSizeBytes
* Byte
.SIZE
);
109 fPacketSizeBits
= (fileSizeBytes
* Byte
.SIZE
);
110 fOffsetBits
= dataOffsetBits
;
111 fOffsetBytes
= dataOffsetBits
/ Byte
.SIZE
;
113 fTarget
= ""; //$NON-NLS-1$
116 fTimestampEnd
= Long
.MAX_VALUE
;
117 fEndPacketHeaderBits
= dataOffsetBits
;
123 * @param dataOffsetBits
124 * offset in the file for the start of data in bits
125 * @param streamPacketContextDef
127 * @param fileSizeBytes
128 * number of bytes in a file
130 * number of lost events so far
134 public StreamInputPacketIndexEntry(long dataOffsetBits
, StructDefinition streamPacketContextDef
, long fileSizeBytes
, long lostSoFar
) {
135 this(dataOffsetBits
, streamPacketContextDef
, fileSizeBytes
, lostSoFar
, dataOffsetBits
);
141 * @param dataOffsetBits
142 * offset in the file for the start of data in bits
143 * @param streamPacketContextDef
145 * @param fileSizeBytes
146 * number of bytes in a file
148 * number of lost events so far
149 * @param endPacketHeaderBits
150 * end of packet headers
152 public StreamInputPacketIndexEntry(long dataOffsetBits
, StructDefinition streamPacketContextDef
, long fileSizeBytes
, long lostSoFar
, long endPacketHeaderBits
) {
153 fEndPacketHeaderBits
= endPacketHeaderBits
;
154 for (String field
: streamPacketContextDef
.getDeclaration().getFieldsList()) {
155 IDefinition id
= streamPacketContextDef
.lookupDefinition(field
);
156 if (id
instanceof IntegerDefinition
) {
157 fAttributes
.put(field
, ((IntegerDefinition
) id
).getValue());
158 } else if (id
instanceof FloatDefinition
) {
159 fAttributes
.put(field
, ((FloatDefinition
) id
).getValue());
160 } else if (id
instanceof EnumDefinition
) {
161 fAttributes
.put(field
, ((EnumDefinition
) id
).getValue());
162 } else if (id
instanceof StringDefinition
) {
163 fAttributes
.put(field
, ((StringDefinition
) id
).getValue());
167 fContentSizeBits
= computeContentSize(fileSizeBytes
);
168 fPacketSizeBits
= computePacketSize(fileSizeBytes
);
169 fTimestampBegin
= computeTsBegin();
170 fTimestampEnd
= computeTsEnd();
171 fOffsetBits
= dataOffsetBits
;
172 fOffsetBytes
= dataOffsetBits
/ Byte
.SIZE
;
175 Target target
= lookupTarget(streamPacketContextDef
);
176 fTarget
= target
.string
;
177 fTargetID
= target
.number
;
178 fLostEvents
= computeLostEvents(lostSoFar
);
181 private Long
getPacketSize() {
182 return (Long
) fAttributes
.get(CTFStrings
.PACKET_SIZE
);
185 private long computeContentSize(long fileSizeBytes
) {
186 Long contentSize
= (Long
) fAttributes
.get(CTFStrings
.CONTENT_SIZE
);
187 /* Read the content size in bits */
188 if (contentSize
!= null) {
189 return contentSize
.longValue();
191 Long packetSize
= getPacketSize();
192 if (packetSize
!= null) {
193 return packetSize
.longValue();
195 return fileSizeBytes
* Byte
.SIZE
;
198 private long computePacketSize(long fileSizeBytes
) {
199 Long packetSize
= getPacketSize();
200 /* Read the packet size in bits */
201 if (packetSize
!= null) {
202 return packetSize
.longValue();
204 long contentSizeBits
= computeContentSize(fileSizeBytes
);
205 if (contentSizeBits
!= 0) {
206 return contentSizeBits
;
208 return fileSizeBytes
* Byte
.SIZE
;
211 private long computeTsBegin() {
212 Long tsBegin
= (Long
) fAttributes
.get(CTFStrings
.TIMESTAMP_BEGIN
);
213 /* Read the begin timestamp */
214 if (tsBegin
!= null) {
215 return tsBegin
.longValue();
220 private long computeTsEnd() {
221 Long tsEnd
= (Long
) fAttributes
.get(CTFStrings
.TIMESTAMP_END
);
222 /* Read the end timestamp */
224 // check if tsEnd == unsigned long max value
226 return Long
.MAX_VALUE
;
228 return tsEnd
.longValue();
230 return Long
.MAX_VALUE
;
233 private long computeLostEvents(long lostSoFar
) {
234 Long lostEvents
= (Long
) fAttributes
.get(CTFStrings
.EVENTS_DISCARDED
);
235 if (lostEvents
!= null) {
236 return lostEvents
- lostSoFar
;
241 private static class Target
{
242 public String string
;
247 number
= IPacketReader
.UNKNOWN_CPU
;
251 private Target
lookupTarget(StructDefinition streamPacketContextDef
) {
252 Target ret
= new Target();
253 boolean hasDevice
= fAttributes
.containsKey(CTFStrings
.DEVICE
);
255 IDefinition def
= streamPacketContextDef
.lookupDefinition(CTFStrings
.DEVICE
);
256 if (def
instanceof SimpleDatatypeDefinition
) {
257 SimpleDatatypeDefinition simpleDefinition
= (SimpleDatatypeDefinition
) def
;
258 ret
.string
= simpleDefinition
.getStringValue();
259 ret
.number
= simpleDefinition
.getIntegerValue();
260 } else if (def
instanceof StringDefinition
) {
261 StringDefinition stringDefinition
= (StringDefinition
) def
;
262 ret
.string
= stringDefinition
.getValue();
263 final Matcher matcher
= NUMBER_PATTERN
.matcher(ret
.string
);
264 if (matcher
.matches()) {
265 String number
= matcher
.group(1);
266 ret
.number
= Integer
.parseInt(number
);
270 Long cpuId
= (Long
) fAttributes
.get(CTFStrings
.CPU_ID
);
272 ret
.string
= ("CPU" + cpuId
.toString()); //$NON-NLS-1$
279 // ------------------------------------------------------------------------
281 // ------------------------------------------------------------------------
284 public boolean includes(long ts
) {
285 return (ts
>= fTimestampBegin
) && (ts
<= fTimestampEnd
);
289 public String
toString() {
290 return "StreamInputPacketIndexEntry [offsetBits=" + fOffsetBits
//$NON-NLS-1$
291 + ", timestampBegin=" + fTimestampBegin
+ ", timestampEnd=" //$NON-NLS-1$ //$NON-NLS-2$
292 + fTimestampEnd
+ "]"; //$NON-NLS-1$
295 // ------------------------------------------------------------------------
296 // Getters and Setters
297 // ------------------------------------------------------------------------
300 public long getOffsetBits() {
305 public long getPacketSizeBits() {
306 return fPacketSizeBits
;
310 public long getContentSizeBits() {
311 return fContentSizeBits
;
315 public long getTimestampBegin() {
316 return fTimestampBegin
;
320 public long getTimestampEnd() {
321 return fTimestampEnd
;
325 public long getLostEvents() {
330 * Add an attribute to this index entry
333 * The name of the attribute
335 * The value to insert
337 public void addAttribute(String field
, Object value
) {
338 fAttributes
.put(field
, value
);
342 public Object
lookupAttribute(String field
) {
343 return fAttributes
.get(field
);
347 public String
getTarget() {
352 public long getTargetId() {
357 public long getOffsetBytes() {
362 public long getPayloadStartBits() {
363 return fEndPacketHeaderBits
;