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 | ||
f357bcd4 | 13 | package org.eclipse.tracecompass.internal.ctf.core.event.types; |
8fa270f6 MK |
14 | |
15 | import org.eclipse.jdt.annotation.NonNull; | |
f357bcd4 AM |
16 | import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration; |
17 | import org.eclipse.tracecompass.ctf.core.event.types.ISimpleDatatypeDeclaration; | |
18 | import 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 | */ |
26 | public 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 | */ | |
42 | public static StructDeclaration tryFlattenStruct(@NonNull StructDeclaration sd) { | |
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 | ||
80 | private static StructDeclaration newFlattenedStruct(@NonNull StructDeclaration sd) { | |
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 | } |