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