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_compact { | |
37 | * enum : uint5_t { compact = 0 ... 30, extended = 31 } id; | |
38 | * variant <id> { | |
39 | * struct { | |
40 | * uint27_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 EventHeaderCompactDeclaration extends Declaration implements IEventHeaderDeclaration { | |
53 | ||
54 | private static final int COMPACT_SIZE = 1; | |
55 | private static final int VARIANT_SIZE = 2; | |
56 | private static final int EXTENDED_FIELD_SIZE = 2; | |
57 | /** | |
58 | * The id is 5 bits | |
59 | */ | |
60 | private static final int COMPACT_ID = 5; | |
61 | private static final int EXTENDED_VALUE = 31; | |
62 | /** | |
63 | * Full sized id is 32 bits | |
64 | */ | |
65 | private static final int ID_SIZE = 32; | |
66 | /** | |
67 | * Full sized timestamp is 64 bits | |
68 | */ | |
69 | private static final int FULL_TS = 64; | |
70 | /** | |
71 | * Compact timestamp is 27 bits, | |
72 | */ | |
73 | private static final int COMPACT_TS = 27; | |
74 | /** | |
75 | * Maximum size = largest this header can be | |
76 | */ | |
77 | private static final int MAX_SIZE = 104; | |
78 | /** | |
79 | * Byte aligned | |
80 | */ | |
81 | private static final int ALIGN = 8; | |
82 | /** | |
83 | * Name of the variant according to the spec | |
84 | */ | |
85 | private static final String V = "v"; //$NON-NLS-1$ | |
86 | ||
87 | private final ByteOrder fByteOrder; | |
88 | ||
89 | /** | |
90 | * Event Header Declaration | |
91 | * | |
92 | * @param byteOrder | |
93 | * the byteorder | |
94 | */ | |
95 | public EventHeaderCompactDeclaration(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 enumId = (int) input.get(COMPACT_ID, false); | |
105 | if (enumId != EXTENDED_VALUE) { | |
106 | long timestamp2 = input.get(COMPACT_TS, false); | |
107 | input.setByteOrder(bo); | |
108 | return new EventHeaderDefinition(this, enumId, timestamp2, COMPACT_TS); | |
109 | } | |
110 | // needed since we read 5 bits | |
111 | input.position(input.position() + 3); | |
733e6767 MK |
112 | long id = input.get(ID_SIZE, false); |
113 | if (id > Integer.MAX_VALUE) { | |
114 | 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$ | |
115 | } | |
6c7592e1 MK |
116 | long timestampLong = input.get(FULL_TS, false); |
117 | input.setByteOrder(bo); | |
733e6767 | 118 | return new EventHeaderDefinition(this, (int) id, timestampLong, FULL_TS); |
6c7592e1 MK |
119 | |
120 | } | |
121 | ||
122 | @Override | |
123 | public long getAlignment() { | |
124 | return ALIGN; | |
125 | } | |
126 | ||
127 | @Override | |
128 | public int getMaximumSize() { | |
129 | return MAX_SIZE; | |
130 | } | |
131 | ||
132 | /** | |
133 | * Check if a given struct declaration is an event header | |
134 | * | |
135 | * @param declaration | |
136 | * the declaration | |
137 | * @return true if the struct is a compact event header | |
138 | */ | |
139 | public static boolean isCompactEventHeader(StructDeclaration declaration) { | |
140 | ||
141 | IDeclaration iDeclaration = declaration.getFields().get(ID); | |
142 | if (!(iDeclaration instanceof EnumDeclaration)) { | |
143 | return false; | |
144 | } | |
145 | EnumDeclaration eId = (EnumDeclaration) iDeclaration; | |
146 | if (eId.getContainerType().getLength() != COMPACT_ID) { | |
147 | return false; | |
148 | } | |
149 | iDeclaration = declaration.getFields().get(V); | |
150 | ||
151 | if (!(iDeclaration instanceof VariantDeclaration)) { | |
152 | return false; | |
153 | } | |
154 | VariantDeclaration vDec = (VariantDeclaration) iDeclaration; | |
155 | if (!vDec.hasField(COMPACT) || !vDec.hasField(EXTENDED)) { | |
156 | return false; | |
157 | } | |
733e6767 | 158 | if (vDec.getFields().size() != VARIANT_SIZE) { |
6c7592e1 MK |
159 | return false; |
160 | } | |
161 | iDeclaration = vDec.getFields().get(COMPACT); | |
733e6767 | 162 | if (!(iDeclaration instanceof StructDeclaration)) { |
6c7592e1 MK |
163 | return false; |
164 | } | |
165 | StructDeclaration compactDec = (StructDeclaration) iDeclaration; | |
166 | if (compactDec.getFields().size() != COMPACT_SIZE) { | |
167 | return false; | |
168 | } | |
169 | if (!compactDec.hasField(TIMESTAMP)) { | |
170 | return false; | |
171 | } | |
172 | iDeclaration = compactDec.getFields().get(TIMESTAMP); | |
733e6767 | 173 | if (!(iDeclaration instanceof IntegerDeclaration)) { |
6c7592e1 MK |
174 | return false; |
175 | } | |
176 | IntegerDeclaration tsDec = (IntegerDeclaration) iDeclaration; | |
177 | if (tsDec.getLength() != COMPACT_TS || tsDec.isSigned()) { | |
178 | return false; | |
179 | } | |
180 | iDeclaration = vDec.getFields().get(EXTENDED); | |
733e6767 | 181 | if (!(iDeclaration instanceof StructDeclaration)) { |
6c7592e1 MK |
182 | return false; |
183 | } | |
184 | StructDeclaration extendedDec = (StructDeclaration) iDeclaration; | |
185 | if (!extendedDec.hasField(TIMESTAMP)) { | |
186 | return false; | |
187 | } | |
188 | if (extendedDec.getFields().size() != EXTENDED_FIELD_SIZE) { | |
189 | return false; | |
190 | } | |
191 | iDeclaration = extendedDec.getFields().get(TIMESTAMP); | |
733e6767 | 192 | if (!(iDeclaration instanceof IntegerDeclaration)) { |
6c7592e1 MK |
193 | return false; |
194 | } | |
195 | tsDec = (IntegerDeclaration) iDeclaration; | |
196 | if (tsDec.getLength() != FULL_TS || tsDec.isSigned()) { | |
197 | return false; | |
198 | } | |
199 | iDeclaration = extendedDec.getFields().get(ID); | |
200 | if (!(iDeclaration instanceof IntegerDeclaration)) { | |
201 | return false; | |
202 | } | |
203 | IntegerDeclaration iId = (IntegerDeclaration) iDeclaration; | |
204 | if (iId.getLength() != ID_SIZE || iId.isSigned()) { | |
205 | return false; | |
206 | } | |
207 | return true; | |
208 | } | |
209 | } |