1 9 package javolution.io; 10 11 import j2me.lang.UnsupportedOperationException; 12 import j2me.nio.ByteBuffer; 13 import j2me.nio.ByteOrder; 14 import j2me.util.List; 15 import javolution.JavolutionError; 16 import javolution.lang.Enum; 17 import javolution.lang.Reflection; 18 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.io.OutputStream ; 22 23 136 public class Struct { 137 138 141 private Struct _outer; 142 143 146 private ByteBuffer _byteBuffer; 147 148 152 private int _outerOffset; 153 154 157 private int _bitsUsed; 158 159 162 private int _alignment = 1; 163 164 167 private int _bitIndex; 168 169 172 private boolean _resetIndex; 173 174 177 private byte[] _bytes; 178 179 182 public Struct() { 183 _resetIndex = isUnion(); 184 } 185 186 193 public final int size() { 194 int nbrOfBytes = (_bitsUsed + 7) >> 3; 195 return ((nbrOfBytes % _alignment) == 0) ? nbrOfBytes : nbrOfBytes + _alignment - (nbrOfBytes % _alignment); } 198 199 213 public final ByteBuffer getByteBuffer() { 214 if (_outer != null) 215 return _outer.getByteBuffer(); 216 return (_byteBuffer != null) ? _byteBuffer : newBuffer(); 217 } 218 219 private synchronized ByteBuffer newBuffer() { 220 if (_byteBuffer != null) 221 return _byteBuffer; int size = size(); 223 int capacity = isPacked() ? (((size & 0x7) == 0) ? size : size + 8 225 - (size & 0x7)) : size; 226 ByteBuffer bf = ByteBuffer.allocateDirect(capacity); 227 bf.order(byteOrder()); 228 setByteBuffer(bf, 0); 229 return _byteBuffer; 230 } 231 232 246 public final Struct setByteBuffer(ByteBuffer byteBuffer, int position) { 247 if (byteBuffer.order() != byteOrder()) 248 throw new IllegalArgumentException ( 249 "The byte order of the specified byte buffer" 250 + " is different from this struct byte order"); 251 if (_outer != null) 252 throw new UnsupportedOperationException ( 253 "Inner struct byte buffer is inherited from outer"); 254 _byteBuffer = byteBuffer; 255 _outerOffset = position; 256 return this; 257 } 258 259 266 public final Struct setByteBufferPosition(int position) { 267 return setByteBuffer(this.getByteBuffer(), position); 268 } 269 270 276 public final int getByteBufferPosition() { 277 return (_outer != null) ? _outer.getByteBufferPosition() + _outerOffset 278 : _outerOffset; 279 } 280 281 291 public int read(InputStream in) throws IOException { 292 ByteBuffer buffer = getByteBuffer(); 293 if (buffer.hasArray()) { 294 int offset = buffer.arrayOffset() + getByteBufferPosition(); 295 return in.read(buffer.array(), offset, size()); 296 } else { 297 synchronized (buffer) { 298 if (_bytes == null) { 299 _bytes = new byte[size()]; 300 } 301 int bytesRead = in.read(_bytes); 302 buffer.position(getByteBufferPosition()); 303 buffer.put(_bytes); 304 return bytesRead; 305 } 306 } 307 } 308 309 317 public void write(OutputStream out) throws IOException { 318 ByteBuffer buffer = getByteBuffer(); 319 if (buffer.hasArray()) { 320 int offset = buffer.arrayOffset() + getByteBufferPosition(); 321 out.write(buffer.array(), offset, size()); 322 } else { 323 synchronized (buffer) { 324 if (_bytes == null) { 325 _bytes = new byte[size()]; 326 } 327 buffer.position(getByteBufferPosition()); 328 buffer.get(_bytes); 329 out.write(_bytes); 330 } 331 } 332 } 333 334 344 public final long address() { 345 ByteBuffer thisBuffer = this.getByteBuffer(); 346 if (ADDRESS_METHOD != null) { 347 Long start = (Long ) ADDRESS_METHOD.invoke(thisBuffer); 348 return start.longValue() + getByteBufferPosition(); 349 } else { 350 throw new UnsupportedOperationException ( 351 "Operation not supported for " + thisBuffer.getClass()); 352 } 353 } 354 355 private static final Reflection.Method ADDRESS_METHOD = Reflection 356 .getMethod("sun.nio.ch.DirectBuffer.address()"); 357 358 378 public String toString() { 379 final int size = size(); 380 StringBuffer sb = new StringBuffer (size * 3); 381 final ByteBuffer buffer = getByteBuffer(); 382 final int start = getByteBufferPosition(); 383 for (int i = 0; i < size; i++) { 384 int b = buffer.get(start + i) & 0xFF; 385 sb.append(HEXA[b >> 4]); 386 sb.append(HEXA[b & 0xF]); 387 sb.append(((i & 0xF) == 0xF) ? '\n' : ' '); 388 } 389 return sb.toString(); 390 } 391 392 private static final char[] HEXA = { '0', '1', '2', '3', '4', '5', '6', 393 '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 394 395 399 420 public boolean isUnion() { 421 return false; 422 } 423 424 439 public ByteOrder byteOrder() { 440 return (_outer != null) ? _outer.byteOrder() : ByteOrder.BIG_ENDIAN; 441 } 442 443 461 public boolean isPacked() { 462 return (_outer != null) ? _outer.isPacked() : false; 463 } 464 465 473 protected Struct inner(Struct struct) { 474 if (struct._outer != null) 475 throw new IllegalArgumentException ( 476 "struct: Already an inner struct"); 477 struct._outer = this; 478 final int bitSize = struct.size() << 3; 479 updateIndexes(struct._alignment, bitSize, bitSize); 480 struct._outerOffset = (_bitIndex - bitSize) >> 3; 481 return (Struct) struct; 482 } 483 484 494 protected Struct[] array(Struct[] structs) { 495 Class structClass = null; 496 boolean resetIndexSaved = _resetIndex; 497 if (_resetIndex) { 498 _bitIndex = 0; 499 _resetIndex = false; } 501 for (int i = 0; i < structs.length;) { 502 Struct struct = structs[i]; 503 if (struct == null) { 504 try { 505 if (structClass == null) { 506 String arrayName = structs.getClass().getName(); 507 String structName = arrayName.substring(2, arrayName 508 .length() - 1); 509 structClass = Reflection.getClass(structName); 510 if (structClass == null) throw new 511 JavolutionError("Struct class: " + structName + " not found"); 512 } 513 struct = (Struct) structClass.newInstance(); 514 } catch (Exception e) { 515 throw new JavolutionError(e); 516 } 517 } 518 structs[i++] = inner(struct); 519 } 520 _resetIndex = resetIndexSaved; 521 return (Struct[]) structs; 522 } 523 524 534 protected Struct[][] array( 535 Struct[][] structs) { 536 boolean resetIndexSaved = _resetIndex; 537 if (_resetIndex) { 538 _bitIndex = 0; 539 _resetIndex = false; } 541 for (int i = 0; i < structs.length; i++) { 542 array(structs[i]); 543 } 544 _resetIndex = resetIndexSaved; 545 return (Struct[][]) structs; 546 } 547 548 558 protected Struct[][][] array( 559 Struct[][][] structs) { 560 boolean resetIndexSaved = _resetIndex; 561 if (_resetIndex) { 562 _bitIndex = 0; 563 _resetIndex = false; } 565 for (int i = 0; i < structs.length; i++) { 566 array(structs[i]); 567 } 568 _resetIndex = resetIndexSaved; 569 return (Struct[][][]) structs; 570 } 571 572 582 protected Member[] array( 583 Member[] arrayMember) { 584 boolean resetIndexSaved = _resetIndex; 585 if (_resetIndex) { 586 _bitIndex = 0; 587 _resetIndex = false; } 589 if (BOOL.isInstance(arrayMember)) { 590 for (int i = 0; i < arrayMember.length;) 591 arrayMember[i++] = (Member) this.new Bool(); 592 } else if (SIGNED_8.isInstance(arrayMember)) { 593 for (int i = 0; i < arrayMember.length;) 594 arrayMember[i++] = (Member) this.new Signed8(); 595 } else if (UNSIGNED_8.isInstance(arrayMember)) { 596 for (int i = 0; i < arrayMember.length;) 597 arrayMember[i++] = (Member) this.new Unsigned8(); 598 } else if (SIGNED_16.isInstance(arrayMember)) { 599 for (int i = 0; i < arrayMember.length;) 600 arrayMember[i++] = (Member) this.new Signed16(); 601 } else if (UNSIGNED_16.isInstance(arrayMember)) { 602 for (int i = 0; i < arrayMember.length;) 603 arrayMember[i++] = (Member) this.new Unsigned16(); 604 } else if (SIGNED_32.isInstance(arrayMember)) { 605 for (int i = 0; i < arrayMember.length;) 606 arrayMember[i++] = (Member) this.new Signed32(); 607 } else if (UNSIGNED_32.isInstance(arrayMember)) { 608 for (int i = 0; i < arrayMember.length;) 609 arrayMember[i++] = (Member) this.new Unsigned32(); 610 } else if (SIGNED_64.isInstance(arrayMember)) { 611 for (int i = 0; i < arrayMember.length;) 612 arrayMember[i++] = (Member) this.new Signed64(); 613 } else if (FLOAT_32.isInstance(arrayMember)) { 614 for (int i = 0; i < arrayMember.length;) 615 arrayMember[i++] = (Member) this.new Float32(); 616 } else if (FLOAT_64.isInstance(arrayMember)) { 617 for (int i = 0; i < arrayMember.length;) 618 arrayMember[i++] = (Member) this.new Float64(); 619 } else { 620 throw new UnsupportedOperationException ( 621 "Cannot create member elements, the arrayMember should " 622 + "contain the member instances instead of null"); 623 } 624 _resetIndex = resetIndexSaved; 625 return (Member[]) arrayMember; 626 } 627 628 private static final Class BOOL = new Bool[0].getClass(); 629 630 private static final Class SIGNED_8 = new Signed8[0].getClass(); 631 632 private static final Class UNSIGNED_8 = new Unsigned8[0].getClass(); 633 634 private static final Class SIGNED_16 = new Signed16[0].getClass(); 635 636 private static final Class UNSIGNED_16 = new Unsigned16[0].getClass(); 637 638 private static final Class SIGNED_32 = new Signed32[0].getClass(); 639 640 private static final Class UNSIGNED_32 = new Unsigned32[0].getClass(); 641 642 private static final Class SIGNED_64 = new Signed64[0].getClass(); 643 644 private static final Class FLOAT_32 = new Float32[0].getClass(); 645 646 private static final Class FLOAT_64 = new Float64[0].getClass(); 647 648 658 protected Member[][] array( 659 Member[][] arrayMember) { 660 boolean resetIndexSaved = _resetIndex; 661 if (_resetIndex) { 662 _bitIndex = 0; 663 _resetIndex = false; } 665 for (int i = 0; i < arrayMember.length; i++) { 666 array(arrayMember[i]); 667 } 668 _resetIndex = resetIndexSaved; 669 return (Member[][]) arrayMember; 670 } 671 672 682 protected Member[][][] array( 683 Member[][][] arrayMember) { 684 boolean resetIndexSaved = _resetIndex; 685 if (_resetIndex) { 686 _bitIndex = 0; 687 _resetIndex = false; } 689 for (int i = 0; i < arrayMember.length; i++) { 690 array(arrayMember[i]); 691 } 692 _resetIndex = resetIndexSaved; 693 return (Member[][][]) arrayMember; 694 } 695 696 704 protected UTF8String[] array(UTF8String[] array, int stringLength) { 705 for (int i = 0; i < array.length; i++) { 706 array[i] = new UTF8String(stringLength); 707 } 708 return array; 709 } 710 711 723 private int updateIndexes(int alignment, int nbrOfBits, int capacity) { 724 if (nbrOfBits > capacity) { 725 throw new IllegalArgumentException ("nbrOfBits: " + nbrOfBits 726 + " exceeds capacity: " + capacity); 727 } 728 729 if (_resetIndex) { 731 _bitIndex = 0; 732 } 733 734 alignment = isPacked() ? 1 : alignment; 736 int offset = (_bitIndex / (alignment << 3)) * alignment; 737 738 int usedBits = _bitIndex - (offset << 3); 740 741 if ((capacity < usedBits + nbrOfBits) 744 || ((nbrOfBits == 0) && (usedBits != 0))) { 745 offset += alignment; 747 _bitIndex = (offset << 3) + nbrOfBits; 748 } else { _bitIndex += nbrOfBits; 750 } 751 752 if (_bitsUsed < _bitIndex) { 754 _bitsUsed = _bitIndex; 755 } 756 757 if (_alignment < alignment) { 759 _alignment = alignment; 760 } 761 return offset; 762 } 763 764 768 784 protected class Member { 785 786 789 private final int _offset; 790 791 797 protected Member(int alignment, int size) { 798 final int nbrOfBits = size << 3; 799 _offset = updateIndexes(alignment, nbrOfBits, nbrOfBits); 800 } 801 802 810 Member(int alignment, int nbrOfBits, int capacity) { 811 _offset = updateIndexes(alignment, nbrOfBits, capacity); 812 } 813 814 819 public final Struct struct() { 820 return Struct.this; 821 } 822 823 828 public final int offset() { 829 return _offset; 830 } 831 832 838 public final int position() { 839 return getByteBufferPosition() + _offset; 840 } 841 } 842 843 847 851 public class UTF8String extends Member { 852 private final UTF8ByteBufferWriter _writer = new UTF8ByteBufferWriter(); 853 854 private final UTF8ByteBufferReader _reader = new UTF8ByteBufferReader(); 855 856 private final char[] _chars; 857 858 private final int _length; 859 860 public UTF8String(int length) { 861 super(1, length); 862 _length = length; _chars = new char[length]; 864 } 865 866 public void set(String string) { 867 final ByteBuffer buffer = getByteBuffer(); 868 synchronized (buffer) { 869 try { 870 buffer.position(position()); 871 _writer.setOutput(buffer); 872 if (string.length() < _length) { 873 _writer.write(string); 874 _writer.write(0); } else if (string.length() > _length) { _writer.write(string.substring(0, _length)); 877 } else { _writer.write(string); 879 } 880 } catch (IOException e) { 881 throw new JavolutionError(e); 882 } finally { 883 _writer.reset(); 884 } 885 } 886 } 887 888 public String get() { 889 final ByteBuffer buffer = getByteBuffer(); 890 synchronized (buffer) { 891 try { 892 buffer.position(position()); 893 _reader.setInput(buffer); 894 for (int i = 0; i < _length;) { 895 char c = (char) _reader.read(); 896 if (c == 0) { return new String (_chars, 0, i); 898 } else { 899 _chars[i++] = c; 900 } 901 } 902 return new String (_chars, 0, _length); 903 } catch (IOException e) { 904 throw new JavolutionError(e); 905 } finally { 906 _reader.reset(); 907 } 908 } 909 } 910 } 911 912 916 public class Bool extends Member { 917 private final int _mask; 918 919 private final int _shift; 920 921 public Bool() { 922 this(8); 923 } 924 925 public Bool(int nbrOfBits) { 926 super(1, nbrOfBits, 8); 927 final int startBit = offset() << 3; 928 _shift = (byteOrder() == ByteOrder.BIG_ENDIAN) ? 8 - _bitIndex 929 + startBit : _bitIndex - startBit - nbrOfBits; 930 _mask = ((1 << nbrOfBits) - 1) << _shift; 931 } 932 933 public boolean get() { 934 return (getByteBuffer().get(position()) & _mask) != 0; 935 } 936 937 public void set(boolean value) { 938 if (_mask == 0xFF) { getByteBuffer().put(position(), (byte) (value ? 1 : 0)); 940 } else { int prevCleared = getByteBuffer().get(position()) & (~_mask); 942 if (value) { 943 getByteBuffer().put(position(), 944 (byte) (prevCleared | (1 << _shift))); 945 } else { 946 getByteBuffer().put(position(), (byte) (prevCleared)); 947 } 948 } 949 } 950 } 951 952 955 public class Signed8 extends Member { 956 private final int _mask; 957 958 private final int _shift; 959 960 private final int _signShift; 961 962 public Signed8() { 963 this(8); 964 } 965 966 public Signed8(int nbrOfBits) { 967 super(1, nbrOfBits, 8); 968 final int startBit = offset() << 3; 969 _shift = (byteOrder() == ByteOrder.BIG_ENDIAN) ? 8 - _bitIndex 970 + startBit : _bitIndex - startBit - nbrOfBits; 971 _mask = ((1 << nbrOfBits) - 1) << _shift; 972 _signShift = 32 - _shift - nbrOfBits; 973 } 974 975 public byte get() { 976 if (_mask == 0xFF) { return getByteBuffer().get(position()); 978 } else { int value = getByteBuffer().get(position()); 980 value &= _mask; 981 value <<= _signShift; 982 value >>= _signShift + _shift; return (byte) value; 984 } 985 } 986 987 public void set(byte value) { 988 if (_mask == 0xFF) { getByteBuffer().put(position(), value); 990 } else { value <<= _shift; 992 value &= _mask; 993 int orMask = getByteBuffer().get(position()) & (~_mask); 994 getByteBuffer().put(position(), (byte) (orMask | value)); 995 } 996 } 997 } 998 999 1002 public class Unsigned8 extends Member { 1003 private final int _shift; 1004 1005 private final int _mask; 1006 1007 public Unsigned8() { 1008 this(8); 1009 } 1010 1011 public Unsigned8(int nbrOfBits) { 1012 super(1, nbrOfBits, 8); 1013 final int startBit = offset() << 3; 1014 _shift = (byteOrder() == ByteOrder.BIG_ENDIAN) ? 8 - _bitIndex 1015 + startBit : _bitIndex - startBit - nbrOfBits; 1016 _mask = ((1 << nbrOfBits) - 1) << _shift; 1017 } 1018 1019 public short get() { 1020 int value = getByteBuffer().get(position()); 1021 return (short) ((value & _mask) >>> _shift); 1022 } 1023 1024 public void set(short value) { 1025 if (_mask == 0xFF) { getByteBuffer().put(position(), (byte) value); 1027 } else { value <<= _shift; 1029 value &= _mask; 1030 int orMask = getByteBuffer().get(position()) & (~_mask); 1031 getByteBuffer().put(position(), (byte) (orMask | value)); 1032 } 1033 } 1034 } 1035 1036 1039 public class Signed16 extends Member { 1040 private final int _mask; 1041 1042 private final int _shift; 1043 1044 private final int _signShift; 1045 1046 public Signed16() { 1047 this(16); 1048 } 1049 1050 public Signed16(int nbrOfBits) { 1051 super(2, nbrOfBits, 16); 1052 final int startBit = offset() << 3; 1053 _shift = (byteOrder() == ByteOrder.BIG_ENDIAN) ? 16 - _bitIndex 1054 + startBit : _bitIndex - startBit - nbrOfBits; 1055 _mask = ((1 << nbrOfBits) - 1) << _shift; 1056 _signShift = 32 - _shift - nbrOfBits; 1057 } 1058 1059 public short get() { 1060 if (_mask == 0xFFFF) { return getByteBuffer().getShort(position()); 1062 } else { int value = getByteBuffer().getShort(position()); 1064 value &= _mask; 1065 value <<= _signShift; 1066 value >>= _signShift + _shift; return (short) value; 1068 } 1069 } 1070 1071 public void set(short value) { 1072 if (_mask == 0xFFFF) { getByteBuffer().putShort(position(), value); 1074 } else { value <<= _shift; 1076 value &= _mask; 1077 int orMask = getByteBuffer().getShort(position()) & (~_mask); 1078 getByteBuffer().putShort(position(), (short) (orMask | value)); 1079 } 1080 } 1081 } 1082 1083 1086 public class Unsigned16 extends Member { 1087 private final int _shift; 1088 1089 private final int _mask; 1090 1091 public Unsigned16() { 1092 this(16); 1093 } 1094 1095 public Unsigned16(int nbrOfBits) { 1096 super(2, nbrOfBits, 16); 1097 final int startBit = offset() << 3; 1098 _shift = (byteOrder() == ByteOrder.BIG_ENDIAN) ? 16 - _bitIndex 1099 + startBit : _bitIndex - startBit - nbrOfBits; 1100 _mask = ((1 << nbrOfBits) - 1) << _shift; 1101 } 1102 1103 public int get() { 1104 int value = getByteBuffer().getShort(position()); 1105 return (value & _mask) >>> _shift; 1106 } 1107 1108 public void set(int value) { 1109 if (_mask == 0xFFFF) { getByteBuffer().putShort(position(), (short) value); 1111 } else { value <<= _shift; 1113 value &= _mask; 1114 int orMask = getByteBuffer().getShort(position()) & (~_mask); 1115 getByteBuffer().putShort(position(), (short) (orMask | value)); 1116 } 1117 } 1118 } 1119 1120 1123 public class Signed32 extends Member { 1124 private final int _mask; 1125 1126 private final int _shift; 1127 1128 private final int _signShift; 1129 1130 public Signed32() { 1131 this(32); 1132 } 1133 1134 public Signed32(int nbrOfBits) { 1135 super(4, nbrOfBits, 32); 1136 final int startBit = offset() << 3; 1137 _shift = (byteOrder() == ByteOrder.BIG_ENDIAN) ? 32 - _bitIndex 1138 + startBit : _bitIndex - startBit - nbrOfBits; 1139 _mask = (nbrOfBits == 32) ? 0xFFFFFFFF 1140 : ((1 << nbrOfBits) - 1) << _shift; 1141 _signShift = 32 - _shift - nbrOfBits; 1142 } 1143 1144 public int get() { 1145 if (_mask == 0xFFFFFFFF) { return getByteBuffer().getInt(position()); 1147 } else { int value = getByteBuffer().getInt(position()); 1149 value &= _mask; 1150 value <<= _signShift; 1151 value >>= _signShift + _shift; return value; 1153 } 1154 } 1155 1156 public void set(int value) { 1157 if (_mask == 0xFFFFFFFF) { getByteBuffer().putInt(position(), value); 1159 } else { value <<= _shift; 1161 value &= _mask; 1162 int orMask = getByteBuffer().getInt(position()) & (~_mask); 1163 getByteBuffer().putInt(position(), orMask | value); 1164 } 1165 } 1166 } 1167 1168 1171 public class Unsigned32 extends Member { 1172 private final int _shift; 1173 1174 private final long _mask; 1175 1176 public Unsigned32() { 1177 this(32); 1178 } 1179 1180 public Unsigned32(int nbrOfBits) { 1181 super(4, nbrOfBits, 32); 1182 final int startBit = offset() << 3; 1183 _shift = (byteOrder() == ByteOrder.BIG_ENDIAN) ? 32 - _bitIndex 1184 + startBit : _bitIndex - startBit - nbrOfBits; 1185 _mask = (nbrOfBits == 32) ? 0xFFFFFFFFl 1186 : ((1l << nbrOfBits) - 1l) << _shift; 1187 } 1188 1189 public long get() { 1190 int value = getByteBuffer().getInt(position()); 1191 return (value & _mask) >>> _shift; 1192 } 1193 1194 public void set(long value) { 1195 if (_mask == 0xFFFFFFFF) { getByteBuffer().putInt(position(), (int) value); 1197 } else { value <<= _shift; 1199 value &= _mask; 1200 int orMask = getByteBuffer().getInt(position()) 1201 & (~(int) _mask); 1202 getByteBuffer().putInt(position(), (int) (orMask | value)); 1203 } 1204 } 1205 } 1206 1207 1210 public class Signed64 extends Member { 1211 private final long _mask; 1212 1213 private final int _shift; 1214 1215 private final int _signShift; 1216 1217 public Signed64() { 1218 this(64); 1219 } 1220 1221 public Signed64(int nbrOfBits) { 1222 super(8, nbrOfBits, 64); 1223 final int startBit = offset() << 3; 1224 _shift = (byteOrder() == ByteOrder.BIG_ENDIAN) ? 64 - _bitIndex 1225 + startBit : _bitIndex - startBit - nbrOfBits; 1226 _mask = (nbrOfBits == 64) ? 0xFFFFFFFFFFFFFFFFl 1227 : ((1l << nbrOfBits) - 1l) << _shift; 1228 _signShift = 64 - _shift - nbrOfBits; 1229 } 1230 1231 public long get() { 1232 if (_mask == 0xFFFFFFFFFFFFFFFFl) { return getByteBuffer().getLong(position()); 1234 } else { long value = getByteBuffer().getLong(position()); 1236 value &= _mask; 1237 value <<= _signShift; 1238 value >>= _signShift + _shift; return value; 1240 } 1241 } 1242 1243 public void set(long value) { 1244 if (_mask == 0xFFFFFFFFFFFFFFFFl) { getByteBuffer().putLong(position(), value); 1246 } else { value <<= _shift; 1248 value &= _mask; 1249 long orMask = getByteBuffer().getLong(position()) & (~_mask); 1250 getByteBuffer().putLong(position(), orMask | value); 1251 } 1252 } 1253 } 1254 1255 1258 public class Float32 extends Member { 1259 public Float32() { 1260 super(4, 4); 1261 } 1262 1271 } 1272 1273 1276 public class Float64 extends Member { 1277 public Float64() { 1278 super(8, 8); 1279 } 1280 1288 } 1289 1290 1300 public class Reference32extends Member { 1301 1302 privateStruct _struct; 1303 1304 public Reference32() { 1305 super(4, 4); 1306 } 1307 1308 public void set(Struct struct) { 1309 if (struct != null) { 1310 getByteBuffer().putInt(position(), (int) struct.address()); 1311 } else { 1312 getByteBuffer().putInt(position(), 0); 1313 } 1314 _struct = struct; 1315 } 1316 1317 publicStruct get() { 1318 return _struct; 1319 } 1320 1321 public int value() { 1322 return getByteBuffer().getInt(position()); 1323 } 1324 1325 public boolean isUpToDate() { 1326 if (_struct != null) { 1327 return getByteBuffer().getInt(position()) == (int) _struct 1328 .address(); 1329 } else { 1330 return getByteBuffer().getInt(position()) == 0; 1331 } 1332 } 1333 } 1334 1335 1345 public class Reference64extends Member { 1346 privateStruct _struct; 1347 1348 public Reference64() { 1349 super(8, 8); 1350 } 1351 1352 public void set(Struct struct) { 1353 if (struct != null) { 1354 getByteBuffer().putLong(position(), struct.address()); 1355 } else if (struct == null) { 1356 getByteBuffer().putLong(position(), 0L); 1357 } 1358 _struct = struct; 1359 } 1360 1361 publicStruct get() { 1362 return _struct; 1363 } 1364 1365 public long value() { 1366 return getByteBuffer().getLong(position()); 1367 } 1368 1369 public boolean isUpToDate() { 1370 if (_struct != null) { 1371 return getByteBuffer().getLong(position()) == _struct.address(); 1372 } else { 1373 return getByteBuffer().getLong(position()) == 0L; 1374 } 1375 } 1376 } 1377 1378 1381 public class Enum8 extends Member { 1382 private final int _mask; 1383 1384 private final int _shift; 1385 1386 private final int _signShift; 1387 1388 private final List _enumValues; 1389 1390 public Enum8(List enumValues) { 1391 this(enumValues, 8); 1392 } 1393 1394 public Enum8(List enumValues, int nbrOfBits) { 1395 super(1, nbrOfBits, 8); 1396 _enumValues = enumValues; 1397 final int startBit = offset() << 3; 1398 _shift = (byteOrder() == ByteOrder.BIG_ENDIAN) ? 8 - _bitIndex 1399 + startBit : _bitIndex - startBit - nbrOfBits; 1400 _mask = ((1 << nbrOfBits) - 1) << _shift; 1401 _signShift = 32 - _shift - nbrOfBits; 1402 } 1403 1404 public Enum get() { 1405 if (_mask == 0xFF) { return (Enum ) _enumValues.get(getByteBuffer().get(position())); 1407 } else { int value = getByteBuffer().get(position()); 1409 value &= _mask; 1410 value <<= _signShift; 1411 value >>= _signShift + _shift; return (Enum ) _enumValues.get(value); 1413 } 1414 } 1415 1416 public void set(Enum e) { 1417 int index = e.ordinal(); 1418 if (_enumValues.get(index) != e) { 1419 throw new IllegalArgumentException ( 1420 "enum: " 1421 + e 1422 + ", ordinal value does not reflect enum values position"); 1423 } 1424 byte value = (byte) index; 1425 if (_mask == 0xFF) { getByteBuffer().put(position(), value); 1427 } else { value <<= _shift; 1429 value &= _mask; 1430 int orMask = getByteBuffer().get(position()) & (~_mask); 1431 getByteBuffer().put(position(), (byte) (orMask | value)); 1432 } 1433 } 1434 } 1435 1436 1439 public class Enum16 extends Member { 1440 private final int _mask; 1441 1442 private final int _shift; 1443 1444 private final int _signShift; 1445 1446 private final List _enumValues; 1447 1448 public Enum16(List enumValues) { 1449 this(enumValues, 16); 1450 } 1451 1452 public Enum16(List enumValues, int nbrOfBits) { 1453 super(2, nbrOfBits, 16); 1454 _enumValues = enumValues; 1455 final int startBit = offset() << 3; 1456 _shift = (byteOrder() == ByteOrder.BIG_ENDIAN) ? 16 - _bitIndex 1457 + startBit : _bitIndex - startBit - nbrOfBits; 1458 _mask = ((1 << nbrOfBits) - 1) << _shift; 1459 _signShift = 32 - _shift - nbrOfBits; 1460 } 1461 1462 public Enum get() { 1463 if (_mask == 0xFFFF) { return (Enum ) _enumValues.get(getByteBuffer().getShort( 1465 position())); 1466 } else { int value = getByteBuffer().getShort(position()); 1468 value &= _mask; 1469 value <<= _signShift; 1470 value >>= _signShift + _shift; return (Enum ) _enumValues.get(value); 1472 } 1473 } 1474 1475 public void set(Enum e) { 1476 int index = e.ordinal(); 1477 if (_enumValues.get(index) != e) { 1478 throw new IllegalArgumentException ( 1479 "enum: " 1480 + e 1481 + ", ordinal value does not reflect enum values position"); 1482 } 1483 short value = (short) index; 1484 if (_mask == 0xFFFF) { getByteBuffer().putShort(position(), value); 1486 } else { value <<= _shift; 1488 value &= _mask; 1489 int orMask = getByteBuffer().getShort(position()) & (~_mask); 1490 getByteBuffer().putShort(position(), (short) (orMask | value)); 1491 } 1492 } 1493 } 1494 1495 1498 public class Enum32 extends Member { 1499 private final int _mask; 1500 1501 private final int _shift; 1502 1503 private final int _signShift; 1504 1505 private final List _enumValues; 1506 1507 public Enum32(List enumValues) { 1508 this(enumValues, 32); 1509 } 1510 1511 public Enum32(List enumValues, int nbrOfBits) { 1512 super(4, nbrOfBits, 32); 1513 _enumValues = enumValues; 1514 final int startBit = offset() << 3; 1515 _shift = (byteOrder() == ByteOrder.BIG_ENDIAN) ? 32 - _bitIndex 1516 + startBit : _bitIndex - startBit - nbrOfBits; 1517 _mask = (nbrOfBits == 32) ? 0xFFFFFFFF 1518 : ((1 << nbrOfBits) - 1) << _shift; 1519 _signShift = 32 - _shift - nbrOfBits; 1520 } 1521 1522 public Enum get() { 1523 if (_mask == 0xFFFFFFFF) { return (Enum ) _enumValues.get(getByteBuffer() 1525 .getInt(position())); 1526 } else { int value = getByteBuffer().getInt(position()); 1528 value &= _mask; 1529 value <<= _signShift; 1530 value >>= _signShift + _shift; return (Enum ) _enumValues.get(value); 1532 } 1533 } 1534 1535 public void set(Enum e) { 1536 int index = e.ordinal(); 1537 if (_enumValues.get(index) != e) { 1538 throw new IllegalArgumentException ( 1539 "enum: " 1540 + e 1541 + ", ordinal value does not reflect enum values position"); 1542 } 1543 int value = index; 1544 if (_mask == 0xFFFFFFFF) { getByteBuffer().putInt(position(), value); 1546 } else { value <<= _shift; 1548 value &= _mask; 1549 int orMask = getByteBuffer().getInt(position()) & (~_mask); 1550 getByteBuffer().putInt(position(), orMask | value); 1551 } 1552 } 1553 } 1554 1555 1558 public class Enum64 extends Member { 1559 private final long _mask; 1560 1561 private final int _shift; 1562 1563 private final int _signShift; 1564 1565 private final List _enumValues; 1566 1567 public Enum64(List enumValues) { 1568 this(enumValues, 64); 1569 } 1570 1571 public Enum64(List enumValues, int nbrOfBits) { 1572 super(8, nbrOfBits, 64); 1573 _enumValues = enumValues; 1574 final int startBit = offset() << 3; 1575 _shift = (byteOrder() == ByteOrder.BIG_ENDIAN) ? 64 - _bitIndex 1576 + startBit : _bitIndex - startBit - nbrOfBits; 1577 _mask = (nbrOfBits == 64) ? 0xFFFFFFFFFFFFFFFFl 1578 : ((1l << nbrOfBits) - 1l) << _shift; 1579 _signShift = 64 - _shift - nbrOfBits; 1580 } 1581 1582 public Enum get() { 1583 if (_mask == 0xFFFFFFFFFFFFFFFFl) { return (Enum ) _enumValues.get((int) getByteBuffer().getLong( 1585 position())); 1586 } else { long value = getByteBuffer().getLong(position()); 1588 value &= _mask; 1589 value <<= _signShift; 1590 value >>= _signShift + _shift; return (Enum ) _enumValues.get((int) value); 1592 } 1593 } 1594 1595 public void set(Enum e) { 1596 int index = e.ordinal(); 1597 if (_enumValues.get(index) != e) { 1598 throw new IllegalArgumentException ( 1599 "enum: " 1600 + e 1601 + ", ordinal value does not reflect enum values position"); 1602 } 1603 long value = index; 1604 if (_mask == 0xFFFFFFFFFFFFFFFFl) { getByteBuffer().putLong(position(), value); 1606 } else { value <<= _shift; 1608 value &= _mask; 1609 long orMask = getByteBuffer().getLong(position()) & (~_mask); 1610 getByteBuffer().putLong(position(), orMask | value); 1611 } 1612 } 1613 } 1614} | Popular Tags |