1 /*******************************************************************************
2 * Copyright (c) 2014 Ericsson, Ecole Polytechnique de Montreal and others
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
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 *******************************************************************************/
12 package org
.eclipse
.linuxtools
.internal
.ctf
.core
.event
.types
;
14 import java
.util
.Collection
;
15 import java
.util
.List
;
17 import org
.eclipse
.jdt
.annotation
.NonNull
;
18 import org
.eclipse
.linuxtools
.ctf
.core
.event
.io
.BitBuffer
;
19 import org
.eclipse
.linuxtools
.ctf
.core
.event
.scope
.IDefinitionScope
;
20 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.AbstractArrayDefinition
;
21 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.CompoundDeclaration
;
22 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.Definition
;
23 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IDeclaration
;
24 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IDefinition
;
25 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IntegerDefinition
;
26 import org
.eclipse
.linuxtools
.ctf
.core
.trace
.CTFReaderException
;
28 import com
.google
.common
.collect
.ArrayListMultimap
;
29 import com
.google
.common
.collect
.ImmutableList
;
30 import com
.google
.common
.collect
.ImmutableList
.Builder
;
31 import com
.google
.common
.collect
.Multimap
;
34 * A CTF sequence declaration.
36 * An array where the size is fixed but declared in the trace, unlike array
37 * where it is declared with a literal
39 * @author Matthew Khouzam
42 public class SequenceDeclaration
extends CompoundDeclaration
{
44 // ------------------------------------------------------------------------
46 // ------------------------------------------------------------------------
48 private final IDeclaration fElemType
;
49 private final String fLengthName
;
50 private final Multimap
<String
, String
> fPaths
= ArrayListMultimap
.create();
52 // ------------------------------------------------------------------------
54 // ------------------------------------------------------------------------
60 * the name of the field describing the length
64 public SequenceDeclaration(String lengthName
, IDeclaration elemType
) {
66 fLengthName
= lengthName
;
69 // ------------------------------------------------------------------------
70 // Getters/Setters/Predicates
71 // ------------------------------------------------------------------------
74 public IDeclaration
getElementType() {
79 * Gets the name of the length field
81 * @return the name of the length field
83 public String
getLengthName() {
87 // ------------------------------------------------------------------------
89 // ------------------------------------------------------------------------
92 public AbstractArrayDefinition
createDefinition(
93 IDefinitionScope definitionScope
, String fieldName
, BitBuffer input
) throws CTFReaderException
{
94 IDefinition lenDef
= null;
96 if (definitionScope
!= null) {
97 lenDef
= definitionScope
.lookupDefinition(getLengthName());
100 if (lenDef
== null) {
101 throw new CTFReaderException("Sequence length field not found"); //$NON-NLS-1$
104 if (!(lenDef
instanceof IntegerDefinition
)) {
105 throw new CTFReaderException("Sequence length field not integer"); //$NON-NLS-1$
108 IntegerDefinition lengthDefinition
= (IntegerDefinition
) lenDef
;
110 if (lengthDefinition
.getDeclaration().isSigned()) {
111 throw new CTFReaderException("Sequence length must not be signed"); //$NON-NLS-1$
114 long length
= lengthDefinition
.getValue();
115 if ((length
> Integer
.MAX_VALUE
) || (!input
.canRead((int) length
* fElemType
.getMaximumSize()))) {
116 throw new CTFReaderException("Sequence length too long " + length
); //$NON-NLS-1$
120 // Don't create "useless" definitions
121 byte[] data
= new byte[(int) length
];
123 return new ByteArrayDefinition(this, definitionScope
, fieldName
, data
);
125 Collection
<String
> collection
= fPaths
.get(fieldName
);
126 while (collection
.size() < length
) {
127 fPaths
.put(fieldName
, fieldName
+ '[' + collection
.size() + ']');
129 List
<String
> paths
= (List
<String
>) fPaths
.get(fieldName
);
130 Builder
<Definition
> definitions
= new ImmutableList
.Builder
<>();
131 for (int i
= 0; i
< length
; i
++) {
132 @SuppressWarnings("null")
133 @NonNull String elemName
= paths
.get(i
);
134 definitions
.add(fElemType
.createDefinition(definitionScope
, elemName
, input
));
136 @SuppressWarnings("null")
137 @NonNull ImmutableList
<Definition
> build
= definitions
.build();
138 return new ArrayDefinition(this, definitionScope
, fieldName
, build
);
142 public String
toString() {
143 /* Only used for debugging */
144 return "[declaration] sequence[" + Integer
.toHexString(hashCode()) + ']'; //$NON-NLS-1$
148 public int getMaximumSize() {
149 return Integer
.MAX_VALUE
;