ctf: split up IOStructGen into 44 files
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / internal / ctf / core / event / metadata / tsdl / AlignmentParser.java
1 /*******************************************************************************
2 * Copyright (c) 2015 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
10 package org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl;
11
12 import static org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.TsdlUtils.isUnaryInteger;
13
14 import org.antlr.runtime.tree.CommonTree;
15 import org.eclipse.tracecompass.ctf.parser.CTFParser;
16 import org.eclipse.tracecompass.internal.ctf.core.event.metadata.ICommonTreeParser;
17 import org.eclipse.tracecompass.internal.ctf.core.event.metadata.ParseException;
18
19 /**
20 * Alignment parser, we define byte-packed types as aligned on the byte size,
21 * namely 8-bit. We define bit-packed types as following on the next bit, as
22 * defined by the Integers section.
23 *
24 * Each basic type must specify its alignment, in bits. Examples of possible
25 * alignments are: bit-packed (align = 1), byte-packed (align = 8), or
26 * word-aligned (e.g. align = 32 or align = 64). The choice depends on the
27 * architecture preference and compactness vs performance trade-offs of the
28 * implementation. Architectures providing fast unaligned write byte-packed
29 * basic types to save space, aligning each type on byte boundaries (8-bit).
30 * Architectures with slow unaligned writes align types on specific alignment
31 * values. If no specific alignment is declared for a type, it is assumed to be
32 * bit-packed for integers with size not multiple of 8 bits and for gcc
33 * bitfields. All other basic types are byte-packed by default. It is however
34 * recommended to always specify the alignment explicitly. Alignment values must
35 * be power of two. Compound types are aligned as specified in their individual
36 * specification.
37 *
38 * The base offset used for field alignment is the start of the packet
39 * containing the field. For instance, a field aligned on 32-bit needs to be at
40 * an offset multiple of 32-bit from the start of the packet that contains it.
41 *
42 * TSDL metadata attribute representation of a specific alignment:
43 *
44 * @author Matthew Khouzam
45 * @author Efficios (javadoc preamble)
46 *
47 */
48 public final class AlignmentParser implements ICommonTreeParser {
49
50 /**
51 * Alignment parser instance
52 */
53 public static final AlignmentParser INSTANCE = new AlignmentParser();
54
55 private static final String INVALID_VALUE_FOR_ALIGNMENT = "Invalid value for alignment"; //$NON-NLS-1$
56
57 private AlignmentParser() {
58 }
59
60 /**
61 * Gets the value of a "align" integer or struct attribute.
62 * @param tree
63 * A CTF_RIGHT node or directly an unary integer.
64 *
65 * @return The align value.
66 * @throws ParseException
67 * Invalid alignment value
68 */
69 @Override
70 public Long parse(CommonTree tree, ICommonTreeParserParameter param) throws ParseException {
71 /*
72 * If a CTF_RIGHT node was passed, call getAlignment with the first
73 * child
74 */
75 if (tree.getType() == CTFParser.CTF_RIGHT) {
76 if (tree.getChildCount() > 1) {
77 throw new ParseException(INVALID_VALUE_FOR_ALIGNMENT);
78 }
79
80 return parse((CommonTree) tree.getChild(0), param);
81 } else if (isUnaryInteger(tree)) {
82 long alignment = UnaryIntegerParser.INSTANCE.parse(tree, null);
83
84 if (!isValidAlignment(alignment)) {
85 throw new ParseException(INVALID_VALUE_FOR_ALIGNMENT + " : " //$NON-NLS-1$
86 + alignment);
87 }
88
89 return alignment;
90 }
91 throw new ParseException(INVALID_VALUE_FOR_ALIGNMENT); // $NON-NLS-1$
92 }
93
94 /**
95 * Determines if the given value is a valid alignment value.
96 *
97 * @param alignment
98 * The value to check.
99 * @return True if it is valid.
100 */
101 private static boolean isValidAlignment(long alignment) {
102 return !((alignment <= 0) || ((alignment & (alignment - 1)) != 0));
103 }
104
105 }
This page took 0.032693 seconds and 5 git commands to generate.