ctf: Move plugins to their own sub-directory
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / internal / ctf / core / event / types / SequenceDeclaration.java
1 /*******************************************************************************
2 * Copyright (c) 2014 Ericsson, Ecole Polytechnique de Montreal and others
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: Matthew Khouzam - Initial API and implementation
10 *******************************************************************************/
11
12 package org.eclipse.tracecompass.internal.ctf.core.event.types;
13
14 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
15
16 import java.util.Collection;
17 import java.util.List;
18
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.eclipse.tracecompass.ctf.core.CTFException;
21 import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
22 import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
23 import org.eclipse.tracecompass.ctf.core.event.types.AbstractArrayDefinition;
24 import org.eclipse.tracecompass.ctf.core.event.types.CompoundDeclaration;
25 import org.eclipse.tracecompass.ctf.core.event.types.Definition;
26 import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration;
27 import org.eclipse.tracecompass.ctf.core.event.types.IDefinition;
28 import org.eclipse.tracecompass.ctf.core.event.types.IntegerDefinition;
29
30 import com.google.common.collect.ArrayListMultimap;
31 import com.google.common.collect.ImmutableList;
32 import com.google.common.collect.ImmutableList.Builder;
33 import com.google.common.collect.Multimap;
34
35 /**
36 * A CTF sequence declaration.
37 *
38 * An array where the size is fixed but declared in the trace, unlike array
39 * where it is declared with a literal
40 *
41 * @author Matthew Khouzam
42 */
43 public class SequenceDeclaration extends CompoundDeclaration {
44
45 // ------------------------------------------------------------------------
46 // Attributes
47 // ------------------------------------------------------------------------
48
49 private final IDeclaration fElemType;
50 private final String fLengthName;
51 private final transient Multimap<String, String> fPaths = ArrayListMultimap.create();
52
53 // ------------------------------------------------------------------------
54 // Constructors
55 // ------------------------------------------------------------------------
56
57 /**
58 * Constructor
59 *
60 * @param lengthName
61 * the name of the field describing the length
62 * @param elemType
63 * The element type
64 */
65 public SequenceDeclaration(@Nullable String lengthName, IDeclaration elemType) {
66 fElemType = elemType;
67 fLengthName = lengthName;
68 }
69
70 // ------------------------------------------------------------------------
71 // Getters/Setters/Predicates
72 // ------------------------------------------------------------------------
73
74 @Override
75 public IDeclaration getElementType() {
76 return fElemType;
77 }
78
79 /**
80 * Gets the name of the length field
81 *
82 * @return the name of the length field
83 */
84 public String getLengthName() {
85 return fLengthName;
86 }
87
88 // ------------------------------------------------------------------------
89 // Operations
90 // ------------------------------------------------------------------------
91
92 @Override
93 public AbstractArrayDefinition createDefinition(
94 @Nullable IDefinitionScope definitionScope, String fieldName, BitBuffer input) throws CTFException {
95 IDefinition lenDef = null;
96
97 if (definitionScope != null) {
98 lenDef = definitionScope.lookupDefinition(getLengthName());
99 }
100
101 if (lenDef == null) {
102 throw new CTFException("Sequence length field not found"); //$NON-NLS-1$
103 }
104
105 if (!(lenDef instanceof IntegerDefinition)) {
106 throw new CTFException("Sequence length field not integer"); //$NON-NLS-1$
107 }
108
109 IntegerDefinition lengthDefinition = (IntegerDefinition) lenDef;
110
111 if (lengthDefinition.getDeclaration().isSigned()) {
112 throw new CTFException("Sequence length must not be signed"); //$NON-NLS-1$
113 }
114
115 long length = lengthDefinition.getValue();
116 if ((length > Integer.MAX_VALUE) || (!input.canRead((int) length * fElemType.getMaximumSize()))) {
117 throw new CTFException("Sequence length too long " + length); //$NON-NLS-1$
118 }
119
120 if (isAlignedBytes()) {
121 // Don't create "useless" definitions
122 byte[] data = new byte[(int) length];
123 input.get(data);
124 return new ByteArrayDefinition(this, definitionScope, fieldName, data);
125 }
126 Collection<String> collection = fPaths.get(fieldName);
127 while (collection.size() < length) {
128 fPaths.put(fieldName, fieldName + '[' + collection.size() + ']');
129 }
130 List<String> paths = (List<String>) fPaths.get(fieldName);
131 Builder<Definition> definitions = new ImmutableList.Builder<>();
132 for (int i = 0; i < length; i++) {
133 /* We should not have inserted any null values */
134 String elemName = checkNotNull(paths.get(i));
135 definitions.add(fElemType.createDefinition(definitionScope, elemName, input));
136 }
137 List<Definition> list = checkNotNull(definitions.build());
138 return new ArrayDefinition(this, definitionScope, fieldName, list);
139 }
140
141 @Override
142 public String toString() {
143 /* Only used for debugging */
144 return "[declaration] sequence[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
145 }
146
147 @Override
148 public int getMaximumSize() {
149 return Integer.MAX_VALUE;
150 }
151
152 @Override
153 public int hashCode() {
154 final int prime = 31;
155 int result = 1;
156 result = prime * result + fElemType.hashCode();
157 result = prime * result + fLengthName.hashCode();
158 return result;
159 }
160
161 @Override
162 public boolean equals(@Nullable Object obj) {
163 if (this == obj) {
164 return true;
165 }
166 if (obj == null) {
167 return false;
168 }
169 if (getClass() != obj.getClass()) {
170 return false;
171 }
172 SequenceDeclaration other = (SequenceDeclaration) obj;
173 if (!fElemType.equals(other.fElemType)) {
174 return false;
175 }
176 if (!fLengthName.equals(other.fLengthName)) {
177 return false;
178 }
179 return true;
180 }
181
182 @Override
183 public boolean isBinaryEquivalent(@Nullable IDeclaration obj) {
184 if (this == obj) {
185 return true;
186 }
187 if (obj == null) {
188 return false;
189 }
190 if (getClass() != obj.getClass()) {
191 return false;
192 }
193 SequenceDeclaration other = (SequenceDeclaration) obj;
194 if (!fElemType.isBinaryEquivalent(other.fElemType)) {
195 return false;
196 }
197 if (!fLengthName.equals(other.fLengthName)) {
198 return false;
199 }
200 return true;
201 }
202
203 }
This page took 0.064737 seconds and 5 git commands to generate.