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);
3345         fields.put("lowestSetBit", -2);
3346         fields.put("firstNonzeroByteNum", -2);
3347 




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 = 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         private static void putSign(BigInteger bi, int sign) {
3329             unsafe.putIntVolatile(bi, signumOffset, sign);
3330         }
3331 
3332         private static void putMag(BigInteger bi, int[] magnitude) {
3333             unsafe.putObjectVolatile(bi, magOffset, magnitude);
3334         }
3335     }
3336 
3337     /**
3338      * Save the {@code BigInteger} instance to a stream.
3339      * The magnitude of a BigInteger is serialized as a byte array for
3340      * historical reasons.
3341      *
3342      * @serialData two necessary fields are written as well as obsolete
3343      *             fields for compatibility with older versions.
3344      */
3345     private void writeObject(ObjectOutputStream s) throws IOException {
3346         // set the values of the Serializable fields
3347         ObjectOutputStream.PutField fields = s.putFields();
3348         fields.put("signum", signum);
3349         fields.put("magnitude", magSerializedForm());
3350         // The values written for cached fields are compatible with older
3351         // versions, but are ignored in readObject so don't otherwise matter.
3352         fields.put("bitCount", -1);
3353         fields.put("bitLength", -1);
3354         fields.put("lowestSetBit", -2);
3355         fields.put("firstNonzeroByteNum", -2);
3356