/*
* Copyright © 2009-2011 Rebecca G. Bettencourt / Kreative Software
* <p>
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* <a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a>
* <p>
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
* <p>
* Alternatively, the contents of this file may be used under the terms
* of the GNU Lesser General Public License (the "LGPL License"), in which
* case the provisions of LGPL License are applicable instead of those
* above. If you wish to allow use of your version of this file only
* under the terms of the LGPL License and not to allow others to use
* your version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the LGPL License. If you do not delete
* the provisions above, a recipient may use your version of this file
* under either the MPL or the LGPL License.
* @since PowerPaint 1.0
* @author Rebecca G. Bettencourt, Kreative Software
*/
package com.kreative.paint.io;
import java.io.*;
import java.util.*;
/* This and CollectionSerializer more or less cover the java.util package. */
/* This more or less covers the java.io package. */
public class UtilitySerializer extends Serializer {
private static final int TYPE_BIT_SET = fcc("BSet");
private static final int TYPE_CURRENCY = fcc("Curr");
private static final int TYPE_DATE = fcc("Date");
private static final int TYPE_FILE = fcc("File");
private static final int TYPE_GREGORIAN_CALENDAR = fcc("GCal");
private static final int TYPE_LOCALE = fcc("Loca");
private static final int TYPE_PROPERTIES = fcc("Prop");
private static final int TYPE_RANDOM = fcc("Rand");
private static final int TYPE_SIMPLE_TIME_ZONE = fcc("STZo");
private static final int TYPE_UUID = fcc("UUID");
protected void loadRecognizedTypesAndClasses() {
addTypeAndClass(TYPE_BIT_SET, 1, BitSet.class);
addTypeAndClass(TYPE_CURRENCY, 1, Currency.class);
addTypeAndClass(TYPE_DATE, 1, Date.class);
addTypeAndClass(TYPE_FILE, 1, File.class);
addTypeAndClass(TYPE_GREGORIAN_CALENDAR, 1, GregorianCalendar.class);
addTypeAndClass(TYPE_LOCALE, 1, Locale.class);
addTypeAndClass(TYPE_PROPERTIES, 1, Properties.class);
addTypeAndClass(TYPE_RANDOM, 1, Random.class);
addTypeAndClass(TYPE_SIMPLE_TIME_ZONE, 1, SimpleTimeZone.class);
addTypeAndClass(TYPE_UUID, 1, UUID.class);
}
public void serializeObject(Object o, DataOutputStream stream) throws IOException {
if (o instanceof BitSet) {
BitSet v = (BitSet)o;
byte[] b = new byte[(v.length() + 7) >>> 3];
for (int i = v.nextSetBit(0); i >= 0; i = v.nextSetBit(i+1)) {
b[i >>> 3] |= (1 << (i & 7));
}
stream.writeInt(b.length);
stream.write(b);
}
else if (o instanceof Currency) {
Currency v = (Currency)o;
stream.writeUTF(v.getCurrencyCode());
}
else if (o instanceof Date) {
Date v = (Date)o;
stream.writeLong(v.getTime());
}
else if (o instanceof File) {
File v = (File)o;
stream.writeUTF(v.getPath());
}
else if (o instanceof GregorianCalendar) {
GregorianCalendar v = (GregorianCalendar)o;
stream.writeLong(v.getTimeInMillis());
stream.writeLong(v.getGregorianChange().getTime());
//SerializationManager.writeObject(v.getTimeZone(), stream);
}
else if (o instanceof Locale) {
Locale v = (Locale)o;
stream.writeUTF(v.toString());
}
else if (o instanceof Properties) {
Properties v = (Properties)o;
stream.writeInt(v.size());
for (Map.Entry<Object,Object> e : v.entrySet()) {
SerializationManager.writeObject(e.getKey(), stream);
SerializationManager.writeObject(e.getValue(), stream);
}
}
else if (o instanceof Random) {
// nothing
}
else if (o instanceof SimpleTimeZone) {
SimpleTimeZone v = (SimpleTimeZone)o;
stream.writeUTF(v.getID());
}
else if (o instanceof UUID) {
UUID v = (UUID)o;
stream.writeLong(v.getMostSignificantBits());
stream.writeLong(v.getLeastSignificantBits());
}
}
public Object deserializeObject(int type, int version, DataInputStream stream) throws IOException {
if (version != 1) throw new IOException("Invalid version number.");
else if (type == TYPE_BIT_SET) {
int n = stream.readInt();
byte[] b = new byte[n];
stream.read(b);
BitSet bs = new BitSet(n << 3);
for (int i = 0; i < n; i++) {
for (int j = 0, m = 1; j < 8; j++, m <<= 1) {
if ((b[i] & m) != 0) {
bs.set((i << 3) | j);
}
}
}
return bs;
}
else if (type == TYPE_CURRENCY) {
return Currency.getInstance(stream.readUTF());
}
else if (type == TYPE_DATE) {
return new Date(stream.readLong());
}
else if (type == TYPE_FILE) {
return new File(stream.readUTF());
}
else if (type == TYPE_GREGORIAN_CALENDAR) {
long t = stream.readLong();
long c = stream.readLong();
//TimeZone tz = (TimeZone)SerializationManager.readObject(stream);
GregorianCalendar gc = new GregorianCalendar();
//gc.setTimeZone(tz);
gc.setGregorianChange(new Date(c));
gc.setTimeInMillis(t);
return gc;
}
else if (type == TYPE_LOCALE) {
String s = stream.readUTF();
Locale[] ll = Locale.getAvailableLocales();
for (Locale l : ll) {
if (l.toString().equals(s)) {
return l;
}
}
return null;
}
else if (type == TYPE_PROPERTIES) {
int n = stream.readInt();
Properties p = new Properties();
for (int i = 0; i < n; i++) {
Object k = SerializationManager.readObject(stream);
Object v = SerializationManager.readObject(stream);
p.put(k,v);
}
return p;
}
else if (type == TYPE_RANDOM) {
return new Random();
}
else if (type == TYPE_SIMPLE_TIME_ZONE) {
return SimpleTimeZone.getTimeZone(stream.readUTF());
}
else if (type == TYPE_UUID) {
long m = stream.readLong();
long l = stream.readLong();
return new UUID(m,l);
}
else return null;
}
}