/** * Copyright 2014 Duan Bingnan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.pinus4j.serializer.codec.impl; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import org.pinus4j.exceptions.CodecException; import org.pinus4j.serializer.codec.Codec; import org.pinus4j.serializer.codec.CodecConfig; import org.pinus4j.serializer.codec.CodecType; import org.pinus4j.serializer.io.DataInput; import org.pinus4j.serializer.io.DataOutput; import org.pinus4j.utils.BeansUtil; import org.pinus4j.utils.ReflectUtil; /** * 这个类只能序列化自定义对象,不能将基本类型当作对象来进行序列化,否则会发生错误. 基本类型的序列化使用相关的编码类. * * @author duanbn * @since 1.0 */ public class ObjectCodec implements Codec<Object> { public void encode(DataOutput output, Object v, CodecConfig config) throws CodecException { try { output.writeByte(CodecType.TYPE_OBJECT); // write type if (v == null) { output.writeByte(CodecType.NULL); // write isnull return; } output.writeByte(CodecType.NOT_NULL); // write is not null Class<?> oc = v.getClass(); output.writeGBK(oc.getName()); // write classname Object fvalue = null; Codec codec = null; for (Field f : ReflectUtil.getFields(oc)) { // write field if (!f.isAccessible()) { f.setAccessible(true); } // 基本类型序列化 if (f.getType() == Boolean.TYPE) { output.writeByte(CodecType.TYPE_BOOLEAN); output.writeBoolean(f.getBoolean(v)); continue; } else if (f.getType() == Byte.TYPE) { output.writeByte(CodecType.TYPE_BYTE); output.writeByte(f.getByte(v)); continue; } else if (f.getType() == Character.TYPE) { output.writeByte(CodecType.TYPE_CHAR); output.writeChar(f.getChar(v)); continue; } else if (f.getType() == Short.TYPE) { output.writeByte(CodecType.TYPE_SHORT); output.writeShort(f.getShort(v)); continue; } else if (f.getType() == Integer.TYPE) { output.writeByte(CodecType.TYPE_INT); output.writeInt(f.getInt(v)); continue; } else if (f.getType() == Long.TYPE) { output.writeByte(CodecType.TYPE_LONG); output.writeLong(f.getLong(v)); continue; } else if (f.getType() == Float.TYPE) { output.writeByte(CodecType.TYPE_FLOAT); output.writeFloat(f.getFloat(v)); continue; } else if (f.getType() == Double.TYPE) { output.writeByte(CodecType.TYPE_DOUBLE); output.writeDouble(f.getDouble(v)); continue; } fvalue = f.get(v); if (fvalue == null) { // write field isnull output.writeByte(CodecType.NULL); continue; } output.writeByte(CodecType.NOT_NULL); codec = config.lookup(fvalue); codec.encode(output, fvalue, config); } } catch (IllegalAccessException e) { throw new CodecException(e); } } public Object decode(DataInput input, CodecConfig config) throws CodecException { try { if (input.readByte() == CodecType.NULL) { // read isnull return null; } Class<?> oc = BeansUtil.getClass(input.readGBK()); // read classname Object instance = ReflectUtil.newObject(oc); Object fvalue = null; Codec<?> codec = null; for (Field f : ReflectUtil.getFields(oc)) { // read field if (!f.isAccessible()) { f.setAccessible(true); } byte type = input.readByte(); // 基本类型反序列化 if (type == CodecType.TYPE_BOOLEAN) { f.setBoolean(instance, input.readBoolean()); continue; } else if (type == CodecType.TYPE_BYTE) { f.setByte(instance, input.readByte()); continue; } else if (type == CodecType.TYPE_CHAR) { f.setChar(instance, input.readChar()); continue; } else if (type == CodecType.TYPE_INT) { f.setInt(instance, input.readInt()); continue; } else if (type == CodecType.TYPE_SHORT) { f.setShort(instance, input.readShort()); continue; } else if (type == CodecType.TYPE_LONG) { f.setLong(instance, input.readLong()); continue; } else if (type == CodecType.TYPE_FLOAT) { f.setFloat(instance, input.readFloat()); continue; } else if (type == CodecType.TYPE_DOUBLE) { f.setDouble(instance, input.readDouble()); continue; } if (type == CodecType.NULL) { f.set(instance, null); continue; } type = input.readByte(); codec = config.lookup(type); fvalue = codec.decode(input, config); f.set(instance, fvalue); } return instance; } catch (Exception e) { throw new CodecException(e); } } }