4587 * least significant). If the magnitude is zero, return value is undefined.
4588 *
4589 * <p>Note: never used for a BigInteger with a magnitude of zero.
4590 * @see #getInt.
4591 */
4592 private int firstNonzeroIntNum() {
4593 int fn = firstNonzeroIntNumPlusTwo - 2;
4594 if (fn == -2) { // firstNonzeroIntNum not initialized yet
4595 // Search for the first nonzero int
4596 int i;
4597 int mlen = mag.length;
4598 for (i = mlen - 1; i >= 0 && mag[i] == 0; i--)
4599 ;
4600 fn = mlen - i - 1;
4601 firstNonzeroIntNumPlusTwo = fn + 2; // offset by two to initialize
4602 }
4603 return fn;
4604 }
4605
4606 /** use serialVersionUID from JDK 1.1. for interoperability */
4607 private static final long serialVersionUID = -8287574255936472291L;
4608
4609 /**
4610 * Serializable fields for BigInteger.
4611 *
4612 * @serialField signum int
4613 * signum of this BigInteger
4614 * @serialField magnitude byte[]
4615 * magnitude array of this BigInteger
4616 * @serialField bitCount int
4617 * appears in the serialized form for backward compatibility
4618 * @serialField bitLength int
4619 * appears in the serialized form for backward compatibility
4620 * @serialField firstNonzeroByteNum int
4621 * appears in the serialized form for backward compatibility
4622 * @serialField lowestSetBit int
4623 * appears in the serialized form for backward compatibility
4624 */
4625 private static final ObjectStreamField[] serialPersistentFields = {
4626 new ObjectStreamField("signum", Integer.TYPE),
4627 new ObjectStreamField("magnitude", byte[].class),
4628 new ObjectStreamField("bitCount", Integer.TYPE),
4629 new ObjectStreamField("bitLength", Integer.TYPE),
4630 new ObjectStreamField("firstNonzeroByteNum", Integer.TYPE),
4631 new ObjectStreamField("lowestSetBit", Integer.TYPE)
4632 };
4633
4634 /**
4635 * Reconstitute the {@code BigInteger} instance from a stream (that is,
4636 * deserialize it). The magnitude is read in as an array of bytes
4637 * for historical reasons, but it is converted to an array of ints
4638 * and the byte array is discarded.
4639 * Note:
4640 * The current convention is to initialize the cache fields, bitCountPlusOne,
4641 * bitLengthPlusOne and lowestSetBitPlusTwo, to 0 rather than some other
4642 * marker value. Therefore, no explicit action to set these fields needs to
4643 * be taken in readObject because those fields already have a 0 value by
4644 * default since defaultReadObject is not being used.
4645 */
4646 private void readObject(java.io.ObjectInputStream s)
4647 throws java.io.IOException, ClassNotFoundException {
4648 // prepare to read the alternate persistent fields
4649 ObjectInputStream.GetField fields = s.readFields();
4650
4651 // Read the alternate persistent fields that we care about
4652 int sign = fields.get("signum", -2);
4653 byte[] magnitude = (byte[])fields.get("magnitude", null);
4654
4655 // Validate signum
4656 if (sign < -1 || sign > 1) {
4657 String message = "BigInteger: Invalid signum value";
4658 if (fields.defaulted("signum"))
4659 message = "BigInteger: Signum not present in stream";
4660 throw new java.io.StreamCorruptedException(message);
4661 }
4662 int[] mag = stripLeadingZeroBytes(magnitude, 0, magnitude.length);
4663 if ((mag.length == 0) != (sign == 0)) {
4664 String message = "BigInteger: signum-magnitude mismatch";
4665 if (fields.defaulted("magnitude"))
4692
4693 static void putSign(BigInteger bi, int sign) {
4694 unsafe.putInt(bi, signumOffset, sign);
4695 }
4696
4697 static void putMag(BigInteger bi, int[] magnitude) {
4698 unsafe.putReference(bi, magOffset, magnitude);
4699 }
4700 }
4701
4702 /**
4703 * Save the {@code BigInteger} instance to a stream. The magnitude of a
4704 * {@code BigInteger} is serialized as a byte array for historical reasons.
4705 * To maintain compatibility with older implementations, the integers
4706 * -1, -1, -2, and -2 are written as the values of the obsolete fields
4707 * {@code bitCount}, {@code bitLength}, {@code lowestSetBit}, and
4708 * {@code firstNonzeroByteNum}, respectively. These values are compatible
4709 * with older implementations, but will be ignored by current
4710 * implementations.
4711 */
4712 private void writeObject(ObjectOutputStream s) throws IOException {
4713 // set the values of the Serializable fields
4714 ObjectOutputStream.PutField fields = s.putFields();
4715 fields.put("signum", signum);
4716 fields.put("magnitude", magSerializedForm());
4717 // The values written for cached fields are compatible with older
4718 // versions, but are ignored in readObject so don't otherwise matter.
4719 fields.put("bitCount", -1);
4720 fields.put("bitLength", -1);
4721 fields.put("lowestSetBit", -2);
4722 fields.put("firstNonzeroByteNum", -2);
4723
4724 // save them
4725 s.writeFields();
4726 }
4727
4728 /**
4729 * Returns the mag array as an array of bytes.
4730 */
4731 private byte[] magSerializedForm() {
|
4587 * least significant). If the magnitude is zero, return value is undefined.
4588 *
4589 * <p>Note: never used for a BigInteger with a magnitude of zero.
4590 * @see #getInt.
4591 */
4592 private int firstNonzeroIntNum() {
4593 int fn = firstNonzeroIntNumPlusTwo - 2;
4594 if (fn == -2) { // firstNonzeroIntNum not initialized yet
4595 // Search for the first nonzero int
4596 int i;
4597 int mlen = mag.length;
4598 for (i = mlen - 1; i >= 0 && mag[i] == 0; i--)
4599 ;
4600 fn = mlen - i - 1;
4601 firstNonzeroIntNumPlusTwo = fn + 2; // offset by two to initialize
4602 }
4603 return fn;
4604 }
4605
4606 /** use serialVersionUID from JDK 1.1. for interoperability */
4607 @java.io.Serial
4608 private static final long serialVersionUID = -8287574255936472291L;
4609
4610 /**
4611 * Serializable fields for BigInteger.
4612 *
4613 * @serialField signum int
4614 * signum of this BigInteger
4615 * @serialField magnitude byte[]
4616 * magnitude array of this BigInteger
4617 * @serialField bitCount int
4618 * appears in the serialized form for backward compatibility
4619 * @serialField bitLength int
4620 * appears in the serialized form for backward compatibility
4621 * @serialField firstNonzeroByteNum int
4622 * appears in the serialized form for backward compatibility
4623 * @serialField lowestSetBit int
4624 * appears in the serialized form for backward compatibility
4625 */
4626 @java.io.Serial
4627 private static final ObjectStreamField[] serialPersistentFields = {
4628 new ObjectStreamField("signum", Integer.TYPE),
4629 new ObjectStreamField("magnitude", byte[].class),
4630 new ObjectStreamField("bitCount", Integer.TYPE),
4631 new ObjectStreamField("bitLength", Integer.TYPE),
4632 new ObjectStreamField("firstNonzeroByteNum", Integer.TYPE),
4633 new ObjectStreamField("lowestSetBit", Integer.TYPE)
4634 };
4635
4636 /**
4637 * Reconstitute the {@code BigInteger} instance from a stream (that is,
4638 * deserialize it). The magnitude is read in as an array of bytes
4639 * for historical reasons, but it is converted to an array of ints
4640 * and the byte array is discarded.
4641 * Note:
4642 * The current convention is to initialize the cache fields, bitCountPlusOne,
4643 * bitLengthPlusOne and lowestSetBitPlusTwo, to 0 rather than some other
4644 * marker value. Therefore, no explicit action to set these fields needs to
4645 * be taken in readObject because those fields already have a 0 value by
4646 * default since defaultReadObject is not being used.
4647 */
4648 @java.io.Serial
4649 private void readObject(java.io.ObjectInputStream s)
4650 throws java.io.IOException, ClassNotFoundException {
4651 // prepare to read the alternate persistent fields
4652 ObjectInputStream.GetField fields = s.readFields();
4653
4654 // Read the alternate persistent fields that we care about
4655 int sign = fields.get("signum", -2);
4656 byte[] magnitude = (byte[])fields.get("magnitude", null);
4657
4658 // Validate signum
4659 if (sign < -1 || sign > 1) {
4660 String message = "BigInteger: Invalid signum value";
4661 if (fields.defaulted("signum"))
4662 message = "BigInteger: Signum not present in stream";
4663 throw new java.io.StreamCorruptedException(message);
4664 }
4665 int[] mag = stripLeadingZeroBytes(magnitude, 0, magnitude.length);
4666 if ((mag.length == 0) != (sign == 0)) {
4667 String message = "BigInteger: signum-magnitude mismatch";
4668 if (fields.defaulted("magnitude"))
4695
4696 static void putSign(BigInteger bi, int sign) {
4697 unsafe.putInt(bi, signumOffset, sign);
4698 }
4699
4700 static void putMag(BigInteger bi, int[] magnitude) {
4701 unsafe.putReference(bi, magOffset, magnitude);
4702 }
4703 }
4704
4705 /**
4706 * Save the {@code BigInteger} instance to a stream. The magnitude of a
4707 * {@code BigInteger} is serialized as a byte array for historical reasons.
4708 * To maintain compatibility with older implementations, the integers
4709 * -1, -1, -2, and -2 are written as the values of the obsolete fields
4710 * {@code bitCount}, {@code bitLength}, {@code lowestSetBit}, and
4711 * {@code firstNonzeroByteNum}, respectively. These values are compatible
4712 * with older implementations, but will be ignored by current
4713 * implementations.
4714 */
4715 @java.io.Serial
4716 private void writeObject(ObjectOutputStream s) throws IOException {
4717 // set the values of the Serializable fields
4718 ObjectOutputStream.PutField fields = s.putFields();
4719 fields.put("signum", signum);
4720 fields.put("magnitude", magSerializedForm());
4721 // The values written for cached fields are compatible with older
4722 // versions, but are ignored in readObject so don't otherwise matter.
4723 fields.put("bitCount", -1);
4724 fields.put("bitLength", -1);
4725 fields.put("lowestSetBit", -2);
4726 fields.put("firstNonzeroByteNum", -2);
4727
4728 // save them
4729 s.writeFields();
4730 }
4731
4732 /**
4733 * Returns the mag array as an array of bytes.
4734 */
4735 private byte[] magSerializedForm() {
|