ctf: Better explain IllegalStateException
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / internal / ctf / core / event / types / ArrayDeclaration.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.tracecompass.internal.ctf.core.event.types;
14
15 import java.util.List;
16
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.eclipse.tracecompass.ctf.core.CTFException;
20 import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
21 import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
22 import org.eclipse.tracecompass.ctf.core.event.types.AbstractArrayDefinition;
23 import org.eclipse.tracecompass.ctf.core.event.types.CompoundDeclaration;
24 import org.eclipse.tracecompass.ctf.core.event.types.Definition;
25 import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration;
26
27 import com.google.common.collect.ArrayListMultimap;
28 import com.google.common.collect.ImmutableList;
29 import com.google.common.collect.ImmutableList.Builder;
30
31 /**
32 * A CTF array declaration
33 *
34 * Arrays are fixed-length. Their length is declared in the type declaration
35 * within the meta-data. They contain an array of "inner type" elements, which
36 * can refer to any type not containing the type of the array being declared (no
37 * circular dependency). The length is the number of elements in an array.
38 *
39 * @author Matthew Khouzam
40 */
41 public final class ArrayDeclaration extends CompoundDeclaration {
42
43 // ------------------------------------------------------------------------
44 // Attributes
45 // ------------------------------------------------------------------------
46
47 private final int fLength;
48 private final IDeclaration fElemType;
49
50 /**
51 * <pre>
52 * Cache where we can pre-generate the children names
53 * Key&colon; parent name
54 * Value&colon; children names
55 * ex: field &#8594; &lbrace;field&lbrack;0&rbrack;, field&lbrack;1&rbrack;, &hellip; field&lbrack;n&rbrack;&rbrace;
56 * </pre>
57 *
58 * TODO: investigate performance
59 */
60 private final transient ArrayListMultimap<String, String> fChildrenNames = ArrayListMultimap.create();
61
62 // ------------------------------------------------------------------------
63 // Constructors
64 // ------------------------------------------------------------------------
65
66 /**
67 * Constructor
68 *
69 * @param length
70 * how many elements in the array
71 * @param elemType
72 * what type of element is in the array
73 */
74 public ArrayDeclaration(int length, IDeclaration elemType) {
75 fLength = length;
76 fElemType = elemType;
77 }
78
79 // ------------------------------------------------------------------------
80 // Getters/Setters/Predicates
81 // ------------------------------------------------------------------------
82
83 @Override
84 public IDeclaration getElementType() {
85 return fElemType;
86 }
87
88 /**
89 * Get the length of the array
90 *
91 * @return the length of the array
92 */
93 public int getLength() {
94 return fLength;
95 }
96
97 // ------------------------------------------------------------------------
98 // Operations
99 // ------------------------------------------------------------------------
100
101 @Override
102 public AbstractArrayDefinition createDefinition(@Nullable IDefinitionScope definitionScope,
103 @NonNull String fieldName, BitBuffer input) throws CTFException {
104 alignRead(input);
105 if (isAlignedBytes()) {
106 byte[] data = new byte[fLength];
107 if (input.getByteBuffer().remaining() < fLength) {
108 throw new CTFException("Buffer underflow"); //$NON-NLS-1$
109 }
110 input.get(data);
111
112 return new ByteArrayDefinition(this, definitionScope, fieldName, data);
113 }
114 @NonNull List<@NonNull Definition> definitions = read(input, definitionScope, fieldName);
115 return new ArrayDefinition(this, definitionScope, fieldName, definitions);
116 }
117
118 @Override
119 public String toString() {
120 /* Only used for debugging */
121 return "[declaration] array[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
122 }
123
124 private @NonNull List<@NonNull Definition> read(@NonNull BitBuffer input, @Nullable IDefinitionScope definitionScope, String fieldName) throws CTFException {
125 Builder<@NonNull Definition> definitions = new ImmutableList.Builder<>();
126 if (!fChildrenNames.containsKey(fieldName)) {
127 for (int i = 0; i < fLength; i++) {
128 fChildrenNames.put(fieldName, fieldName + '[' + i + ']');
129 }
130 }
131 List<String> elemNames = fChildrenNames.get(fieldName);
132 for (int i = 0; i < fLength; i++) {
133 String name = elemNames.get(i);
134 if (name == null) {
135 throw new IllegalStateException("Field " + fieldName + " has a nameless field"); //$NON-NLS-1$//$NON-NLS-2$
136 }
137 definitions.add(fElemType.createDefinition(definitionScope, name, input));
138 }
139 return definitions.build();
140 }
141
142 @Override
143 public int getMaximumSize() {
144 long val = (long) fLength * fElemType.getMaximumSize();
145 return (int) Math.min(Integer.MAX_VALUE, val);
146 }
147
148 @Override
149 public int hashCode() {
150 final int prime = 31;
151 int result = 1;
152 result = prime * result + fElemType.hashCode();
153 result = prime * result + fLength;
154 return result;
155 }
156
157 @Override
158 public boolean equals(@Nullable Object obj) {
159 if (this == obj) {
160 return true;
161 }
162 if (obj == null) {
163 return false;
164 }
165 if (getClass() != obj.getClass()) {
166 return false;
167 }
168 ArrayDeclaration other = (ArrayDeclaration) obj;
169 if (!fElemType.equals(other.fElemType)) {
170 return false;
171 }
172 if (fLength != other.fLength) {
173 return false;
174 }
175 return true;
176 }
177
178 @Override
179 public boolean isBinaryEquivalent(@Nullable IDeclaration obj) {
180 if (this == obj) {
181 return true;
182 }
183 if (obj == null) {
184 return false;
185 }
186 if (getClass() != obj.getClass()) {
187 return false;
188 }
189 ArrayDeclaration other = (ArrayDeclaration) obj;
190 if (!fElemType.isBinaryEquivalent(other.fElemType)) {
191 return false;
192 }
193 if (fLength != other.fLength) {
194 return false;
195 }
196 return true;
197 }
198
199 }
This page took 0.048976 seconds and 5 git commands to generate.