1 /* 2 * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos 3 * 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * * Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * * Neither the name of JSR-310 nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package org.threeten.bp; 33 34 import java.io.DataInput; 35 import java.io.DataOutput; 36 import java.io.Externalizable; 37 import java.io.IOException; 38 import java.io.InvalidClassException; 39 import java.io.ObjectInput; 40 import java.io.ObjectOutput; 41 import java.io.StreamCorruptedException; 42 43 /** 44 * The shared serialization delegate for this package. 45 * 46 * <h4>Implementation notes</h4> 47 * This class wraps the object being serialized, and takes a byte representing the type of the class to 48 * be serialized. This byte can also be used for versioning the serialization format. In this case another 49 * byte flag would be used in order to specify an alternative version of the type format. 50 * For example {@code LOCAL_DATE_TYPE_VERSION_2 = 21}. 51 * <p> 52 * In order to serialise the object it writes its byte and then calls back to the appropriate class where 53 * the serialisation is performed. In order to deserialise the object it read in the type byte, switching 54 * in order to select which class to call back into. 55 * <p> 56 * The serialisation format is determined on a per class basis. In the case of field based classes each 57 * of the fields is written out with an appropriate size format in descending order of the field's size. For 58 * example in the case of {@link LocalDate} year is written before month. Composite classes, such as 59 * {@link LocalDateTime} are serialised as one object. 60 * <p> 61 * This class is mutable and should be created once per serialization. 62 * 63 * @serial include 64 */ 65 final class Ser implements Externalizable { 66 67 /** 68 * Serialization version. 69 */ 70 private static final long serialVersionUID = -7683839454370182990L; 71 72 static final byte DURATION_TYPE = 1; 73 static final byte INSTANT_TYPE = 2; 74 static final byte LOCAL_DATE_TYPE = 3; 75 static final byte LOCAL_DATE_TIME_TYPE = 4; 76 static final byte LOCAL_TIME_TYPE = 5; 77 static final byte ZONED_DATE_TIME_TYPE = 6; 78 static final byte ZONE_REGION_TYPE = 7; 79 static final byte ZONE_OFFSET_TYPE = 8; 80 81 static final byte MONTH_DAY_TYPE = 64; 82 static final byte OFFSET_TIME_TYPE = 66; 83 static final byte YEAR_TYPE = 67; 84 static final byte YEAR_MONTH_TYPE = 68; 85 static final byte OFFSET_DATE_TIME_TYPE = 69; 86 87 /** The type being serialized. */ 88 private byte type; 89 /** The object being serialized. */ 90 private Object object; 91 92 /** 93 * Constructor for deserialization. 94 */ Ser()95 public Ser() { 96 } 97 98 /** 99 * Creates an instance for serialization. 100 * 101 * @param type the type 102 * @param object the object 103 */ Ser(byte type, Object object)104 Ser(byte type, Object object) { 105 this.type = type; 106 this.object = object; 107 } 108 109 //----------------------------------------------------------------------- 110 /** 111 * Implements the {@code Externalizable} interface to write the object. 112 * 113 * @param out the data stream to write to, not null 114 */ writeExternal(ObjectOutput out)115 public void writeExternal(ObjectOutput out) throws IOException { 116 writeInternal(type, object, out); 117 } 118 writeInternal(byte type, Object object, DataOutput out)119 static void writeInternal(byte type, Object object, DataOutput out) throws IOException { 120 out.writeByte(type); 121 switch (type) { 122 case DURATION_TYPE: 123 ((Duration) object).writeExternal(out); 124 break; 125 case INSTANT_TYPE: 126 ((Instant) object).writeExternal(out); 127 break; 128 case LOCAL_DATE_TYPE: 129 ((LocalDate) object).writeExternal(out); 130 break; 131 case LOCAL_DATE_TIME_TYPE: 132 ((LocalDateTime) object).writeExternal(out); 133 break; 134 case LOCAL_TIME_TYPE: 135 ((LocalTime) object).writeExternal(out); 136 break; 137 case MONTH_DAY_TYPE: 138 ((MonthDay) object).writeExternal(out); 139 break; 140 case OFFSET_DATE_TIME_TYPE: 141 ((OffsetDateTime) object).writeExternal(out); 142 break; 143 case OFFSET_TIME_TYPE: 144 ((OffsetTime) object).writeExternal(out); 145 break; 146 case YEAR_MONTH_TYPE: 147 ((YearMonth) object).writeExternal(out); 148 break; 149 case YEAR_TYPE: 150 ((Year) object).writeExternal(out); 151 break; 152 case ZONE_REGION_TYPE: 153 ((ZoneRegion) object).writeExternal(out); 154 break; 155 case ZONE_OFFSET_TYPE: 156 ((ZoneOffset) object).writeExternal(out); 157 break; 158 case ZONED_DATE_TIME_TYPE: 159 ((ZonedDateTime) object).writeExternal(out); 160 break; 161 default: 162 throw new InvalidClassException("Unknown serialized type"); 163 } 164 } 165 166 //----------------------------------------------------------------------- 167 /** 168 * Implements the {@code Externalizable} interface to read the object. 169 * 170 * @param in the data to read, not null 171 */ readExternal(ObjectInput in)172 public void readExternal(ObjectInput in) throws IOException { 173 type = in.readByte(); 174 object = readInternal(type, in); 175 } 176 read(DataInput in)177 static Object read(DataInput in) throws IOException { 178 byte type = in.readByte(); 179 return readInternal(type, in); 180 } 181 readInternal(byte type, DataInput in)182 private static Object readInternal(byte type, DataInput in) throws IOException { 183 switch (type) { 184 case DURATION_TYPE: return Duration.readExternal(in); 185 case INSTANT_TYPE: return Instant.readExternal(in); 186 case LOCAL_DATE_TYPE: return LocalDate.readExternal(in); 187 case LOCAL_DATE_TIME_TYPE: return LocalDateTime.readExternal(in); 188 case LOCAL_TIME_TYPE: return LocalTime.readExternal(in); 189 case MONTH_DAY_TYPE: return MonthDay.readExternal(in); 190 case OFFSET_DATE_TIME_TYPE: return OffsetDateTime.readExternal(in); 191 case OFFSET_TIME_TYPE: return OffsetTime.readExternal(in); 192 case YEAR_TYPE: return Year.readExternal(in); 193 case YEAR_MONTH_TYPE: return YearMonth.readExternal(in); 194 case ZONED_DATE_TIME_TYPE: return ZonedDateTime.readExternal(in); 195 case ZONE_OFFSET_TYPE: return ZoneOffset.readExternal(in); 196 case ZONE_REGION_TYPE: return ZoneRegion.readExternal(in); 197 default: 198 throw new StreamCorruptedException("Unknown serialized type"); 199 } 200 } 201 202 /** 203 * Returns the object that will replace this one. 204 * 205 * @return the read object, should never be null 206 */ readResolve()207 private Object readResolve() { 208 return object; 209 } 210 211 } 212