Commit | Line | Data |
---|---|---|
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 | ||
13 | package org.eclipse.linuxtools.internal.ctf.core.event.types.composite; | |
14 | ||
15 | import java.nio.ByteOrder; | |
16 | ||
17 | import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer; | |
18 | import org.eclipse.linuxtools.ctf.core.event.scope.IDefinitionScope; | |
19 | import org.eclipse.linuxtools.ctf.core.event.types.Declaration; | |
20 | import org.eclipse.linuxtools.ctf.core.event.types.EnumDeclaration; | |
21 | import org.eclipse.linuxtools.ctf.core.event.types.IDeclaration; | |
22 | import org.eclipse.linuxtools.ctf.core.event.types.IEventHeaderDeclaration; | |
23 | import org.eclipse.linuxtools.ctf.core.event.types.IntegerDeclaration; | |
24 | import org.eclipse.linuxtools.ctf.core.event.types.StructDeclaration; | |
25 | import org.eclipse.linuxtools.ctf.core.event.types.VariantDeclaration; | |
26 | import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; | |
27 | ||
28 | /** | |
29 | * An event header declaration is a declaration of a structure defined in the | |
30 | * CTF spec examples section 6.1.1 . It is used in LTTng traces. This will | |
31 | * accelerate reading of the trace. | |
32 | * | |
33 | * Reminder | |
34 | * | |
35 | * <pre> | |
36 | * struct event_header_large { | |
37 | * enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id; | |
38 | * variant <id> { | |
39 | * struct { | |
40 | * uint32_clock_monotonic_t timestamp; | |
41 | * } compact; | |
42 | * struct { | |
43 | * uint32_t id; | |
44 | * uint64_clock_monotonic_t timestamp; | |
45 | * } extended; | |
46 | * } v; | |
47 | * } align(8); | |
48 | * </pre> | |
49 | * | |
50 | * @author Matthew Khouzam | |
51 | */ | |
52 | public class EventHeaderLargeDeclaration extends Declaration implements IEventHeaderDeclaration { | |
53 | ||
54 | /** | |
55 | * The id is 16 bits | |
56 | */ | |
57 | private static final int COMPACT_ID = 16; | |
58 | private static final int EXTENDED_VALUE = 65535; | |
59 | /** | |
60 | * Full sized id is 32 bits | |
61 | */ | |
62 | private static final int ID_SIZE = 32; | |
63 | /** | |
64 | * Full sized timestamp is 64 bits | |
65 | */ | |
66 | private static final int FULL_TS = 64; | |
67 | /** | |
68 | * Compact timestamp is 32 bits, | |
69 | */ | |
70 | private static final int COMPACT_TS = 32; | |
71 | /** | |
72 | * Maximum size = largest this header can be | |
73 | */ | |
74 | private static final int MAX_SIZE = 112; | |
75 | /** | |
76 | * Byte aligned | |
77 | */ | |
78 | private static final int ALIGN = 8; | |
79 | /** | |
80 | * Name of the variant according to the spec | |
81 | */ | |
82 | private static final String V = "v"; //$NON-NLS-1$ | |
83 | private static final int VARIANT_SIZE = 2; | |
84 | private static final int COMPACT_SIZE = 1; | |
85 | private static final int EXTENDED_FIELD_SIZE = 2; | |
86 | ||
87 | private final ByteOrder fByteOrder; | |
88 | ||
89 | /** | |
90 | * Event Header Declaration | |
91 | * | |
92 | * @param byteOrder | |
93 | * the byteorder | |
94 | */ | |
95 | public EventHeaderLargeDeclaration(ByteOrder byteOrder) { | |
96 | fByteOrder = byteOrder; | |
97 | } | |
98 | ||
99 | @Override | |
100 | public EventHeaderDefinition createDefinition(IDefinitionScope definitionScope, String fieldName, BitBuffer input) throws CTFReaderException { | |
101 | alignRead(input); | |
102 | ByteOrder bo = input.getByteOrder(); | |
103 | input.setByteOrder(fByteOrder); | |
104 | int first = (int) input.get(COMPACT_ID, false); | |
733e6767 | 105 | long second = input.get(COMPACT_TS, false); |
6c7592e1 MK |
106 | if (first != EXTENDED_VALUE) { |
107 | input.setByteOrder(bo); | |
108 | return new EventHeaderDefinition(this, first, second, COMPACT_TS); | |
109 | } | |
110 | long timestampLong = input.get(FULL_TS, false); | |
111 | input.setByteOrder(bo); | |
733e6767 MK |
112 | if (second > Integer.MAX_VALUE) { |
113 | throw new CTFReaderException("ID " + second + " larger than " + Integer.MAX_VALUE + " is currently unsupported by the parser"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ | |
114 | } | |
115 | return new EventHeaderDefinition(this, (int) second, timestampLong, FULL_TS); | |
6c7592e1 MK |
116 | } |
117 | ||
118 | @Override | |
119 | public long getAlignment() { | |
120 | return ALIGN; | |
121 | } | |
122 | ||
123 | @Override | |
124 | public int getMaximumSize() { | |
125 | return MAX_SIZE; | |
126 | } | |
127 | ||
128 | /** | |
129 | * Check if a given struct declaration is an event header | |
130 | * | |
131 | * @param declaration | |
132 | * the declaration | |
133 | * @return true if the event is a large event header | |
134 | */ | |
135 | public static boolean isLargeEventHeader(StructDeclaration declaration) { | |
136 | ||
137 | IDeclaration iDeclaration = declaration.getFields().get(ID); | |
138 | if (!(iDeclaration instanceof EnumDeclaration)) { | |
139 | return false; | |
140 | } | |
141 | EnumDeclaration eId = (EnumDeclaration) iDeclaration; | |
142 | if (eId.getContainerType().getLength() != COMPACT_ID) { | |
143 | return false; | |
144 | } | |
145 | iDeclaration = declaration.getFields().get(V); | |
146 | ||
147 | if (!(iDeclaration instanceof VariantDeclaration)) { | |
148 | return false; | |
149 | } | |
150 | VariantDeclaration vDec = (VariantDeclaration) iDeclaration; | |
151 | if (!vDec.hasField(COMPACT) || !vDec.hasField(EXTENDED)) { | |
152 | return false; | |
153 | } | |
154 | if (vDec.getFields().size() != VARIANT_SIZE) { | |
155 | return false; | |
156 | } | |
157 | iDeclaration = vDec.getFields().get(COMPACT); | |
158 | if (!(iDeclaration instanceof StructDeclaration)) { | |
159 | return false; | |
160 | } | |
161 | StructDeclaration compactDec = (StructDeclaration) iDeclaration; | |
162 | if (compactDec.getFields().size() != COMPACT_SIZE) { | |
163 | return false; | |
164 | } | |
165 | if (!compactDec.hasField(TIMESTAMP)) { | |
166 | return false; | |
167 | } | |
168 | iDeclaration = compactDec.getFields().get(TIMESTAMP); | |
169 | if (!(iDeclaration instanceof IntegerDeclaration)) { | |
170 | return false; | |
171 | } | |
172 | IntegerDeclaration tsDec = (IntegerDeclaration) iDeclaration; | |
173 | if (tsDec.getLength() != COMPACT_TS || tsDec.isSigned()) { | |
174 | return false; | |
175 | } | |
176 | iDeclaration = vDec.getFields().get(EXTENDED); | |
177 | if (!(iDeclaration instanceof StructDeclaration)) { | |
178 | return false; | |
179 | } | |
180 | StructDeclaration extendedDec = (StructDeclaration) iDeclaration; | |
181 | if (!extendedDec.hasField(TIMESTAMP)) { | |
182 | return false; | |
183 | } | |
184 | if (extendedDec.getFields().size() != EXTENDED_FIELD_SIZE) { | |
185 | return false; | |
186 | } | |
187 | iDeclaration = extendedDec.getFields().get(TIMESTAMP); | |
188 | if (!(iDeclaration instanceof IntegerDeclaration)) { | |
189 | return false; | |
190 | } | |
191 | tsDec = (IntegerDeclaration) iDeclaration; | |
192 | if (tsDec.getLength() != FULL_TS || tsDec.isSigned()) { | |
193 | return false; | |
194 | } | |
195 | iDeclaration = extendedDec.getFields().get(ID); | |
196 | if (!(iDeclaration instanceof IntegerDeclaration)) { | |
197 | return false; | |
198 | } | |
199 | IntegerDeclaration iId = (IntegerDeclaration) iDeclaration; | |
200 | if (iId.getLength() != ID_SIZE || iId.isSigned()) { | |
201 | return false; | |
202 | } | |
203 | return true; | |
204 | } | |
205 | ||
206 | } |