1 /*******************************************************************************
2 * Copyright (c) 2014 Ericsson
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
10 * Matthew Khouzam - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.types
;
15 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
17 import java
.util
.List
;
19 import org
.eclipse
.jdt
.annotation
.NonNull
;
20 import org
.eclipse
.jdt
.annotation
.Nullable
;
21 import org
.eclipse
.tracecompass
.ctf
.core
.CTFException
;
22 import org
.eclipse
.tracecompass
.ctf
.core
.event
.io
.BitBuffer
;
23 import org
.eclipse
.tracecompass
.ctf
.core
.event
.scope
.IDefinitionScope
;
24 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.AbstractArrayDefinition
;
25 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.CompoundDeclaration
;
26 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.Definition
;
27 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.IDeclaration
;
29 import com
.google
.common
.collect
.ArrayListMultimap
;
30 import com
.google
.common
.collect
.ImmutableList
;
31 import com
.google
.common
.collect
.ImmutableList
.Builder
;
34 * A CTF array declaration
36 * Arrays are fixed-length. Their length is declared in the type declaration
37 * within the meta-data. They contain an array of "inner type" elements, which
38 * can refer to any type not containing the type of the array being declared (no
39 * circular dependency). The length is the number of elements in an array.
41 * @author Matthew Khouzam
43 public final class ArrayDeclaration
extends CompoundDeclaration
{
45 // ------------------------------------------------------------------------
47 // ------------------------------------------------------------------------
49 private final int fLength
;
50 private final IDeclaration fElemType
;
54 * Cache where we can pre-generate the children names
55 * Key: parent name
56 * Value: children names
57 * ex: field → {field[0], field[1], … field[n]}
60 * TODO: investigate performance
62 private final transient ArrayListMultimap
<String
, String
> fChildrenNames
= ArrayListMultimap
.create();
64 // ------------------------------------------------------------------------
66 // ------------------------------------------------------------------------
72 * how many elements in the array
74 * what type of element is in the array
76 public ArrayDeclaration(int length
, IDeclaration elemType
) {
81 // ------------------------------------------------------------------------
82 // Getters/Setters/Predicates
83 // ------------------------------------------------------------------------
86 public IDeclaration
getElementType() {
91 * Get the length of the array
93 * @return the length of the array
95 public int getLength() {
99 // ------------------------------------------------------------------------
101 // ------------------------------------------------------------------------
104 public AbstractArrayDefinition
createDefinition(@Nullable IDefinitionScope definitionScope
,
105 @NonNull String fieldName
, BitBuffer input
) throws CTFException
{
107 if (isAlignedBytes()) {
108 byte[] data
= new byte[fLength
];
109 if (input
.getByteBuffer().remaining() < fLength
) {
110 throw new CTFException("Buffer underflow"); //$NON-NLS-1$
114 return new ByteArrayDefinition(this, definitionScope
, fieldName
, data
);
116 @NonNull List
<Definition
> definitions
= read(input
, definitionScope
, fieldName
);
117 return new ArrayDefinition(this, definitionScope
, fieldName
, definitions
);
121 public String
toString() {
122 /* Only used for debugging */
123 return "[declaration] array[" + Integer
.toHexString(hashCode()) + ']'; //$NON-NLS-1$
126 private @NonNull List
<@NonNull Definition
> read(@NonNull BitBuffer input
, @Nullable IDefinitionScope definitionScope
, String fieldName
) throws CTFException
{
127 Builder
<@NonNull Definition
> definitions
= new ImmutableList
.Builder
<>();
128 if (!fChildrenNames
.containsKey(fieldName
)) {
129 for (int i
= 0; i
< fLength
; i
++) {
130 fChildrenNames
.put(fieldName
, fieldName
+ '[' + i
+ ']');
133 List
<String
> elemNames
= fChildrenNames
.get(fieldName
);
134 for (int i
= 0; i
< fLength
; i
++) {
135 String name
= elemNames
.get(i
);
137 throw new IllegalStateException();
139 definitions
.add(fElemType
.createDefinition(definitionScope
, name
, input
));
141 return checkNotNull(definitions
.build());
145 public int getMaximumSize() {
146 long val
= (long) fLength
* fElemType
.getMaximumSize();
147 return (int) Math
.min(Integer
.MAX_VALUE
, val
);
151 public int hashCode() {
152 final int prime
= 31;
154 result
= prime
* result
+ fElemType
.hashCode();
155 result
= prime
* result
+ fLength
;
160 public boolean equals(@Nullable Object obj
) {
167 if (getClass() != obj
.getClass()) {
170 ArrayDeclaration other
= (ArrayDeclaration
) obj
;
171 if (!fElemType
.equals(other
.fElemType
)) {
174 if (fLength
!= other
.fLength
) {
181 public boolean isBinaryEquivalent(@Nullable IDeclaration obj
) {
188 if (getClass() != obj
.getClass()) {
191 ArrayDeclaration other
= (ArrayDeclaration
) obj
;
192 if (!fElemType
.isBinaryEquivalent(other
.fElemType
)) {
195 if (fLength
!= other
.fLength
) {