ctf: Throw CTFReaderException in the BitBuffer API
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / event / types / SequenceDefinition.java
1 /*******************************************************************************
2 * Copyright (c) 2011-2012 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 * Contributors: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.ctf.core.event.types;
14
15 import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer;
16 import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException;
17
18 /**
19 * A CTF sequence definition (a fixed-size array).
20 *
21 * An array where the size is fixed but declared in the trace, unlike array
22 * where it is declared with a literal
23 *
24 * @version 1.0
25 * @author Matthew Khouzam
26 * @author Simon Marchi
27 */
28 public class SequenceDefinition extends Definition {
29
30 // ------------------------------------------------------------------------
31 // Attributes
32 // ------------------------------------------------------------------------
33
34 private final SequenceDeclaration declaration;
35 private final IntegerDefinition lengthDefinition;
36 private Definition definitions[];
37 private int currentLength;
38
39 // ------------------------------------------------------------------------
40 // Constructors
41 // ------------------------------------------------------------------------
42
43 /**
44 * Constructor
45 *
46 * @param declaration
47 * the parent declaration
48 * @param definitionScope
49 * the parent scope
50 * @param fieldName
51 * the field name
52 * @throws CTFReaderException
53 * If the sequence field was malformatted
54 */
55 public SequenceDefinition(SequenceDeclaration declaration,
56 IDefinitionScope definitionScope, String fieldName)
57 throws CTFReaderException {
58 super(definitionScope, fieldName);
59 Definition lenDef = null;
60
61 this.declaration = declaration;
62
63 if (definitionScope != null) {
64 lenDef = definitionScope.lookupDefinition(declaration
65 .getLengthName());
66 }
67
68 if (lenDef == null) {
69 throw new CTFReaderException("Sequence length field not found"); //$NON-NLS-1$
70 }
71
72 if (!(lenDef instanceof IntegerDefinition)) {
73 throw new CTFReaderException("Sequence length field not integer"); //$NON-NLS-1$
74 }
75
76 lengthDefinition = (IntegerDefinition) lenDef;
77
78 if (this.lengthDefinition.getDeclaration().isSigned()) {
79 throw new CTFReaderException("Sequence length must not be signed"); //$NON-NLS-1$
80 }
81 }
82
83 // ------------------------------------------------------------------------
84 // Getters/Setters/Predicates
85 // ------------------------------------------------------------------------
86
87 @Override
88 public SequenceDeclaration getDeclaration() {
89 return declaration;
90 }
91
92 /**
93 * The length of the sequence in number of elements so a sequence of 5
94 * GIANT_rediculous_long_ints is the same as a sequence of 5 bits. (5)
95 *
96 * @return the length of the sequence
97 */
98 public int getLength() {
99 return currentLength;
100 }
101
102 /**
103 * Get the element at i
104 *
105 * @param i
106 * the index (cannot be negative)
107 * @return The element at I, if I > length, null, if I < 0, the method
108 * throws an out of bounds exception
109 */
110 public Definition getElem(int i) {
111 if (i > definitions.length) {
112 return null;
113 }
114
115 return definitions[i];
116 }
117
118 /**
119 * Is the sequence a null terminated string?
120 * @return true == is a string, false == is not a string
121 */
122 public boolean isString() {
123 IntegerDeclaration elemInt;
124
125 if (declaration.getElementType() instanceof IntegerDeclaration) {
126 elemInt = (IntegerDeclaration) declaration.getElementType();
127 if (elemInt.isCharacter()) {
128 return true;
129 }
130 }
131 return false;
132 }
133
134 // ------------------------------------------------------------------------
135 // Operations
136 // ------------------------------------------------------------------------
137
138 @Override
139 public void read(BitBuffer input) throws CTFReaderException {
140 currentLength = (int) lengthDefinition.getValue();
141
142 if ((definitions == null) || (definitions.length < currentLength)) {
143 Definition newDefinitions[] = new Definition[currentLength];
144
145 int i = 0;
146
147 if (definitions != null) {
148 System.arraycopy(definitions, 0, newDefinitions, 0, definitions.length);
149 }
150
151 for (; i < currentLength; i++) {
152 newDefinitions[i] = declaration.getElementType()
153 .createDefinition(getDefinitionScope(),
154 getFieldName() + "[" + i + "]"); //$NON-NLS-1$ //$NON-NLS-2$
155 }
156
157 definitions = newDefinitions;
158 }
159
160 for (int i = 0; i < currentLength; i++) {
161 definitions[i].read(input);
162 }
163 }
164
165 @Override
166 public String toString() {
167 StringBuilder b = new StringBuilder();
168
169 if (this.isString()) {
170 for (int i = 0; i < currentLength; i++) {
171 IntegerDefinition character = (IntegerDefinition) definitions[i];
172
173 if (character.getValue() == 0) {
174 break;
175 }
176
177 b.append(character.toString());
178 }
179 } else {
180 b.append('[');
181 if (currentLength > 0) {
182 for (int i = 0; i < (currentLength - 1); i++) {
183 b.append(' ');
184 b.append(definitions[i].toString());
185 b.append(',');
186 }
187 b.append(' ');
188 b.append(definitions[currentLength - 1].toString());
189 }
190 b.append(" ]"); //$NON-NLS-1$
191
192 }
193
194 return b.toString();
195 }
196 }
This page took 0.037315 seconds and 5 git commands to generate.