ActiveJ学习心得——serializer(5)

2021SC@SDUSC

一、代码分析内容

本次博客我们继续介绍core-serializer包中的impl包。上个博客我介绍了其中的一部分,例如AbstractSerializerDefCollection类、AbstractSerializerDefMap类、ForwardingSerializerDef类、SerializerDefWithFixedSize类、SerializerDefWithNullable类、SerializerDefWithVarLength类、SerializerExpressions类。
这些类不是定义数据结构序列化的类,而是比较层次比较高的类,层次要比具体的数据结构要高一些。而这次博客就介绍定义数据结构序列化的类。

二、impl包结构


本次先介绍SerializerDefArray类、SerializerDefBoolean类、SerializerDefByte类、SerializerDefByteBuffer类、SerializerDefChar类和SerializerDefPrimitive类这六个类。

三、代码解读

1.SerializerDefPrimitive类
我们从类名中就可以看出这是序列化定义原语的类。原语在前面几次博客中也有提到过,它在序列化器中起着比较重要的作用。下面我们来看一下它的代码。
SerializerDefPrimitive类继承了AbstractSerializerDef类和SerializerDef抽象类。它定义了primitiveType、wrappedType、wrapped,分别是原语类型,包装类型,是否已经包装。下面是它的构造方法:

	protected SerializerDefPrimitive(Class<?> primitiveType, boolean wrapped) {
    
    
		if (!primitiveType.isPrimitive())
			throw new IllegalArgumentException("Not a primitive type");
		this.primitiveType = primitiveType;
		this.wrappedType = wrap(primitiveType);
		this.wrapped = wrapped;
	}

在构造方法中有一个判断,判断是否是原语,如果不是就抛出异常。
下面是三个重写的方法,是重写的SerializerDef类中的,它是根据是否包装来返回包装类型或者原语类型。上下两个就是序列化定于原语的编码和解码方法。

	@Override
	public Class<?> getEncodeType() {
    
    
		return wrapped ? wrappedType : primitiveType;
	}
	@Override
	public final Expression encoder(StaticEncoders staticEncoders, Expression buf, Variable pos, Expression value, int version, CompatibilityLevel compatibilityLevel) {
    
    
		return doSerialize(buf, pos, castToPrimitive() ? cast(value, primitiveType) : value, compatibilityLevel);
	}
	@Override
	public final Expression decoder(StaticDecoders staticDecoders, Expression in, int version, CompatibilityLevel compatibilityLevel) {
    
    
		Expression expression = doDeserialize(in, compatibilityLevel);
		return wrapped ? cast(expression, wrappedType) : expression;
	}

2.SerializerDefArray类
SerializerDefArray类是序列化定义数组的类,它继承AbstractSerializerDef类、SerializerDefWithNullable类和 SerializerDefWithFixedSize类。
因为是有关Array的,所以此类要定义fixedSize属性,而且数组可能会为空,所以也要定义nullable这个是否可为空的属性。下面是定义的属性和构造方法:

	private final SerializerDef valueSerializer;
	private final int fixedSize;
	private final Class<?> type;
	private final boolean nullable;

	public SerializerDefArray(SerializerDef serializer, Class<?> type) {
    
    
		this.valueSerializer = serializer;
		this.fixedSize = -1;
		this.type = type;
		this.nullable = false;
	}
	private SerializerDefArray(@NotNull SerializerDef serializer, int fixedSize, Class<?> type, boolean nullable) {
    
    
		this.valueSerializer = serializer;
		this.fixedSize = fixedSize;
		this.type = type;
		this.nullable = nullable;
	}

下面是两个重写的方法,分别是SerializerDefWithFixedSize类中的方法和SerializerDefWithNullable类中的方法。

	@Override
	public SerializerDefArray ensureFixedSize(int fixedSize) {
    
    
		return new SerializerDefArray(valueSerializer, fixedSize, type, nullable);
	}

	@Override
	public SerializerDef ensureNullable(CompatibilityLevel compatibilityLevel) {
    
    
		if (compatibilityLevel.getLevel() < LEVEL_3.getLevel()) {
    
    
			return new SerializerDefNullable(this);
		}
		return new SerializerDefArray(valueSerializer, fixedSize, type, true);
	}

3.SerializerDefBoolean类
SerializerDefBoolean类是序列化定义Boolean的类。继承了SerializerDefPrimitive类和SerializerDefWithNullable类。
它定义的属性和构造方法如下:

	public static final byte NULLABLE_NULL = 0b00;
	public static final byte NULLABLE_FALSE = 0b10;
	public static final byte NULLABLE_TRUE = 0b11;

	private final boolean nullable;

	public SerializerDefBoolean() {
    
    
		this(true);
	}

	public SerializerDefBoolean(boolean wrapped) {
    
    
		this(wrapped, false);
	}

	public SerializerDefBoolean(boolean wrapped, boolean nullable) {
    
    
		super(boolean.class, wrapped);
		if (nullable && !wrapped) throw new IllegalArgumentException("Primitive cannot be nullable");
		this.nullable = nullable;
	}

这是一个经过序列化包装的Boolean,它也重写了几个继承自SerializerDefPrimitive类的方法。原语在这里还是很重要的,有很多类都继承了此方法。

	@Override
	public SerializerDef ensureWrapped() {
    
    
		return new SerializerDefBoolean(true, nullable);
	}

	@Override
	protected boolean castToPrimitive() {
    
    
		return !nullable;
	}

4.SerializerDefByte类
SerializerDefByte类也继承了SerializerDefPrimitive类。因为是序列化定义的字节,所以比较内容比较简单,没有再定义新的属性,而是重写了SerializerDefPrimitive类中的几个方法。

	public SerializerDefByte() {
    
    
		this(true);
	}
	public SerializerDefByte(boolean wrapped) {
    
    
		super(byte.class, wrapped);
	}
	@Override
	public SerializerDef ensureWrapped() {
    
    
		return new SerializerDefByte(true);
	}
	@Override
	protected Expression doSerialize(Expression byteArray, Variable off, Expression value, CompatibilityLevel compatibilityLevel) {
    
    
		return writeByte(byteArray, off, value);
	}
	@Override
	protected Expression doDeserialize(Expression in, CompatibilityLevel compatibilityLevel) {
    
    
		return readByte(in);
	}

分别是确定包装、序列化和反序列化方法。序列化是使用writeByte方法实现,反序列化是使用readByte方法实现。
5.SerializerDefChar类
SerializerDefChar类和SerializerDefByte类类似,因为都是基本的数据类型,所以实现起来都是类似的。最大的区别就是这些方法都是换乘Char对象的了。序列化和反序列化方法使用的是writeChar方法和readChar方法。

	public SerializerDefChar() {
    
    
		this(true);
	}
	public SerializerDefChar(boolean wrapped) {
    
    
		super(char.class, wrapped);
	}
	@Override
	public SerializerDef ensureWrapped() {
    
    
		return new SerializerDefChar(true);
	}
	@Override
	protected Expression doSerialize(Expression byteArray, Variable off, Expression value, CompatibilityLevel compatibilityLevel) {
    
    
		return writeChar(byteArray, off, value, !compatibilityLevel.isLittleEndian());
	}
	@Override
	protected Expression doDeserialize(Expression in, CompatibilityLevel compatibilityLevel) {
    
    
		return readChar(in, !compatibilityLevel.isLittleEndian());
	}

6.SerializerDefByteBuffer类
SerializerDefByteBuffer类继承了AbstractSerializerDef类和 SerializerDefWithNullable类,它是序列化定义字节缓冲的类,定义的属性和构造方法如下:

	private final boolean wrapped;
	private final boolean nullable;

	public SerializerDefByteBuffer() {
    
    
		this(false);
	}

	public SerializerDefByteBuffer(boolean wrapped) {
    
    
		this.wrapped = wrapped;
		this.nullable = false;
	}

这个类中最重要的是编码和解码方法,因为它是一个字节缓冲,所以它既要有Byte的属性还要对buffer进行定义和修改。编码需要对缓冲区间进行操作,编码的过程共要使用writeVarInt和writeBytes方法在缓冲的某一位置进行编写,解码过程就是编码过程反过来。下面是encoder方法:

	public Expression encoder(StaticEncoders staticEncoders, Expression buf, Variable pos, Expression value, int version, CompatibilityLevel compatibilityLevel) {
    
    
		return let(
				cast(value, ByteBuffer.class),
				buffer -> {
    
    
					if (!nullable) {
    
    
						return let(call(buffer, "remaining"), remaining ->
								sequence(
										writeVarInt(buf, pos, remaining),
										writeBytes(buf, pos, call(buffer, "array"), call(buffer, "position"), remaining)));
					} else {
    
    
						return ifThenElse(isNull(buffer),
								writeByte(buf, pos, value((byte) 0)),
								let(call(buffer, "remaining"), remaining ->
										sequence(
												writeVarInt(buf, pos, inc(remaining)),
												writeBytes(buf, pos, call(buffer, "array"), call(buffer, "position"), remaining))));
					}
				});
	}

四、总结

本次博客分析的是impl包中另外的6个类。除了定义原语之外的5个类都是对一定的数据结构进行序列化定义,根据原本数据结构的复杂程度,序列化定义的复杂程度也有所不同,但它们的基本结构是类似的,且都有encoder和decoder方法。

猜你喜欢

转载自blog.csdn.net/zth_idea/article/details/121781262