1 package org.lcsim.detector.identifier;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.HashMap;
6 import java.util.LinkedHashMap;
7 import java.util.List;
8 import java.util.Map;
9
10
11
12
13
14
15
16
17
18
19 public final class IdentifierDictionary implements IIdentifierDictionary
20 {
21
22 private IIdentifierField fieldArray[] = null;
23
24
25 private Map<String, IIdentifierField> fieldMap = new LinkedHashMap<String, IIdentifierField>();
26
27
28 private Map<String, Integer> fieldIndices = new HashMap<String, Integer>();
29
30
31 private final String name;
32
33
34 protected int numberOfFields;
35
36
37 protected int maxIndex;
38
39
40
41
42
43
44
45 public IdentifierDictionary(String name, List<IIdentifierField> fieldList)
46 {
47
48 this.name = name;
49
50
51 addFields(fieldList);
52
53
54 numberOfFields = fieldList.size();
55
56
57 maxIndex = numberOfFields - 1;
58
59
60 }
61
62
63
64
65
66 public String getName()
67 {
68 return name;
69 }
70
71
72
73
74
75 public List<IIdentifierField> getFieldList() {
76 return Arrays.asList(fieldArray);
77 }
78
79
80
81
82
83 public IIdentifierField getField(String fieldName)
84 {
85 return fieldMap.get(fieldName);
86 }
87
88
89
90
91
92
93 public IIdentifierField getField(int index)
94 {
95 return fieldArray[index];
96 }
97
98
99
100
101
102 public int getFieldIndex(String fieldName)
103 {
104 return fieldIndices.get(fieldName);
105 }
106
107
108
109
110
111
112 public List<String> getFieldNames()
113 {
114 return new ArrayList<String>(fieldMap.keySet());
115 }
116
117
118
119
120
121 public int getNumberOfFields()
122 {
123 return numberOfFields;
124 }
125
126
127
128
129
130 public int getMaxIndex()
131 {
132 return maxIndex;
133 }
134
135
136
137
138
139 public boolean hasField(String fieldName)
140 {
141 return fieldMap.containsKey(fieldName);
142 }
143
144
145
146
147
148 public IExpandedIdentifier unpack(IIdentifier compact)
149 {
150 ExpandedIdentifier expId = new ExpandedIdentifier();
151 long id = compact.getValue();
152
153 for (int i = 0; i < numberOfFields; i++ )
154 {
155 IIdentifierField field = getField(i);
156
157 int start = field.getOffset();
158 int length = field.getNumberOfBits();
159 int mask = field.getIntegerMask();
160
161 int result = (int)((id >> start) & mask);
162 if (field.isSigned())
163 {
164 int signBit = 1 << (length - 1);
165 if ((result & signBit) != 0)
166 result -= (1 << length);
167 }
168
169 expId.addValue(result);
170 }
171
172 return expId;
173 }
174
175 public IExpandedIdentifier unpack(IIdentifier compact, List<Integer> indices)
176 {
177 ExpandedIdentifier buffer = new ExpandedIdentifier();
178
179 long id = compact.getValue();
180
181 for ( int i=0; i<numberOfFields; i++)
182 {
183 if (indices.contains(i))
184 {
185 IIdentifierField field = getField(i);
186
187 int start = field.getOffset();
188 int length = field.getNumberOfBits();
189 int mask = field.getIntegerMask();
190
191 int result = (int) ((id >> start) & mask);
192 if (field.isSigned())
193 {
194 int signBit = 1<<(length-1);
195 if ((result & signBit) != 0) result -= (1<<length);
196 }
197
198 buffer.addValue(result);
199 }
200 else
201 {
202 buffer.addValue(0);
203 }
204 }
205
206 return buffer;
207 }
208
209
210
211
212
213
214
215 public IIdentifier pack(IExpandedIdentifier id)
216 {
217 long result = 0;
218
219 for (int i = 0; i <= maxIndex; i++ )
220 {
221 IIdentifierField field = getField(i);
222
223 int start = field.getOffset();
224 long mask = field.getLongMask();
225 result |= (mask & id.getValue(i)) << start;
226 }
227
228 return new Identifier(result);
229 }
230
231
232
233
234
235
236
237 public int getFieldValue(IIdentifier compact, String field)
238 {
239 return getField(field).unpack(compact);
240 }
241
242
243
244
245
246
247
248 public int getFieldValue(IIdentifier compact, int idx)
249 {
250 return getField(idx).unpack(compact);
251 }
252
253
254
255
256
257
258 private void addField(IIdentifierField field, int index)
259 {
260
261 if (fieldMap.containsKey(field.getLabel()))
262 {
263 throw new RuntimeException("Duplicate field name <" + field.getLabel() + "> in IdDict <" + getName() + ">.");
264 }
265
266
267 fieldMap.put(field.getLabel(), field);
268
269
270 fieldArray[index] = field;
271
272
273 fieldIndices.put(field.getLabel(), index);
274 }
275
276
277
278
279
280
281 private void addFields(List<IIdentifierField> fields)
282 {
283
284 fieldArray = new IIdentifierField[fields.size()];
285
286
287 int fieldIndex = 0;
288 for (int i = 0, n = fields.size(); i < n; i++ )
289 {
290 IIdentifierField field = fields.get(i);
291 addField(field, i);
292 fieldArray[fieldIndex] = field;
293 ++fieldIndex;
294 }
295 }
296
297
298
299
300
301
302
303
304 public boolean isValid(IExpandedIdentifier id)
305 {
306 int size = id.size();
307 if (size != numberOfFields)
308 {
309 return false;
310 }
311 for (int i = 0, n = id.getMaxIndex(); i < n; i++ )
312 {
313 IIdentifierField field = getField(i);
314 if (!field.isValidValue(id.getValue(i)))
315 return false;
316 }
317 return true;
318 }
319
320
321
322
323
324 public String toString()
325 {
326 StringBuffer str = new StringBuffer();
327 str.append(getName() + '\n');
328 for (IIdentifierField field : fieldMap.values())
329 {
330 str.append(" " + field.toString());
331 }
332 return str.toString();
333 }
334
335 }