src/share/classes/java/math/BigInteger.java

Print this page




3286 
3287         // Read the alternate persistent fields that we care about
3288         int sign = fields.get("signum", -2);
3289         byte[] magnitude = (byte[])fields.get("magnitude", null);
3290 
3291         // Validate signum
3292         if (sign < -1 || sign > 1) {
3293             String message = "BigInteger: Invalid signum value";
3294             if (fields.defaulted("signum"))
3295                 message = "BigInteger: Signum not present in stream";
3296             throw new java.io.StreamCorruptedException(message);
3297         }
3298         if ((magnitude.length == 0) != (sign == 0)) {
3299             String message = "BigInteger: signum-magnitude mismatch";
3300             if (fields.defaulted("magnitude"))
3301                 message = "BigInteger: Magnitude not present in stream";
3302             throw new java.io.StreamCorruptedException(message);
3303         }
3304 
3305         // Commit final fields via Unsafe
3306         unsafe.putIntVolatile(this, signumOffset, sign);
3307 
3308         // Calculate mag field from magnitude and discard magnitude
3309         unsafe.putObjectVolatile(this, magOffset,
3310                                  stripLeadingZeroBytes(magnitude));
3311     }
3312 
3313     // Support for resetting final fields while deserializing
3314     private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();

3315     private static final long signumOffset;
3316     private static final long magOffset;
3317     static {
3318         try {

3319             signumOffset = unsafe.objectFieldOffset
3320                 (BigInteger.class.getDeclaredField("signum"));
3321             magOffset = unsafe.objectFieldOffset
3322                 (BigInteger.class.getDeclaredField("mag"));
3323         } catch (Exception ex) {
3324             throw new Error(ex);









3325         }
3326     }
3327 
3328     /**
3329      * Save the {@code BigInteger} instance to a stream.
3330      * The magnitude of a BigInteger is serialized as a byte array for
3331      * historical reasons.
3332      *
3333      * @serialData two necessary fields are written as well as obsolete
3334      *             fields for compatibility with older versions.
3335      */
3336     private void writeObject(ObjectOutputStream s) throws IOException {
3337         // set the values of the Serializable fields
3338         ObjectOutputStream.PutField fields = s.putFields();
3339         fields.put("signum", signum);
3340         fields.put("magnitude", magSerializedForm());
3341         // The values written for cached fields are compatible with older
3342         // versions, but are ignored in readObject so don't otherwise matter.
3343         fields.put("bitCount", -1);
3344         fields.put("bitLength", -1);




3286 
3287         // Read the alternate persistent fields that we care about
3288         int sign = fields.get("signum", -2);
3289         byte[] magnitude = (byte[])fields.get("magnitude", null);
3290 
3291         // Validate signum
3292         if (sign < -1 || sign > 1) {
3293             String message = "BigInteger: Invalid signum value";
3294             if (fields.defaulted("signum"))
3295                 message = "BigInteger: Signum not present in stream";
3296             throw new java.io.StreamCorruptedException(message);
3297         }
3298         if ((magnitude.length == 0) != (sign == 0)) {
3299             String message = "BigInteger: signum-magnitude mismatch";
3300             if (fields.defaulted("magnitude"))
3301                 message = "BigInteger: Magnitude not present in stream";
3302             throw new java.io.StreamCorruptedException(message);
3303         }
3304 
3305         // Commit final fields via Unsafe
3306         UnsafeHolder.putSign(this, sign);
3307 
3308         // Calculate mag field from magnitude and discard magnitude
3309         UnsafeHolder.putMag(this, stripLeadingZeroBytes(magnitude));

3310     }
3311 
3312     // Support for resetting final fields while deserializing
3313     private static class UnsafeHolder {
3314         private static final sun.misc.Unsafe unsafe;
3315         private static final long signumOffset;
3316         private static final long magOffset;
3317         static {
3318             try {
3319                 unsafe = sun.misc.Unsafe.getUnsafe();
3320                 signumOffset = unsafe.objectFieldOffset
3321                     (BigInteger.class.getDeclaredField("signum"));
3322                 magOffset = unsafe.objectFieldOffset
3323                     (BigInteger.class.getDeclaredField("mag"));
3324             } catch (Exception ex) {
3325                 throw new ExceptionInInitializerError(ex);
3326             }
3327         }
3328 
3329         static void putSign(BigInteger bi, int sign) {
3330             unsafe.putIntVolatile(bi, signumOffset, sign);
3331         }
3332 
3333         static void putMag(BigInteger bi, int[] magnitude) {
3334             unsafe.putObjectVolatile(bi, magOffset, magnitude);
3335         }
3336     }
3337 
3338     /**
3339      * Save the {@code BigInteger} instance to a stream.
3340      * The magnitude of a BigInteger is serialized as a byte array for
3341      * historical reasons.
3342      *
3343      * @serialData two necessary fields are written as well as obsolete
3344      *             fields for compatibility with older versions.
3345      */
3346     private void writeObject(ObjectOutputStream s) throws IOException {
3347         // set the values of the Serializable fields
3348         ObjectOutputStream.PutField fields = s.putFields();
3349         fields.put("signum", signum);
3350         fields.put("magnitude", magSerializedForm());
3351         // The values written for cached fields are compatible with older
3352         // versions, but are ignored in readObject so don't otherwise matter.
3353         fields.put("bitCount", -1);
3354         fields.put("bitLength", -1);