rcp: Move plugins to their own sub-directory
[deliverable/tracecompass.git] / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / internal / ctf / core / event / types / StructDeclarationFlattener.java
CommitLineData
8fa270f6
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;
8fa270f6
MK
14
15import org.eclipse.jdt.annotation.NonNull;
f357bcd4
AM
16import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration;
17import org.eclipse.tracecompass.ctf.core.event.types.ISimpleDatatypeDeclaration;
18import org.eclipse.tracecompass.ctf.core.event.types.StructDeclaration;
8fa270f6
MK
19
20/**
21 * A fixed size struct declaration is a declaration of a structure that has no
22 * variant or sequence fields. This will accelerate reading of the trace.
23 *
24 * @author Matthew Khouzam
8fa270f6
MK
25 */
26public final class StructDeclarationFlattener {
27
28 private StructDeclarationFlattener() {}
29
30 /**
31 * Flatten a {@link StructDeclaration}, if it can be (which means if it
32 * contains only fixed-size elements).
33 *
34 * This does not modify the declaration passed in parameter, you need to use
35 * the return value.
36 *
37 * @param sd
38 * The initial StructDeclaration
39 * @return The flattened struct. Or if it couldn't be flattened, the 'sd'
40 * struct itself
41 */
0e210c26 42 public static @NonNull StructDeclaration tryFlattenStruct(@NonNull StructDeclaration sd) {
8fa270f6
MK
43 if (canBeFlattened(sd)) {
44 return newFlattenedStruct(sd);
45 }
46 return sd;
47 }
48
49 /**
50 * Check if this struct is fixed size
51 *
52 * @param sd
53 * the struct
54 * @return if the struct is of fixed size
55 */
56 private static boolean canBeFlattened(@NonNull StructDeclaration sd) {
57 for (String field : sd.getFieldsList()) {
58 IDeclaration dec = sd.getField(field);
59 if (!isFixedSize(dec)) {
60 return false;
61 }
62 }
63 return true;
64 }
65
66 private static boolean isFixedSize(IDeclaration dec) {
67 if (dec instanceof ISimpleDatatypeDeclaration) {
68 return true;
69 }
70 if (dec instanceof ArrayDeclaration) {
71 return isFixedSize(((ArrayDeclaration) dec).getElementType());
72 }
73 if (dec instanceof StructDeclaration) {
74 StructDeclaration sDec = ((StructDeclaration) dec);
75 return canBeFlattened(sDec);
76 }
77 return false;
78 }
79
0e210c26 80 private static @NonNull StructDeclaration newFlattenedStruct(@NonNull StructDeclaration sd) {
8fa270f6
MK
81 StructDeclaration flatStruct = new StructDeclaration(sd.getAlignment());
82 for (String name : sd.getFieldsList()) {
83 depthFirstAdd(name, flatStruct, sd.getField(name));
84 }
85 return flatStruct;
86 }
87
88 private static void depthFirstAdd(String path, StructDeclaration flatStruct, IDeclaration dec) {
89 if (dec instanceof ISimpleDatatypeDeclaration) {
90 flatStruct.addField(path, dec);
91 } else if (dec instanceof ArrayDeclaration) {
92 ArrayDeclaration ad = (ArrayDeclaration) dec;
93 int lastIndexOf = path.lastIndexOf('.');
8fa270f6 94 String name = (lastIndexOf > 0) ? path.substring(lastIndexOf) : path;
15f6223a 95 if (ad.isAlignedBytes()) {
8fa270f6
MK
96 flatStruct.addField(path, dec);
97 } else {
98 for (int i = 0; i < ad.getLength(); i++) {
99 depthFirstAdd(path + '.' + name + '[' + i + ']', flatStruct, ad.getElementType());
100 }
101 }
102 } else if (dec instanceof StructDeclaration) {
103 StructDeclaration sDec = ((StructDeclaration) dec);
104 for (String name : sDec.getFieldsList()) {
105 depthFirstAdd(path + '.' + name, flatStruct, sDec.getField(name));
106 }
107 }
108 }
109
110}
This page took 0.070709 seconds and 5 git commands to generate.