1 /* 2 * hunt-time: A time library for D programming language. 3 * 4 * Copyright (C) 2015-2018 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.time.chrono.Ser; 13 14 import hunt.stream.Externalizable; 15 import hunt.Exceptions; 16 // import hunt.io.InvalidClassException; 17 import hunt.stream.ObjectInput; 18 import hunt.stream.ObjectOutput; 19 // import hunt.io.StreamCorruptedException; 20 import hunt.time.LocalDate; 21 import hunt.time.LocalDateTime; 22 import hunt.time.chrono.AbstractChronology; 23 import hunt.time.chrono.JapaneseDate; 24 import hunt.time.chrono.JapaneseEra; 25 import hunt.time.chrono.HijrahDate; 26 import hunt.time.chrono.MinguoDate; 27 import hunt.time.chrono.ThaiBuddhistDate; 28 import hunt.time.chrono.ChronoPeriodImpl; 29 import hunt.time.chrono.ChronoLocalDateTimeImpl; 30 import hunt.time.chrono.ChronoZonedDateTimeImpl; 31 import hunt.time.chrono.ChronoLocalDate; 32 /** 33 * The shared serialization delegate for this package. 34 * 35 * @implNote 36 * This class wraps the object being serialized, and takes a byte representing the type of the class to 37 * be serialized. This byte can also be used for versioning the serialization format. In this case another 38 * byte flag would be used _in order to specify an alternative version of the type format. 39 * For example {@code CHRONO_TYPE_VERSION_2 = 21} 40 * !(p) 41 * In order to serialize the object it writes its byte and then calls back to the appropriate class where 42 * the serialization is performed. In order to deserialize the object it read _in the type byte, switching 43 * _in order to select which class to call back into. 44 * !(p) 45 * The serialization format is determined on a per class basis. In the case of field based classes each 46 * of the fields is written _out with an appropriate size format _in descending order of the field's size. For 47 * example _in the case of {@link LocalDate} year is written before month. Composite classes, such as 48 * {@link LocalDateTime} are serialized as one object. Enum classes are serialized using the index of their 49 * element. 50 * !(p) 51 * This class is mutable and should be created once per serialization. 52 * 53 * @serial include 54 * @since 1.8 55 */ 56 final class Ser : Externalizable { 57 58 /** 59 * Serialization version. 60 */ 61 private enum long serialVersionUID = -6103370247208168577L; 62 63 enum byte CHRONO_TYPE = 1; 64 enum byte CHRONO_LOCAL_DATE_TIME_TYPE = 2; 65 enum byte CHRONO_ZONE_DATE_TIME_TYPE = 3; 66 enum byte JAPANESE_DATE_TYPE = 4; 67 enum byte JAPANESE_ERA_TYPE = 5; 68 enum byte HIJRAH_DATE_TYPE = 6; 69 enum byte MINGUO_DATE_TYPE = 7; 70 enum byte THAIBUDDHIST_DATE_TYPE = 8; 71 enum byte CHRONO_PERIOD_TYPE = 9; 72 73 /** The type being serialized. */ 74 private byte type; 75 /** The object being serialized. */ 76 private Object object; 77 78 /** 79 * Constructor for deserialization. 80 */ 81 public this() { 82 } 83 84 /** 85 * Creates an instance for serialization. 86 * 87 * @param type the type 88 * @param object the object 89 */ 90 this(byte type, Object object) { 91 this.type = type; 92 this.object = object; 93 } 94 95 //----------------------------------------------------------------------- 96 /** 97 * Implements the {@code Externalizable} interface to write the object. 98 * @serialData 99 * Each serializable class is mapped to a type that is the first byte 100 * _in the stream. Refer to each class {@code writeReplace} 101 * serialized form for the value of the type and sequence of values for the type. 102 * !(ul) 103 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.HijrahChronology">HijrahChronology.writeReplace</a> 104 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.IsoChronology">IsoChronology.writeReplace</a> 105 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.JapaneseChronology">JapaneseChronology.writeReplace</a> 106 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.MinguoChronology">MinguoChronology.writeReplace</a> 107 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.ThaiBuddhistChronology">ThaiBuddhistChronology.writeReplace</a> 108 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.ChronoLocalDateTimeImpl">ChronoLocalDateTime.writeReplace</a> 109 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.ChronoZonedDateTimeImpl">ChronoZonedDateTime.writeReplace</a> 110 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.JapaneseDate">JapaneseDate.writeReplace</a> 111 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.JapaneseEra">JapaneseEra.writeReplace</a> 112 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.HijrahDate">HijrahDate.writeReplace</a> 113 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.MinguoDate">MinguoDate.writeReplace</a> 114 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.ThaiBuddhistDate">ThaiBuddhistDate.writeReplace</a> 115 * </ul> 116 * 117 * @param _out the data stream to write to, not null 118 */ 119 override 120 public void writeExternal(ObjectOutput _out) /*throws IOException*/ { 121 writeInternal(type, object, _out); 122 } 123 124 private static void writeInternal(byte type, Object object, ObjectOutput _out) /*throws IOException*/ { 125 _out.writeByte(type); 126 switch (type) { 127 case CHRONO_TYPE: 128 (cast(AbstractChronology) object).writeExternal(_out); 129 break; 130 case CHRONO_LOCAL_DATE_TIME_TYPE: 131 (cast(ChronoLocalDateTimeImpl!(ChronoLocalDate)) object).writeExternal(_out); 132 break; 133 case CHRONO_ZONE_DATE_TIME_TYPE: 134 (cast(ChronoZonedDateTimeImpl!(ChronoLocalDate)) object).writeExternal(_out); 135 break; 136 // case JAPANESE_DATE_TYPE: 137 // (cast(JapaneseDate) object).writeExternal(_out); 138 // break; 139 // case JAPANESE_ERA_TYPE: 140 // (cast(JapaneseEra) object).writeExternal(_out); 141 // break; 142 // case HIJRAH_DATE_TYPE: 143 // (cast(HijrahDate) object).writeExternal(_out); 144 // break; 145 // case MINGUO_DATE_TYPE: 146 // (cast(MinguoDate) object).writeExternal(_out); 147 // break; 148 // case THAIBUDDHIST_DATE_TYPE: 149 // (cast(ThaiBuddhistDate) object).writeExternal(_out); 150 // break; 151 case CHRONO_PERIOD_TYPE: 152 (cast(ChronoPeriodImpl) object).writeExternal(_out); 153 break; 154 default: 155 throw new InvalidClassException("Unknown serialized type"); 156 } 157 } 158 159 //----------------------------------------------------------------------- 160 /** 161 * Implements the {@code Externalizable} interface to read the object. 162 * @serialData 163 * The streamed type and parameters defined by the type's {@code writeReplace} 164 * method are read and passed to the corresponding static factory for the type 165 * to create a new instance. That instance is returned as the de-serialized 166 * {@code Ser} object. 167 * 168 * !(ul) 169 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.HijrahChronology">HijrahChronology</a> - Chronology.of(id) 170 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.IsoChronology">IsoChronology</a> - Chronology.of(id) 171 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.JapaneseChronology">JapaneseChronology</a> - Chronology.of(id) 172 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.MinguoChronology">MinguoChronology</a> - Chronology.of(id) 173 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.ThaiBuddhistChronology">ThaiBuddhistChronology</a> - Chronology.of(id) 174 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.ChronoLocalDateTimeImpl">ChronoLocalDateTime</a> - date.atTime(time) 175 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.ChronoZonedDateTimeImpl">ChronoZonedDateTime</a> - dateTime.atZone(offset).withZoneSameLocal(zone) 176 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.JapaneseDate">JapaneseDate</a> - JapaneseChronology.INSTANCE.date(year, month, dayOfMonth) 177 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.JapaneseEra">JapaneseEra</a> - JapaneseEra.of(eraValue) 178 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.HijrahDate">HijrahDate</a> - HijrahChronology chrono.date(year, month, dayOfMonth) 179 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.MinguoDate">MinguoDate</a> - MinguoChronology.INSTANCE.date(year, month, dayOfMonth) 180 * !(li)<a href="{@docRoot}/serialized-form.html#hunt.time.chrono.ThaiBuddhistDate">ThaiBuddhistDate</a> - ThaiBuddhistChronology.INSTANCE.date(year, month, dayOfMonth) 181 * </ul> 182 * 183 * @param _in the data stream to read from, not null 184 */ 185 override 186 public void readExternal(ObjectInput _in) /*throws IOException, ClassNotFoundException*/ { 187 type = _in.readByte(); 188 object = readInternal(type, _in); 189 } 190 191 static Object read(ObjectInput _in) /*throws IOException, ClassNotFoundException*/ { 192 byte type = _in.readByte(); 193 return readInternal(type, _in); 194 } 195 196 private static Object readInternal(byte type, ObjectInput _in) /*throws IOException, ClassNotFoundException */{ 197 switch (type) { 198 case CHRONO_TYPE: return cast(Object)(AbstractChronology.readExternal(_in)); 199 case CHRONO_LOCAL_DATE_TIME_TYPE: return cast(Object)(ChronoLocalDateTimeImpl!(ChronoLocalDate).readExternal(_in)); 200 case CHRONO_ZONE_DATE_TIME_TYPE: return cast(Object)(ChronoZonedDateTimeImpl!(ChronoLocalDate).readExternal(_in)); 201 // case JAPANESE_DATE_TYPE: return JapaneseDate.readExternal(_in); 202 // case JAPANESE_ERA_TYPE: return JapaneseEra.readExternal(_in); 203 // case HIJRAH_DATE_TYPE: return HijrahDate.readExternal(_in); 204 // case MINGUO_DATE_TYPE: return MinguoDate.readExternal(_in); 205 // case THAIBUDDHIST_DATE_TYPE: return ThaiBuddhistDate.readExternal(_in); 206 case CHRONO_PERIOD_TYPE: return cast(Object)(ChronoPeriodImpl.readExternal(_in)); 207 default: throw new Exception("Unknown serialized type"); 208 } 209 } 210 211 /** 212 * Returns the object that will replace this one. 213 * 214 * @return the read object, should never be null 215 */ 216 private Object readResolve() { 217 return object; 218 } 219 220 }