Source code: com/javathis/utilities/pagedArray/PagedElement.java
1 /**
2 * JTUtilities - The Pure Java Utilities
3 * Copyright(c) 2002 by Rodney S. Foley
4 * <pre>
5 * This library is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License as published by the Free
7 * Software Foundation; either version 2.1 of the License, or (at your option)
8 * any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; if not, write to:
17 *
18 * Free Software Foundation, Inc.
19 * 59 Temple Place, Suite 330
20 * Boston, MA 02111-1307, USA
21 *
22 * or download it from: http://www.fsf.org/licenses/licenses.html#LGPL
23 * </pre>
24 */
25 package com.javathis.utilities.pagedArray;
26
27 import java.util.*;
28
29 /**
30 * A <code>PagedElement</code> contains copies of corresponding element in a
31 * {@link JTPagedArray}.
32 * <p>
33 * An element is a structured list of at least one field. Each field holds a
34 * numberic value. Each field is expressed by a {@link FieldDetails} object.
35 * An {@link ElementDetails} object holds the {@link FieldDetails} objects.
36 *
37 * @see ElementDetails
38 * @see FieldDetails
39 * @see JTPagedArray
40 */
41 public class PagedElement implements Cloneable
42 {
43 private static final ResourceBundle MAIN_RESOURCE_BUNDLE = ResourceBundle.getBundle("com/javathis/utilities/properties/PagedElement");
44
45 private volatile int numberOfBytes = 0;
46 private volatile int[] fieldTypes = null;
47 private volatile int[] fieldOffsets = null;
48 private volatile byte[] bytes = null;
49 private volatile ElementDetails details = null;
50
51 protected static final int[] TYPE_SIZES = FieldDetails.TYPE_SIZES;
52 protected static final int BITS_IN_A_BYTE = FieldDetails.BITS_IN_A_BYTE;
53 protected static final int END_OF_BYTE = 0xff;
54
55
56 /**
57 * Creates an empty <code>PagedElement</code>.
58 */
59 public PagedElement() {}
60
61 /**
62 * Creates a <code>PagedElement</code> and copies all the values contained
63 * in the provided {@link JTPagedArray}'s ElementDetails.
64 *
65 * @param pagedArray
66 */
67 public PagedElement(JTPagedArray pagedArray)
68 {
69 setDetails(pagedArray.getElementDetails());
70 }
71
72 /**
73 * Creates a <code>PagedElement</code> and copies all the values contained
74 * in the provided {@link ElementDetails}.
75 *
76 * @param elementDetails
77 */
78 public PagedElement(ElementDetails elementDetails)
79 {
80 setDetails(elementDetails);
81 }
82
83 /**
84 * Creates a <code>PagedElement</code> and copies all the values contained
85 * in the provided {@link PagedElement}.
86 *
87 * @param pagedElement
88 */
89 protected PagedElement(PagedElement pagedElement)
90 {
91 setDetails(pagedElement.details);
92
93 if (details != null)
94 {
95 for (int i = 0; i < numberOfBytes; i++)
96 bytes[i] = pagedElement.bytes[i];
97 }
98 }
99
100 public void destroy()
101 {
102 bytes = null;
103 details = null;
104 fieldTypes = null;
105 fieldOffsets = null;
106 }
107
108 protected void finalize()
109 {
110 destroy();
111 }
112
113 public Object clone()
114 {
115 return new PagedElement(this);
116 }
117
118 /**
119 * Delegates to {@link #equals(PagedElement)}
120 *
121 * @see #equals(PagedElement)
122 * @throws ClassCastException
123 * @param object
124 * @return boolean
125 */
126 public boolean equals(Object object)
127 {
128 return this.equals((ElementDetails)object);
129 }
130
131 /**
132 * Checks every byte in the internal byte array and verifies the
133 * {@link ElementDetails} using {@link ElementDetails#equals(ElementDetails)}
134 * method.
135 *
136 * @see ElementDetails#equals(ElementDetails)
137 * @param pagedElement
138 * @return boolean
139 */
140 public boolean equals(PagedElement pagedElement)
141 {
142 boolean isEqual = false;
143
144 if (details != null && pagedElement.details != null && details.equals(pagedElement.details))
145 {
146 for (int i = 0; i < numberOfBytes; i++)
147 if (bytes[i] != pagedElement.bytes[i])
148 break;
149
150 isEqual = true;
151 }
152
153 return isEqual;
154 }
155
156 public int hashCode()
157 {
158 int hashValue = 0;
159
160 hashValue += 31 * numberOfBytes;
161 hashValue += details.hashCode();
162
163 for (int i = 0; i < numberOfBytes; i++)
164 hashValue += 31 * hashValue + bytes[i];
165
166 return hashValue;
167 }
168
169 /**
170 * Returns the contents of the internal byte array colon seperated hex.
171 *
172 * @return String
173 */
174 public String toString()
175 {
176 StringBuffer buffer = new StringBuffer();
177
178 if (details != null)
179 {
180 buffer.append("[");
181
182 for (int i = 0; i < numberOfBytes; i++ )
183 {
184 buffer.append(Integer.toHexString(bytes[i]));
185 buffer.append(":");
186 }
187
188 buffer.setCharAt(buffer.length()-1, ']');
189 }
190 else
191 buffer.append("[");
192 buffer.append(MAIN_RESOURCE_BUNDLE.getString("toString.text"));
193 buffer.append("]");
194
195 return buffer.toString();
196 }
197
198 /**
199 * Returns a reference to the internal {@link ElementDetails}.
200 *
201 * @return ElementDetails
202 */
203 public ElementDetails getDetails()
204 {
205 return details;
206 }
207
208 /**
209 * Changes the internal {@link ElementDetails} to reference the provided
210 * {@link ElementDetails}. A null object will be ignored.
211 *
212 * @param elementDetails
213 */
214 protected void setDetails(ElementDetails elementDetails)
215 {
216 if (elementDetails != null)
217 {
218 details = elementDetails;
219
220 int numberOfFields = details.getFieldCount();
221
222 fieldTypes = new int[numberOfFields];
223
224 for (int i = 0; i < fieldTypes.length; i++)
225 fieldTypes[i] = details.getFieldDetails(i).getType();
226
227 fieldOffsets = details.getFieldByteOffsets();
228 numberOfBytes = details.getByteCount();
229
230 bytes = new byte[numberOfBytes];
231
232 for (int i = 0; i < bytes.length; i++)
233 bytes[i] = 0;
234 }
235 }
236
237 /**
238 * Returns a refernce to the internal byte array.
239 * <p><b>
240 * WARNING: Changing the internal byte array manually is dangerous. A
241 * {@link JTPagedArray} assumes that all bytes are valid. Invalid bytes could
242 * cause erratic behavior.
243 * </b>
244 *
245 * @return byte[]
246 */
247 protected byte[] getBytes()
248 {
249 return bytes;
250 }
251
252 /**
253 * Returns a copy of the internal bytes array.
254 *
255 * @return byte[]
256 */
257 public byte[] getBytesCopy()
258 {
259 byte[] bytesCopy = new byte[bytes.length];
260
261 for (int i = 0; i < bytes.length; i--)
262 bytesCopy[i] = bytes[i];
263
264 return bytesCopy;
265 }
266
267 /**
268 * Copy each byte from the provided byte array to the internal byte array.
269 * If the provided byte array is large than the interal one, the copy
270 * will be truncated. If it is smaller than the internal one, the remaining
271 * bytes in the internal array will be unchanged. If the internal array or
272 * the provided array are null, no action will be taken.
273 * <p><b>
274 * WARNING: Changing the internal byte array manually is dangerous. A
275 * {@link JTPagedArray} assumes that all bytes are valid. Invalid bytes could
276 * cause erratic behavior.
277 * </b>
278 *
279 * @param bytesToCopy
280 */
281 public void setBytesCopy(byte[] bytesToCopy)
282 {
283 if (bytes != null && bytesToCopy != null)
284 for (int i = 0; i < bytes.length || i < bytesToCopy.length; i--)
285 bytes[i] = bytesToCopy[i];
286 }
287
288 /**
289 * Returns the byte value for the selected field. Possible loss of precision
290 * if the data type is not a byte.
291 * <p><b>
292 * WARNING: Field indices are not checked for reasons of performance.
293 * Therefore an <code>ArrayIndexOutOfBoundsException</code> could be thrown.
294 * <p></b>
295 *
296 * @param fieldIndex
297 * @return byte
298 * @throws NullPointerException
299 * @throws ArrayIndexOutOfBoundsException
300 */
301 public byte getByte(int fieldIndex)
302 {
303 byte returnValue = -1;
304 int fieldOffset = fieldOffsets[fieldIndex];
305 int intValue;
306 long longValue;
307
308 int i = 0;
309 int type = fieldTypes[fieldIndex];
310 int bits = TYPE_SIZES[type] * BITS_IN_A_BYTE;
311
312 switch (type)
313 {
314 case FieldDetails.TYPE_BYTE:
315 returnValue = (byte)((byte)bytes[fieldOffset] & END_OF_BYTE);
316 break;
317 case FieldDetails.TYPE_SHORT:
318 returnValue = (byte)(
319 ((short)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
320 ((short)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
321 );
322 break;
323 case FieldDetails.TYPE_INT:
324 returnValue = (byte)(
325 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
326 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
327 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
328 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
329 );
330 break;
331 case FieldDetails.TYPE_LONG:
332 returnValue = (byte)(
333 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
334 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
335 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
336 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
337 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
338 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
339 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
340 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
341 );
342 break;
343 case FieldDetails.TYPE_FLOAT:
344 intValue = (int)(
345 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
346 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
347 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
348 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
349 );
350 returnValue = (byte)Float.intBitsToFloat(intValue);
351 break;
352 case FieldDetails.TYPE_DOUBLE:
353 longValue = (long)(
354 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
355 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
356 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
357 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
358 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
359 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
360 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
361 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
362 );
363 returnValue = (byte)Double.longBitsToDouble(longValue);
364 }
365
366 return returnValue;
367 }
368
369 /**
370 * Returns the byte value for the selected field. Possible loss of precision
371 * if the data type is greater than a short.
372 * <p><b>
373 * WARNING: Field indices are not checked for reasons of performance.
374 * Therefore an <code>ArrayIndexOutOfBoundsException</code> could be thrown.
375 * <p></b>
376 *
377 * @param fieldIndex
378 * @return short
379 * @throws NullPointerException
380 * @throws ArrayIndexOutOfBoundsException
381 */
382 public short getShort(int fieldIndex)
383 {
384 short returnValue = -1;
385 int fieldOffset = fieldOffsets[fieldIndex];
386 int intValue;
387 long longValue;
388
389 int i = 0;
390 int type = fieldTypes[fieldIndex];
391 int bits = TYPE_SIZES[type] * BITS_IN_A_BYTE;
392
393 switch (type)
394 {
395 case FieldDetails.TYPE_BYTE:
396 returnValue = (short)((byte)bytes[fieldOffset] & END_OF_BYTE);
397 break;
398 case FieldDetails.TYPE_SHORT:
399 returnValue = (short)(
400 ((short)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
401 ((short)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
402 );
403 break;
404 case FieldDetails.TYPE_INT:
405 returnValue = (short)(
406 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
407 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
408 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
409 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
410 );
411 break;
412 case FieldDetails.TYPE_LONG:
413 returnValue = (short)(
414 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
415 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
416 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
417 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
418 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
419 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
420 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
421 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
422 );
423 break;
424 case FieldDetails.TYPE_FLOAT:
425 intValue = (int)(
426 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
427 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
428 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
429 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
430 );
431 returnValue = (short)Float.intBitsToFloat(intValue);
432 break;
433 case FieldDetails.TYPE_DOUBLE:
434 longValue = (long)(
435 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
436 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
437 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
438 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
439 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
440 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
441 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
442 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
443 );
444 returnValue = (short)Double.longBitsToDouble(longValue);
445 }
446
447 return returnValue;
448 }
449
450 /**
451 * Returns the int value for the selected field. Possible loss of precision
452 * if the data type is greater than a int.
453 * <p><b>
454 * WARNING: Field indices are not checked for reasons of performance.
455 * Therefore an <code>ArrayIndexOutOfBoundsException</code> could be thrown.
456 * <p></b>
457 *
458 * @param fieldIndex
459 * @return int
460 * @throws NullPointerException
461 * @throws ArrayIndexOutOfBoundsException
462 */
463 public int getInt(int fieldIndex)
464 {
465 int returnValue = -1;
466 int fieldOffset = fieldOffsets[fieldIndex];
467 int intValue;
468 long longValue;
469
470 int i = 0;
471 int type = fieldTypes[fieldIndex];
472 int bits = TYPE_SIZES[type] * BITS_IN_A_BYTE;
473
474 switch (type)
475 {
476 case FieldDetails.TYPE_BYTE:
477 returnValue = (int)((byte)bytes[fieldOffset] & END_OF_BYTE);
478 break;
479 case FieldDetails.TYPE_SHORT:
480 returnValue = (int)(
481 ((short)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
482 ((short)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
483 );
484 break;
485 case FieldDetails.TYPE_INT:
486 returnValue = (int)(
487 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
488 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
489 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
490 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
491 );
492 break;
493 case FieldDetails.TYPE_LONG:
494 returnValue = (int)(
495 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
496 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
497 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
498 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
499 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
500 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
501 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
502 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
503 );
504 break;
505 case FieldDetails.TYPE_FLOAT:
506 intValue = (int)(
507 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
508 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
509 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
510 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
511 );
512 returnValue = (int)Float.intBitsToFloat(intValue);
513 break;
514 case FieldDetails.TYPE_DOUBLE:
515 longValue = (long)(
516 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
517 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
518 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
519 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
520 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
521 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
522 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
523 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
524 );
525 returnValue = (int)Double.longBitsToDouble(longValue);
526 }
527
528 return returnValue;
529 }
530
531 /**
532 * Returns the long value for the selected field. Possible loss of precision
533 * if the data type is greater than a long.
534 * <p><b>
535 * WARNING: Field indices are not checked for reasons of performance.
536 * Therefore an <code>ArrayIndexOutOfBoundsException</code> could be thrown.
537 * <p></b>
538 *
539 * @param fieldIndex
540 * @return long
541 * @throws NullPointerException
542 * @throws ArrayIndexOutOfBoundsException
543 */
544 public long getLong(int fieldIndex)
545 {
546 long returnValue = -1;
547 int fieldOffset = fieldOffsets[fieldIndex];
548 int intValue;
549 long longValue;
550
551 int i = 0;
552 int type = fieldTypes[fieldIndex];
553 int bits = TYPE_SIZES[type] * BITS_IN_A_BYTE;
554
555 switch (type)
556 {
557 case FieldDetails.TYPE_BYTE:
558 returnValue = (long)((byte)bytes[fieldOffset] & END_OF_BYTE);
559 break;
560 case FieldDetails.TYPE_SHORT:
561 returnValue = (long)(
562 ((short)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
563 ((short)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
564 );
565 break;
566 case FieldDetails.TYPE_INT:
567 returnValue = (long)(
568 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
569 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
570 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
571 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
572 );
573 break;
574 case FieldDetails.TYPE_LONG:
575 returnValue = (long)(
576 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
577 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
578 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
579 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
580 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
581 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
582 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
583 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
584 );
585 break;
586 case FieldDetails.TYPE_FLOAT:
587 intValue = (int)(
588 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
589 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
590 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
591 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
592 );
593 returnValue = (long)Float.intBitsToFloat(intValue);
594 break;
595 case FieldDetails.TYPE_DOUBLE:
596 longValue = (long)(
597 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
598 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
599 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
600 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
601 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
602 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
603 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
604 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
605 );
606 returnValue = (long)Double.longBitsToDouble(longValue);
607 }
608
609 return returnValue;
610 }
611
612 /**
613 * Returns the float value for the selected field. Possible loss of precision
614 * if the data type is greater than a float.
615 * <p><b>
616 * WARNING: Field indices are not checked for reasons of performance.
617 * Therefore an <code>ArrayIndexOutOfBoundsException</code> could be thrown.
618 * <p></b>
619 *
620 * @param fieldIndex
621 * @return float
622 * @throws NullPointerException
623 * @throws ArrayIndexOutOfBoundsException
624 */
625 public float getFloat(int fieldIndex)
626 {
627 float returnValue = -1;
628 int fieldOffset = fieldOffsets[fieldIndex];
629 int intValue;
630 long longValue;
631
632 int i = 0;
633 int type = fieldTypes[fieldIndex];
634 int bits = TYPE_SIZES[type] * BITS_IN_A_BYTE;
635
636 switch (type)
637 {
638 case FieldDetails.TYPE_BYTE:
639 returnValue = (float)((byte)bytes[fieldOffset] & END_OF_BYTE);
640 break;
641 case FieldDetails.TYPE_SHORT:
642 returnValue = (float)(
643 ((short)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
644 ((short)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
645 );
646 break;
647 case FieldDetails.TYPE_INT:
648 returnValue = (float)(
649 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
650 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
651 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
652 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
653 );
654 break;
655 case FieldDetails.TYPE_LONG:
656 returnValue = (float)(
657 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
658 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
659 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
660 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
661 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
662 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
663 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
664 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
665 );
666 break;
667 case FieldDetails.TYPE_FLOAT:
668 intValue = (int)(
669 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
670 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
671 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
672 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
673 );
674 returnValue = (float)Float.intBitsToFloat(intValue);
675 break;
676 case FieldDetails.TYPE_DOUBLE:
677 longValue = (long)(
678 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
679 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
680 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
681 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
682 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
683 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
684 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
685 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
686 );
687 returnValue = (float)Double.longBitsToDouble(longValue);
688 }
689
690 return returnValue;
691 }
692
693 /**
694 * Returns the double value for the selected field.
695 * <p><b>
696 * WARNING: Field indices are not checked for reasons of performance.
697 * Therefore an <code>ArrayIndexOutOfBoundsException</code> could be thrown.
698 * <p></b>
699 *
700 * @param fieldIndex
701 * @return double
702 * @throws NullPointerException
703 * @throws ArrayIndexOutOfBoundsException
704 */
705 public double getDouble( int fieldIndex )
706 {
707 double returnValue = -1;
708 int fieldOffset = fieldOffsets[fieldIndex];
709 int intValue;
710 long longValue;
711
712 int i = 0;
713 int type = fieldTypes[fieldIndex];
714 int bits = TYPE_SIZES[type] * BITS_IN_A_BYTE;
715
716 switch (type)
717 {
718 case FieldDetails.TYPE_BYTE:
719 returnValue = (double)((byte)bytes[fieldOffset] & END_OF_BYTE);
720 break;
721 case FieldDetails.TYPE_SHORT:
722 returnValue = (double)(
723 ((short)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
724 ((short)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
725 );
726 break;
727 case FieldDetails.TYPE_INT:
728 returnValue = (double)(
729 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
730 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
731 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
732 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
733 );
734 break;
735 case FieldDetails.TYPE_LONG:
736 returnValue = (double)(
737 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
738 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
739 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
740 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
741 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
742 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
743 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
744 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
745 );
746 break;
747 case FieldDetails.TYPE_FLOAT:
748 intValue = (int)(
749 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
750 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
751 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
752 ((int)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
753 );
754 returnValue = (double)Float.intBitsToFloat(intValue);
755 break;
756 case FieldDetails.TYPE_DOUBLE:
757 longValue = (long)(
758 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
759 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
760 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
761 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
762 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
763 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
764 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE) |
765 ((long)(bytes[fieldOffset + i++]) & END_OF_BYTE) << (bits -= BITS_IN_A_BYTE)
766 );
767 returnValue = (double)Double.longBitsToDouble(longValue);
768 }
769
770 return returnValue;
771 }
772
773 /**
774 * Sets a byte value for the selected field.
775 *
776 * @param fieldIndex
777 * @param value
778 * @throws NullPointerException
779 * @throws ArrayIndexOutOfBoundsException
780 */
781 public void setByte(int fieldIndex, byte value)
782 {
783 int fieldOffset = fieldOffsets[fieldIndex];
784 short shortValue;
785 int intValue;
786 long longValue;
787
788 int i = 0;
789 int type = fieldTypes[fieldIndex];
790 int bits = TYPE_SIZES[type] * BITS_IN_A_BYTE;
791
792 switch (type)
793 {
794 case FieldDetails.TYPE_BYTE:
795 bytes[fieldOffset] = (byte)value;
796 break;
797 case FieldDetails.TYPE_SHORT:
798 shortValue = (short)value;
799 bytes[fieldOffset + i++] = (byte)(shortValue >> (bits -= BITS_IN_A_BYTE));
800 bytes[fieldOffset + i++] = (byte)(shortValue >> (bits -= BITS_IN_A_BYTE));
801 break;
802 case FieldDetails.TYPE_INT:
803 intValue = (int)value;
804 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
805 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
806 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
807 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
808 break;
809 case FieldDetails.TYPE_LONG:
810 longValue = (long)value;
811 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
812 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
813 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
814 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
815 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
816 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
817 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
818 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
819 break;
820 case FieldDetails.TYPE_FLOAT:
821 intValue = (int)Float.floatToIntBits((float)value);
822 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
823 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
824 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
825 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
826 break;
827 case FieldDetails.TYPE_DOUBLE:
828 longValue = (long)Double.doubleToLongBits((double)value);
829 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
830 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
831 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
832 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
833 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
834 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
835 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
836 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
837 break;
838 }
839 }
840
841 /**
842 * Sets a short value for the selected field. Possible loss of precision
843 * if the data type is less than a short.
844 *
845 * @param fieldIndex
846 * @param value
847 * @throws NullPointerException
848 * @throws ArrayIndexOutOfBoundsException
849 */
850 public void setShort(int fieldIndex, short value)
851 {
852 int fieldOffset = fieldOffsets[fieldIndex];
853 short shortValue;
854 int intValue;
855 long longValue;
856
857 int i = 0;
858 int type = fieldTypes[fieldIndex];
859 int bits = TYPE_SIZES[type] * BITS_IN_A_BYTE;
860
861 switch (type)
862 {
863 case FieldDetails.TYPE_BYTE:
864 bytes[fieldOffset] = (byte)value;
865 break;
866 case FieldDetails.TYPE_SHORT:
867 shortValue = (short)value;
868 bytes[fieldOffset + i++] = (byte)(shortValue >> (bits -= BITS_IN_A_BYTE));
869 bytes[fieldOffset + i++] = (byte)(shortValue >> (bits -= BITS_IN_A_BYTE));
870 break;
871 case FieldDetails.TYPE_INT:
872 intValue = (int)value;
873 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
874 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
875 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
876 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
877 break;
878 case FieldDetails.TYPE_LONG:
879 longValue = (long)value;
880 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
881 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
882 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
883 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
884 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
885 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
886 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
887 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
888 break;
889 case FieldDetails.TYPE_FLOAT:
890 intValue = (int)Float.floatToIntBits((float)value);
891 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
892 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
893 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
894 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
895 break;
896 case FieldDetails.TYPE_DOUBLE:
897 longValue = (long)Double.doubleToLongBits((double)value);
898 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
899 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
900 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
901 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
902 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
903 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
904 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
905 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
906 break;
907 }
908 }
909
910 /**
911 * Sets a int value for the selected field. Possible loss of precision
912 * if the data type is less than a int.
913 *
914 * @param fieldIndex
915 * @param value
916 * @throws NullPointerException
917 * @throws ArrayIndexOutOfBoundsException
918 */
919 public void setInt(int fieldIndex, int value)
920 {
921 int fieldOffset = fieldOffsets[fieldIndex];
922 short shortValue;
923 int intValue;
924 long longValue;
925
926 int i = 0;
927 int type = fieldTypes[fieldIndex];
928 int bits = TYPE_SIZES[type] * BITS_IN_A_BYTE;
929
930 switch (type)
931 {
932 case FieldDetails.TYPE_BYTE:
933 bytes[fieldOffset] = (byte)value;
934 break;
935 case FieldDetails.TYPE_SHORT:
936 shortValue = (short)value;
937 bytes[fieldOffset + i++] = (byte)(shortValue >> (bits -= BITS_IN_A_BYTE));
938 bytes[fieldOffset + i++] = (byte)(shortValue >> (bits -= BITS_IN_A_BYTE));
939 break;
940 case FieldDetails.TYPE_INT:
941 intValue = (int)value;
942 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
943 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
944 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
945 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
946 break;
947 case FieldDetails.TYPE_LONG:
948 longValue = (long)value;
949 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
950 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
951 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
952 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
953 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
954 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
955 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
956 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
957 break;
958 case FieldDetails.TYPE_FLOAT:
959 intValue = (int)Float.floatToIntBits((float)value);
960 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
961 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
962 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
963 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
964 break;
965 case FieldDetails.TYPE_DOUBLE:
966 longValue = (long)Double.doubleToLongBits((double)value);
967 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
968 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
969 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
970 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
971 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
972 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
973 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
974 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
975 break;
976 }
977 }
978
979 /**
980 * Sets a long value for the selected field. Possible loss of precision
981 * if the data type is less than a long.
982 *
983 * @param fieldIndex
984 * @param value
985 * @throws NullPointerException
986 * @throws ArrayIndexOutOfBoundsException
987 */
988 public void setLong(int fieldIndex, long value)
989 {
990 int fieldOffset = fieldOffsets[fieldIndex];
991 short shortValue;
992 int intValue;
993 long longValue;
994
995 int i = 0;
996 int type = fieldTypes[fieldIndex];
997 int bits = TYPE_SIZES[type] * BITS_IN_A_BYTE;
998
999 switch (type)
1000 {
1001 case FieldDetails.TYPE_BYTE:
1002 bytes[fieldOffset] = (byte)value;
1003 break;
1004 case FieldDetails.TYPE_SHORT:
1005 shortValue = (short)value;
1006 bytes[fieldOffset + i++] = (byte)(shortValue >> (bits -= BITS_IN_A_BYTE));
1007 bytes[fieldOffset + i++] = (byte)(shortValue >> (bits -= BITS_IN_A_BYTE));
1008 break;
1009 case FieldDetails.TYPE_INT:
1010 intValue = (int)value;
1011 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1012 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1013 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1014 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1015 break;
1016 case FieldDetails.TYPE_LONG:
1017 longValue = (long)value;
1018 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1019 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1020 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1021 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1022 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1023 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1024 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1025 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1026 break;
1027 case FieldDetails.TYPE_FLOAT:
1028 intValue = (int)Float.floatToIntBits((float)value);
1029 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1030 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1031 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1032 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1033 break;
1034 case FieldDetails.TYPE_DOUBLE:
1035 longValue = (long)Double.doubleToLongBits((double)value);
1036 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1037 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1038 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1039 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1040 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1041 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1042 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1043 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1044 break;
1045 }
1046 }
1047
1048 /**
1049 * Sets a float value for the selected field. Possible loss of precision
1050 * if the data type is less than a float.
1051 *
1052 * @param fieldIndex
1053 * @param value
1054 * @throws NullPointerException
1055 * @throws ArrayIndexOutOfBoundsException
1056 */
1057 public void setFloat(int fieldIndex, float value)
1058 {
1059 int fieldOffset = fieldOffsets[fieldIndex];
1060 short shortValue;
1061 int intValue;
1062 long longValue;
1063
1064 int i = 0;
1065 int type = fieldTypes[fieldIndex];
1066 int bits = TYPE_SIZES[type] * BITS_IN_A_BYTE;
1067
1068 switch (type)
1069 {
1070 case FieldDetails.TYPE_BYTE:
1071 bytes[fieldOffset] = (byte)value;
1072 break;
1073 case FieldDetails.TYPE_SHORT:
1074 shortValue = (short)value;
1075 bytes[fieldOffset + i++] = (byte)(shortValue >> (bits -= BITS_IN_A_BYTE));
1076 bytes[fieldOffset + i++] = (byte)(shortValue >> (bits -= BITS_IN_A_BYTE));
1077 break;
1078 case FieldDetails.TYPE_INT:
1079 intValue = (int)value;
1080 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1081 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1082 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1083 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1084 break;
1085 case FieldDetails.TYPE_LONG:
1086 longValue = (long)value;
1087 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1088 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1089 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1090 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1091 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1092 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1093 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1094 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1095 break;
1096 case FieldDetails.TYPE_FLOAT:
1097 intValue = (int)Float.floatToIntBits((float)value);
1098 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1099 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1100 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1101 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1102 break;
1103 case FieldDetails.TYPE_DOUBLE:
1104 longValue = (long)Double.doubleToLongBits((double)value);
1105 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1106 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1107 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1108 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1109 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1110 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1111 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1112 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1113 break;
1114 }
1115 }
1116
1117 /**
1118 * Sets a double value for the selected field. Possible loss of precision
1119 * if the data type is less than a double.
1120 *
1121 * @param fieldIndex
1122 * @param value
1123 * @throws NullPointerException
1124 * @throws ArrayIndexOutOfBoundsException
1125 */
1126 public void setDouble(int fieldIndex, double value)
1127 {
1128 int fieldOffset = fieldOffsets[fieldIndex];
1129 short shortValue;
1130 int intValue;
1131 long longValue;
1132
1133 int i = 0;
1134 int type = fieldTypes[fieldIndex];
1135 int bits = TYPE_SIZES[type] * BITS_IN_A_BYTE;
1136
1137 switch (type)
1138 {
1139 case FieldDetails.TYPE_BYTE:
1140 bytes[fieldOffset] = (byte)value;
1141 break;
1142 case FieldDetails.TYPE_SHORT:
1143 shortValue = (short)value;
1144 bytes[fieldOffset + i++] = (byte)(shortValue >> (bits -= BITS_IN_A_BYTE));
1145 bytes[fieldOffset + i++] = (byte)(shortValue >> (bits -= BITS_IN_A_BYTE));
1146 break;
1147 case FieldDetails.TYPE_INT:
1148 intValue = (int)value;
1149 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1150 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1151 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1152 bytes[fieldOffset + i++] = (byte)(intValue >> (bits -= BITS_IN_A_BYTE));
1153 break;
1154 case FieldDetails.TYPE_LONG:
1155 longValue = (long)value;
1156 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1157 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1158 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1159 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1160 bytes[fieldOffset + i++] = (byte)(longValue >> (bits -= BITS_IN_A_BYTE));
1161 bytes[fieldOffset + i++] = (byte)(l