rcp: Change workspace directory to .tracecompass
[deliverable/tracecompass.git] / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / internal / ctf / core / event / types / composite / EventHeaderCompactDeclaration.java
CommitLineData
6c7592e1
MK
1/*******************************************************************************
2 * Copyright (c) 2014 Ericsson
3 *
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
8 *
9 * Contributors:
10 * Matthew Khouzam - Initial API and implementation
11 *******************************************************************************/
12
f357bcd4 13package org.eclipse.tracecompass.internal.ctf.core.event.types.composite;
6c7592e1
MK
14
15import java.nio.ByteOrder;
16
f78eb6a7
MK
17import org.eclipse.jdt.annotation.NonNullByDefault;
18import org.eclipse.jdt.annotation.Nullable;
f357bcd4
AM
19import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
20import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
21import org.eclipse.tracecompass.ctf.core.event.types.Declaration;
22import org.eclipse.tracecompass.ctf.core.event.types.EnumDeclaration;
23import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration;
24import org.eclipse.tracecompass.ctf.core.event.types.IEventHeaderDeclaration;
25import org.eclipse.tracecompass.ctf.core.event.types.IntegerDeclaration;
26import org.eclipse.tracecompass.ctf.core.event.types.StructDeclaration;
27import org.eclipse.tracecompass.ctf.core.event.types.VariantDeclaration;
28import org.eclipse.tracecompass.ctf.core.trace.CTFReaderException;
6c7592e1
MK
29
30/**
31 * An event header declaration is a declaration of a structure defined in the
32 * CTF spec examples section 6.1.1 . It is used in LTTng traces. This will
33 * accelerate reading of the trace.
34 *
35 * Reminder
36 *
37 * <pre>
38 * struct event_header_compact {
39 * enum : uint5_t { compact = 0 ... 30, extended = 31 } id;
40 * variant <id> {
41 * struct {
42 * uint27_clock_monotonic_t timestamp;
43 * } compact;
44 * struct {
45 * uint32_t id;
46 * uint64_clock_monotonic_t timestamp;
47 * } extended;
48 * } v;
49 * } align(8);
50 * </pre>
51 *
52 * @author Matthew Khouzam
53 */
f78eb6a7 54@NonNullByDefault
6c7592e1
MK
55public class EventHeaderCompactDeclaration extends Declaration implements IEventHeaderDeclaration {
56
57 private static final int COMPACT_SIZE = 1;
58 private static final int VARIANT_SIZE = 2;
59 private static final int EXTENDED_FIELD_SIZE = 2;
60 /**
61 * The id is 5 bits
62 */
63 private static final int COMPACT_ID = 5;
64 private static final int EXTENDED_VALUE = 31;
65 /**
66 * Full sized id is 32 bits
67 */
68 private static final int ID_SIZE = 32;
69 /**
70 * Full sized timestamp is 64 bits
71 */
72 private static final int FULL_TS = 64;
73 /**
74 * Compact timestamp is 27 bits,
75 */
76 private static final int COMPACT_TS = 27;
77 /**
78 * Maximum size = largest this header can be
79 */
80 private static final int MAX_SIZE = 104;
81 /**
82 * Byte aligned
83 */
84 private static final int ALIGN = 8;
85 /**
86 * Name of the variant according to the spec
87 */
88 private static final String V = "v"; //$NON-NLS-1$
89
90 private final ByteOrder fByteOrder;
91
f78eb6a7
MK
92 /**
93 * Big-Endian Large Event Header
94 */
95 private static final EventHeaderCompactDeclaration EVENT_HEADER_BIG_ENDIAN = new EventHeaderCompactDeclaration(nullCheck(ByteOrder.BIG_ENDIAN));
96
97 /**
98 * Little-Endian Large Event Header
99 */
100 private static final EventHeaderCompactDeclaration EVENT_HEADER_LITTLE_ENDIAN = new EventHeaderCompactDeclaration(nullCheck(ByteOrder.LITTLE_ENDIAN));
101
6c7592e1
MK
102 /**
103 * Event Header Declaration
104 *
105 * @param byteOrder
106 * the byteorder
107 */
f78eb6a7 108 private EventHeaderCompactDeclaration(ByteOrder byteOrder) {
6c7592e1
MK
109 fByteOrder = byteOrder;
110 }
111
f78eb6a7
MK
112 /**
113 * Gets an {@link EventHeaderCompactDeclaration} of a given ByteOrder
114 *
115 * @param byteOrder
116 * the byte order
117 * @return the header declaration
118 */
119 public static EventHeaderCompactDeclaration getEventHeader(@Nullable ByteOrder byteOrder) {
120 if (byteOrder == ByteOrder.BIG_ENDIAN) {
121 return EVENT_HEADER_BIG_ENDIAN;
122 }
123 return EVENT_HEADER_LITTLE_ENDIAN;
124 }
125
6c7592e1 126 @Override
f78eb6a7 127 public EventHeaderDefinition createDefinition(@Nullable IDefinitionScope definitionScope, String fieldName, BitBuffer input) throws CTFReaderException {
6c7592e1
MK
128 alignRead(input);
129 ByteOrder bo = input.getByteOrder();
130 input.setByteOrder(fByteOrder);
131 int enumId = (int) input.get(COMPACT_ID, false);
132 if (enumId != EXTENDED_VALUE) {
133 long timestamp2 = input.get(COMPACT_TS, false);
134 input.setByteOrder(bo);
135 return new EventHeaderDefinition(this, enumId, timestamp2, COMPACT_TS);
136 }
137 // needed since we read 5 bits
138 input.position(input.position() + 3);
733e6767
MK
139 long id = input.get(ID_SIZE, false);
140 if (id > Integer.MAX_VALUE) {
141 throw new CTFReaderException("ID " + id + " larger than " + Integer.MAX_VALUE + " is currently unsupported by the parser"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
142 }
6c7592e1
MK
143 long timestampLong = input.get(FULL_TS, false);
144 input.setByteOrder(bo);
733e6767 145 return new EventHeaderDefinition(this, (int) id, timestampLong, FULL_TS);
6c7592e1
MK
146
147 }
148
149 @Override
150 public long getAlignment() {
151 return ALIGN;
152 }
153
154 @Override
155 public int getMaximumSize() {
156 return MAX_SIZE;
157 }
158
159 /**
160 * Check if a given struct declaration is an event header
161 *
162 * @param declaration
163 * the declaration
164 * @return true if the struct is a compact event header
165 */
f78eb6a7
MK
166 public static boolean isCompactEventHeader(@Nullable StructDeclaration declaration) {
167 if (declaration == null) {
168 return false;
169 }
6c7592e1
MK
170
171 IDeclaration iDeclaration = declaration.getFields().get(ID);
172 if (!(iDeclaration instanceof EnumDeclaration)) {
173 return false;
174 }
175 EnumDeclaration eId = (EnumDeclaration) iDeclaration;
176 if (eId.getContainerType().getLength() != COMPACT_ID) {
177 return false;
178 }
179 iDeclaration = declaration.getFields().get(V);
180
181 if (!(iDeclaration instanceof VariantDeclaration)) {
182 return false;
183 }
184 VariantDeclaration vDec = (VariantDeclaration) iDeclaration;
185 if (!vDec.hasField(COMPACT) || !vDec.hasField(EXTENDED)) {
186 return false;
187 }
733e6767 188 if (vDec.getFields().size() != VARIANT_SIZE) {
6c7592e1
MK
189 return false;
190 }
191 iDeclaration = vDec.getFields().get(COMPACT);
733e6767 192 if (!(iDeclaration instanceof StructDeclaration)) {
6c7592e1
MK
193 return false;
194 }
195 StructDeclaration compactDec = (StructDeclaration) iDeclaration;
196 if (compactDec.getFields().size() != COMPACT_SIZE) {
197 return false;
198 }
199 if (!compactDec.hasField(TIMESTAMP)) {
200 return false;
201 }
202 iDeclaration = compactDec.getFields().get(TIMESTAMP);
733e6767 203 if (!(iDeclaration instanceof IntegerDeclaration)) {
6c7592e1
MK
204 return false;
205 }
206 IntegerDeclaration tsDec = (IntegerDeclaration) iDeclaration;
207 if (tsDec.getLength() != COMPACT_TS || tsDec.isSigned()) {
208 return false;
209 }
210 iDeclaration = vDec.getFields().get(EXTENDED);
733e6767 211 if (!(iDeclaration instanceof StructDeclaration)) {
6c7592e1
MK
212 return false;
213 }
214 StructDeclaration extendedDec = (StructDeclaration) iDeclaration;
215 if (!extendedDec.hasField(TIMESTAMP)) {
216 return false;
217 }
218 if (extendedDec.getFields().size() != EXTENDED_FIELD_SIZE) {
219 return false;
220 }
221 iDeclaration = extendedDec.getFields().get(TIMESTAMP);
733e6767 222 if (!(iDeclaration instanceof IntegerDeclaration)) {
6c7592e1
MK
223 return false;
224 }
225 tsDec = (IntegerDeclaration) iDeclaration;
226 if (tsDec.getLength() != FULL_TS || tsDec.isSigned()) {
227 return false;
228 }
229 iDeclaration = extendedDec.getFields().get(ID);
230 if (!(iDeclaration instanceof IntegerDeclaration)) {
231 return false;
232 }
233 IntegerDeclaration iId = (IntegerDeclaration) iDeclaration;
234 if (iId.getLength() != ID_SIZE || iId.isSigned()) {
235 return false;
236 }
237 return true;
238 }
f78eb6a7
MK
239
240 private static ByteOrder nullCheck(@Nullable ByteOrder bo) {
241 if (bo == null) {
242 throw new IllegalStateException("Could not create byteorder"); //$NON-NLS-1$
243 }
244 return bo;
245 }
e00e6663
MK
246
247@Override
248 public int hashCode() {
249 final int prime = 31;
250 int result = 1;
251 result = prime * result + (fByteOrder.equals(ByteOrder.BIG_ENDIAN) ? 4321 : 1234);
252 return result;
253 }
254
255 @Override
256 public boolean equals(@Nullable Object obj) {
257 if (this == obj) {
258 return true;
259 }
260 if (obj == null) {
261 return false;
262 }
263 if (getClass() != obj.getClass()) {
264 return false;
265 }
266 EventHeaderCompactDeclaration other = (EventHeaderCompactDeclaration) obj;
267 if (!fByteOrder.equals(other.fByteOrder)) {
268 return false;
269 }
270 return true;
271 }
272
6c7592e1 273}
This page took 0.042615 seconds and 5 git commands to generate.