1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002-2009 Oracle. All rights reserved. 5 * 6 * $Id$ 7 */ 8 9package com.sleepycat.persist.impl; 10 11import java.lang.reflect.Field; 12import java.math.BigInteger; 13import java.util.Date; 14import java.util.Map; 15import java.util.Set; 16 17import com.sleepycat.db.DatabaseEntry; 18import com.sleepycat.persist.model.EntityModel; 19 20/** 21 * Format for simple types, including primitives. Additional methods are 22 * included to optimize the handling of primitives. Other classes such as 23 * PrimitiveArrayFormat and ReflectAccessor take advantage of these methods. 24 * 25 * @author Mark Hayes 26 */ 27public abstract class SimpleFormat extends Format { 28 29 private static final long serialVersionUID = 4595245575868697702L; 30 31 private final boolean primitive; 32 private SimpleFormat wrapperFormat; 33 34 SimpleFormat(Class type, boolean primitive) { 35 super(type); 36 this.primitive = primitive; 37 } 38 39 void setWrapperFormat(SimpleFormat wrapperFormat) { 40 this.wrapperFormat = wrapperFormat; 41 } 42 43 @Override 44 Format getWrapperFormat() { 45 return wrapperFormat; 46 } 47 48 @Override 49 public boolean isSimple() { 50 return true; 51 } 52 53 @Override 54 public boolean isPrimitive() { 55 return primitive; 56 } 57 58 @Override 59 void collectRelatedFormats(Catalog catalog, 60 Map<String,Format> newFormats) { 61 } 62 63 @Override 64 void initialize(Catalog catalog, EntityModel model, int initVersion) { 65 } 66 67 @Override 68 public Object readObject(Object o, EntityInput input, boolean rawAccess) { 69 /* newInstance reads the value -- do nothing here. */ 70 return o; 71 } 72 73 @Override 74 boolean evolve(Format newFormat, Evolver evolver) { 75 evolver.useOldFormat(this, newFormat); 76 return true; 77 } 78 79 /* -- Begin methods to be overridden by primitive formats only. -- */ 80 81 Object newPrimitiveArray(int len, EntityInput input) { 82 throw new UnsupportedOperationException(); 83 } 84 85 void writePrimitiveArray(Object o, EntityOutput output) { 86 throw new UnsupportedOperationException(); 87 } 88 89 int getPrimitiveLength() { 90 throw new UnsupportedOperationException(); 91 } 92 93 /** 94 * @throws IllegalAccessException from subclasses. 95 */ 96 void readPrimitiveField(Object o, EntityInput input, Field field) 97 throws IllegalAccessException { 98 99 throw new UnsupportedOperationException(); 100 } 101 102 /** 103 * @throws IllegalAccessException from subclasses. 104 */ 105 void writePrimitiveField(Object o, EntityOutput output, Field field) 106 throws IllegalAccessException { 107 108 throw new UnsupportedOperationException(); 109 } 110 111 /* -- End methods to be overridden by primitive formats only. -- */ 112 113 void skipPrimitiveArray(int len, RecordInput input) { 114 input.skipFast(len * getPrimitiveLength()); 115 } 116 117 void copySecMultiKeyPrimitiveArray(int len, 118 RecordInput input, 119 Set results) { 120 int primLen = getPrimitiveLength(); 121 for (int i = 0; i < len; i += 1) { 122 DatabaseEntry entry = new DatabaseEntry 123 (input.getBufferBytes(), input.getBufferOffset(), primLen); 124 results.add(entry); 125 input.skipFast(primLen); 126 } 127 } 128 129 public static class FBool extends SimpleFormat { 130 131 private static final long serialVersionUID = -7724949525068533451L; 132 133 FBool(boolean primitive) { 134 super(primitive ? Boolean.TYPE : Boolean.class, primitive); 135 } 136 137 @Override 138 Object newArray(int len) { 139 return new Boolean[len]; 140 } 141 142 @Override 143 public Object newInstance(EntityInput input, boolean rawAccess) { 144 return Boolean.valueOf(input.readBoolean()); 145 } 146 147 @Override 148 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 149 output.writeBoolean(((Boolean) o).booleanValue()); 150 } 151 152 @Override 153 void skipContents(RecordInput input) { 154 input.skipFast(1); 155 } 156 157 @Override 158 void copySecKey(RecordInput input, RecordOutput output) { 159 output.writeFast(input.readFast()); 160 } 161 162 @Override 163 Object newPrimitiveArray(int len, EntityInput input) { 164 boolean[] a = new boolean[len]; 165 for (int i = 0; i < len; i += 1) { 166 a[i] = input.readBoolean(); 167 } 168 return a; 169 } 170 171 @Override 172 void writePrimitiveArray(Object o, EntityOutput output) { 173 boolean[] a = (boolean[]) o; 174 int len = a.length; 175 output.writeArrayLength(len); 176 for (int i = 0; i < len; i += 1) { 177 output.writeBoolean(a[i]); 178 } 179 } 180 181 @Override 182 int getPrimitiveLength() { 183 return 1; 184 } 185 186 @Override 187 void readPrimitiveField(Object o, EntityInput input, Field field) 188 throws IllegalAccessException { 189 190 field.setBoolean(o, input.readBoolean()); 191 } 192 193 @Override 194 void writePrimitiveField(Object o, EntityOutput output, Field field) 195 throws IllegalAccessException { 196 197 output.writeBoolean(field.getBoolean(o)); 198 } 199 } 200 201 public static class FByte extends SimpleFormat { 202 203 private static final long serialVersionUID = 3651752958101447257L; 204 205 FByte(boolean primitive) { 206 super(primitive ? Byte.TYPE : Byte.class, primitive); 207 } 208 209 @Override 210 Object newArray(int len) { 211 return new Byte[len]; 212 } 213 214 @Override 215 public Object newInstance(EntityInput input, boolean rawAccess) { 216 return Byte.valueOf(input.readByte()); 217 } 218 219 @Override 220 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 221 output.writeByte(((Number) o).byteValue()); 222 } 223 224 @Override 225 void skipContents(RecordInput input) { 226 input.skipFast(1); 227 } 228 229 @Override 230 void copySecKey(RecordInput input, RecordOutput output) { 231 output.writeFast(input.readFast()); 232 } 233 234 @Override 235 Object newPrimitiveArray(int len, EntityInput input) { 236 byte[] a = new byte[len]; 237 for (int i = 0; i < len; i += 1) { 238 a[i] = input.readByte(); 239 } 240 return a; 241 } 242 243 @Override 244 void writePrimitiveArray(Object o, EntityOutput output) { 245 byte[] a = (byte[]) o; 246 int len = a.length; 247 output.writeArrayLength(len); 248 for (int i = 0; i < len; i += 1) { 249 output.writeByte(a[i]); 250 } 251 } 252 253 @Override 254 int getPrimitiveLength() { 255 return 1; 256 } 257 258 @Override 259 void readPrimitiveField(Object o, EntityInput input, Field field) 260 throws IllegalAccessException { 261 262 field.setByte(o, input.readByte()); 263 } 264 265 @Override 266 void writePrimitiveField(Object o, EntityOutput output, Field field) 267 throws IllegalAccessException { 268 269 output.writeByte(field.getByte(o)); 270 } 271 272 @Override 273 Format getSequenceKeyFormat() { 274 return this; 275 } 276 } 277 278 public static class FShort extends SimpleFormat { 279 280 private static final long serialVersionUID = -4909138198491785624L; 281 282 FShort(boolean primitive) { 283 super(primitive ? Short.TYPE : Short.class, primitive); 284 } 285 286 @Override 287 Object newArray(int len) { 288 return new Short[len]; 289 } 290 291 @Override 292 public Object newInstance(EntityInput input, boolean rawAccess) { 293 return Short.valueOf(input.readShort()); 294 } 295 296 @Override 297 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 298 output.writeShort(((Number) o).shortValue()); 299 } 300 301 @Override 302 void skipContents(RecordInput input) { 303 input.skipFast(2); 304 } 305 306 @Override 307 void copySecKey(RecordInput input, RecordOutput output) { 308 output.writeFast(input.readFast()); 309 output.writeFast(input.readFast()); 310 } 311 312 @Override 313 Object newPrimitiveArray(int len, EntityInput input) { 314 short[] a = new short[len]; 315 for (int i = 0; i < len; i += 1) { 316 a[i] = input.readShort(); 317 } 318 return a; 319 } 320 321 @Override 322 void writePrimitiveArray(Object o, EntityOutput output) { 323 short[] a = (short[]) o; 324 int len = a.length; 325 output.writeArrayLength(len); 326 for (int i = 0; i < len; i += 1) { 327 output.writeShort(a[i]); 328 } 329 } 330 331 @Override 332 int getPrimitiveLength() { 333 return 2; 334 } 335 336 @Override 337 void readPrimitiveField(Object o, EntityInput input, Field field) 338 throws IllegalAccessException { 339 340 field.setShort(o, input.readShort()); 341 } 342 343 @Override 344 void writePrimitiveField(Object o, EntityOutput output, Field field) 345 throws IllegalAccessException { 346 347 output.writeShort(field.getShort(o)); 348 } 349 350 @Override 351 Format getSequenceKeyFormat() { 352 return this; 353 } 354 } 355 356 public static class FInt extends SimpleFormat { 357 358 private static final long serialVersionUID = 2695910006049980013L; 359 360 FInt(boolean primitive) { 361 super(primitive ? Integer.TYPE : Integer.class, primitive); 362 } 363 364 @Override 365 Object newArray(int len) { 366 return new Integer[len]; 367 } 368 369 @Override 370 public Object newInstance(EntityInput input, boolean rawAccess) { 371 return Integer.valueOf(input.readInt()); 372 } 373 374 @Override 375 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 376 output.writeInt(((Number) o).intValue()); 377 } 378 379 @Override 380 void skipContents(RecordInput input) { 381 input.skipFast(4); 382 } 383 384 @Override 385 void copySecKey(RecordInput input, RecordOutput output) { 386 output.writeFast(input.readFast()); 387 output.writeFast(input.readFast()); 388 output.writeFast(input.readFast()); 389 output.writeFast(input.readFast()); 390 } 391 392 @Override 393 Object newPrimitiveArray(int len, EntityInput input) { 394 int[] a = new int[len]; 395 for (int i = 0; i < len; i += 1) { 396 a[i] = input.readInt(); 397 } 398 return a; 399 } 400 401 @Override 402 void writePrimitiveArray(Object o, EntityOutput output) { 403 int[] a = (int[]) o; 404 int len = a.length; 405 output.writeArrayLength(len); 406 for (int i = 0; i < len; i += 1) { 407 output.writeInt(a[i]); 408 } 409 } 410 411 @Override 412 int getPrimitiveLength() { 413 return 4; 414 } 415 416 @Override 417 void readPrimitiveField(Object o, EntityInput input, Field field) 418 throws IllegalAccessException { 419 420 field.setInt(o, input.readInt()); 421 } 422 423 @Override 424 void writePrimitiveField(Object o, EntityOutput output, Field field) 425 throws IllegalAccessException { 426 427 output.writeInt(field.getInt(o)); 428 } 429 430 @Override 431 Format getSequenceKeyFormat() { 432 return this; 433 } 434 } 435 436 public static class FLong extends SimpleFormat { 437 438 private static final long serialVersionUID = 1872661106534776520L; 439 440 FLong(boolean primitive) { 441 super(primitive ? Long.TYPE : Long.class, primitive); 442 } 443 444 @Override 445 Object newArray(int len) { 446 return new Long[len]; 447 } 448 449 @Override 450 public Object newInstance(EntityInput input, boolean rawAccess) { 451 return Long.valueOf(input.readLong()); 452 } 453 454 @Override 455 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 456 output.writeLong(((Number) o).longValue()); 457 } 458 459 @Override 460 void skipContents(RecordInput input) { 461 input.skipFast(8); 462 } 463 464 @Override 465 void copySecKey(RecordInput input, RecordOutput output) { 466 output.writeFast 467 (input.getBufferBytes(), input.getBufferOffset(), 8); 468 input.skipFast(8); 469 } 470 471 @Override 472 Object newPrimitiveArray(int len, EntityInput input) { 473 long[] a = new long[len]; 474 for (int i = 0; i < len; i += 1) { 475 a[i] = input.readLong(); 476 } 477 return a; 478 } 479 480 @Override 481 void writePrimitiveArray(Object o, EntityOutput output) { 482 long[] a = (long[]) o; 483 int len = a.length; 484 output.writeArrayLength(len); 485 for (int i = 0; i < len; i += 1) { 486 output.writeLong(a[i]); 487 } 488 } 489 490 @Override 491 int getPrimitiveLength() { 492 return 8; 493 } 494 495 @Override 496 void readPrimitiveField(Object o, EntityInput input, Field field) 497 throws IllegalAccessException { 498 499 field.setLong(o, input.readLong()); 500 } 501 502 @Override 503 void writePrimitiveField(Object o, EntityOutput output, Field field) 504 throws IllegalAccessException { 505 506 output.writeLong(field.getLong(o)); 507 } 508 509 @Override 510 Format getSequenceKeyFormat() { 511 return this; 512 } 513 } 514 515 public static class FFloat extends SimpleFormat { 516 517 private static final long serialVersionUID = 1033413049495053602L; 518 519 FFloat(boolean primitive) { 520 super(primitive ? Float.TYPE : Float.class, primitive); 521 } 522 523 @Override 524 Object newArray(int len) { 525 return new Float[len]; 526 } 527 528 @Override 529 public Object newInstance(EntityInput input, boolean rawAccess) { 530 return Float.valueOf(input.readSortedFloat()); 531 } 532 533 @Override 534 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 535 output.writeSortedFloat(((Number) o).floatValue()); 536 } 537 538 @Override 539 void skipContents(RecordInput input) { 540 input.skipFast(4); 541 } 542 543 @Override 544 void copySecKey(RecordInput input, RecordOutput output) { 545 output.writeFast(input.readFast()); 546 output.writeFast(input.readFast()); 547 output.writeFast(input.readFast()); 548 output.writeFast(input.readFast()); 549 } 550 551 @Override 552 Object newPrimitiveArray(int len, EntityInput input) { 553 float[] a = new float[len]; 554 for (int i = 0; i < len; i += 1) { 555 a[i] = input.readSortedFloat(); 556 } 557 return a; 558 } 559 560 @Override 561 void writePrimitiveArray(Object o, EntityOutput output) { 562 float[] a = (float[]) o; 563 int len = a.length; 564 output.writeArrayLength(len); 565 for (int i = 0; i < len; i += 1) { 566 output.writeSortedFloat(a[i]); 567 } 568 } 569 570 @Override 571 int getPrimitiveLength() { 572 return 4; 573 } 574 575 @Override 576 void readPrimitiveField(Object o, EntityInput input, Field field) 577 throws IllegalAccessException { 578 579 field.setFloat(o, input.readSortedFloat()); 580 } 581 582 @Override 583 void writePrimitiveField(Object o, EntityOutput output, Field field) 584 throws IllegalAccessException { 585 586 output.writeSortedFloat(field.getFloat(o)); 587 } 588 } 589 590 public static class FDouble extends SimpleFormat { 591 592 private static final long serialVersionUID = 646904456811041423L; 593 594 FDouble(boolean primitive) { 595 super(primitive ? Double.TYPE : Double.class, primitive); 596 } 597 598 @Override 599 Object newArray(int len) { 600 return new Double[len]; 601 } 602 603 @Override 604 public Object newInstance(EntityInput input, boolean rawAccess) { 605 return Double.valueOf(input.readSortedDouble()); 606 } 607 608 @Override 609 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 610 output.writeSortedDouble(((Number) o).doubleValue()); 611 } 612 613 @Override 614 void skipContents(RecordInput input) { 615 input.skipFast(8); 616 } 617 618 @Override 619 void copySecKey(RecordInput input, RecordOutput output) { 620 output.writeFast 621 (input.getBufferBytes(), input.getBufferOffset(), 8); 622 input.skipFast(8); 623 } 624 625 @Override 626 Object newPrimitiveArray(int len, EntityInput input) { 627 double[] a = new double[len]; 628 for (int i = 0; i < len; i += 1) { 629 a[i] = input.readSortedDouble(); 630 } 631 return a; 632 } 633 634 @Override 635 void writePrimitiveArray(Object o, EntityOutput output) { 636 double[] a = (double[]) o; 637 int len = a.length; 638 output.writeArrayLength(len); 639 for (int i = 0; i < len; i += 1) { 640 output.writeSortedDouble(a[i]); 641 } 642 } 643 644 @Override 645 int getPrimitiveLength() { 646 return 8; 647 } 648 649 @Override 650 void readPrimitiveField(Object o, EntityInput input, Field field) 651 throws IllegalAccessException { 652 653 field.setDouble(o, input.readSortedDouble()); 654 } 655 656 @Override 657 void writePrimitiveField(Object o, EntityOutput output, Field field) 658 throws IllegalAccessException { 659 660 output.writeSortedDouble(field.getDouble(o)); 661 } 662 } 663 664 public static class FChar extends SimpleFormat { 665 666 private static final long serialVersionUID = -7609118195770005374L; 667 668 FChar(boolean primitive) { 669 super(primitive ? Character.TYPE : Character.class, primitive); 670 } 671 672 @Override 673 Object newArray(int len) { 674 return new Character[len]; 675 } 676 677 @Override 678 public Object newInstance(EntityInput input, boolean rawAccess) { 679 return Character.valueOf(input.readChar()); 680 } 681 682 @Override 683 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 684 output.writeChar(((Character) o).charValue()); 685 } 686 687 @Override 688 void skipContents(RecordInput input) { 689 input.skipFast(2); 690 } 691 692 @Override 693 void copySecKey(RecordInput input, RecordOutput output) { 694 output.writeFast(input.readFast()); 695 output.writeFast(input.readFast()); 696 } 697 698 @Override 699 Object newPrimitiveArray(int len, EntityInput input) { 700 char[] a = new char[len]; 701 for (int i = 0; i < len; i += 1) { 702 a[i] = input.readChar(); 703 } 704 return a; 705 } 706 707 @Override 708 void writePrimitiveArray(Object o, EntityOutput output) { 709 char[] a = (char[]) o; 710 int len = a.length; 711 output.writeArrayLength(len); 712 for (int i = 0; i < len; i += 1) { 713 output.writeChar(a[i]); 714 } 715 } 716 717 @Override 718 int getPrimitiveLength() { 719 return 2; 720 } 721 722 @Override 723 void readPrimitiveField(Object o, EntityInput input, Field field) 724 throws IllegalAccessException { 725 726 field.setChar(o, input.readChar()); 727 } 728 729 @Override 730 void writePrimitiveField(Object o, EntityOutput output, Field field) 731 throws IllegalAccessException { 732 733 output.writeChar(field.getChar(o)); 734 } 735 } 736 737 public static class FString extends SimpleFormat { 738 739 private static final long serialVersionUID = 5710392786480064612L; 740 741 FString() { 742 super(String.class, false); 743 } 744 745 @Override 746 Object newArray(int len) { 747 return new String[len]; 748 } 749 750 @Override 751 public Object newInstance(EntityInput input, boolean rawAccess) { 752 return input.readString(); 753 } 754 755 @Override 756 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 757 output.writeString((String) o); 758 } 759 760 @Override 761 void skipContents(RecordInput input) { 762 input.skipFast(input.getStringByteLength()); 763 } 764 765 @Override 766 void copySecKey(RecordInput input, RecordOutput output) { 767 int len = input.getStringByteLength(); 768 output.writeFast 769 (input.getBufferBytes(), input.getBufferOffset(), len); 770 input.skipFast(len); 771 } 772 } 773 774 public static class FBigInt extends SimpleFormat { 775 776 private static final long serialVersionUID = -5027098112507644563L; 777 778 FBigInt() { 779 super(BigInteger.class, false); 780 } 781 782 @Override 783 Object newArray(int len) { 784 return new BigInteger[len]; 785 } 786 787 @Override 788 public Object newInstance(EntityInput input, boolean rawAccess) { 789 return input.readBigInteger(); 790 } 791 792 @Override 793 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 794 output.writeBigInteger((BigInteger) o); 795 } 796 797 @Override 798 void skipContents(RecordInput input) { 799 input.skipFast(input.getBigIntegerByteLength()); 800 } 801 802 @Override 803 void copySecKey(RecordInput input, RecordOutput output) { 804 int len = input.getBigIntegerByteLength(); 805 output.writeFast 806 (input.getBufferBytes(), input.getBufferOffset(), len); 807 input.skipFast(len); 808 } 809 } 810 811 public static class FDate extends SimpleFormat { 812 813 private static final long serialVersionUID = -5665773229869034145L; 814 815 FDate() { 816 super(Date.class, false); 817 } 818 819 @Override 820 Object newArray(int len) { 821 return new Date[len]; 822 } 823 824 @Override 825 public Object newInstance(EntityInput input, boolean rawAccess) { 826 return new Date(input.readLong()); 827 } 828 829 @Override 830 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 831 output.writeLong(((Date) o).getTime()); 832 } 833 834 @Override 835 void skipContents(RecordInput input) { 836 input.skipFast(8); 837 } 838 839 @Override 840 void copySecKey(RecordInput input, RecordOutput output) { 841 output.writeFast 842 (input.getBufferBytes(), input.getBufferOffset(), 8); 843 input.skipFast(8); 844 } 845 } 846} 847