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 private static void putSign(BigInteger bi, int sign) { 3330 unsafe.putIntVolatile(bi, signumOffset, sign); 3331 } 3332 3333 private 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); |