Commit | Line | Data |
---|---|---|
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 | ||
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 | } |