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 |