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