187 lines
7.0 KiB
Java
187 lines
7.0 KiB
Java
package com.esotericsoftware.kryo.serializers;
|
|
|
|
import c.e.a.a;
|
|
import com.esotericsoftware.kryo.Kryo;
|
|
import com.esotericsoftware.kryo.KryoException;
|
|
import com.esotericsoftware.kryo.io.Input;
|
|
import com.esotericsoftware.kryo.io.InputChunked;
|
|
import com.esotericsoftware.kryo.io.Output;
|
|
import com.esotericsoftware.kryo.io.OutputChunked;
|
|
import com.esotericsoftware.kryo.serializers.FieldSerializer;
|
|
import java.lang.annotation.ElementType;
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.lang.annotation.Target;
|
|
import java.lang.reflect.Field;
|
|
import java.util.Arrays;
|
|
import java.util.Comparator;
|
|
public class TaggedFieldSerializer<T> extends FieldSerializer<T> {
|
|
private static final Comparator<FieldSerializer.CachedField> TAGGED_VALUE_COMPARATOR = new AnonymousClass1();
|
|
private boolean[] annexed;
|
|
private boolean[] deprecated;
|
|
private int[] tags;
|
|
private int writeFieldCount;
|
|
|
|
/* renamed from: com.esotericsoftware.kryo.serializers.TaggedFieldSerializer$1 reason: invalid class name */
|
|
public static class AnonymousClass1 implements Comparator<FieldSerializer.CachedField> {
|
|
public int compare(FieldSerializer.CachedField cachedField, FieldSerializer.CachedField cachedField2) {
|
|
return ((Tag) cachedField.getField().getAnnotation(Tag.class)).value() - ((Tag) cachedField2.getField().getAnnotation(Tag.class)).value();
|
|
}
|
|
}
|
|
|
|
@Target({ElementType.FIELD})
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
public @interface Tag {
|
|
boolean annexed() default false;
|
|
|
|
int value();
|
|
}
|
|
|
|
public TaggedFieldSerializer(Kryo kryo, Class cls) {
|
|
super(kryo, cls, null, kryo.getTaggedFieldSerializerConfig().clone());
|
|
}
|
|
|
|
@Override // com.esotericsoftware.kryo.serializers.FieldSerializer
|
|
public void initializeCachedFields() {
|
|
FieldSerializer.CachedField[] fields = getFields();
|
|
int length = fields.length;
|
|
for (int i = 0; i < length; i++) {
|
|
if (fields[i].getField().getAnnotation(Tag.class) == null) {
|
|
a.C0053a aVar = a.a;
|
|
super.removeField(fields[i]);
|
|
}
|
|
}
|
|
FieldSerializer.CachedField[] fields2 = getFields();
|
|
this.tags = new int[fields2.length];
|
|
this.deprecated = new boolean[fields2.length];
|
|
this.annexed = new boolean[fields2.length];
|
|
this.writeFieldCount = fields2.length;
|
|
Arrays.sort(fields2, TAGGED_VALUE_COMPARATOR);
|
|
int length2 = fields2.length;
|
|
for (int i2 = 0; i2 < length2; i2++) {
|
|
Field field = fields2[i2].getField();
|
|
this.tags[i2] = ((Tag) field.getAnnotation(Tag.class)).value();
|
|
if (i2 > 0) {
|
|
int[] iArr = this.tags;
|
|
int i3 = i2 - 1;
|
|
if (iArr[i2] == iArr[i3]) {
|
|
throw new KryoException(String.format("The fields [%s] and [%s] both have a Tag value of %d.", field, fields2[i3].getField(), Integer.valueOf(this.tags[i2])));
|
|
}
|
|
}
|
|
if (field.getAnnotation(Deprecated.class) != null) {
|
|
this.deprecated[i2] = true;
|
|
this.writeFieldCount--;
|
|
}
|
|
if (((Tag) field.getAnnotation(Tag.class)).annexed()) {
|
|
this.annexed[i2] = true;
|
|
}
|
|
}
|
|
this.removedFields.clear();
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean isIgnoreUnkownTags() {
|
|
return false;
|
|
}
|
|
|
|
public boolean isSkipUnknownTags() {
|
|
return ((TaggedFieldSerializerConfig) this.config).isSkipUnknownTags();
|
|
}
|
|
|
|
@Override // com.esotericsoftware.kryo.serializers.FieldSerializer, com.esotericsoftware.kryo.Serializer
|
|
public T read(Kryo kryo, Input input, Class<T> cls) {
|
|
boolean z2;
|
|
FieldSerializer.CachedField cachedField;
|
|
T create = create(kryo, input, cls);
|
|
kryo.reference(create);
|
|
int readVarInt = input.readVarInt(true);
|
|
int[] iArr = this.tags;
|
|
FieldSerializer.CachedField[] fields = getFields();
|
|
InputChunked inputChunked = null;
|
|
for (int i = 0; i < readVarInt; i++) {
|
|
int readVarInt2 = input.readVarInt(true);
|
|
int length = iArr.length;
|
|
int i2 = 0;
|
|
while (true) {
|
|
if (i2 >= length) {
|
|
z2 = false;
|
|
cachedField = null;
|
|
break;
|
|
} else if (iArr[i2] == readVarInt2) {
|
|
cachedField = fields[i2];
|
|
z2 = this.annexed[i2];
|
|
break;
|
|
} else {
|
|
i2++;
|
|
}
|
|
}
|
|
if (cachedField == null) {
|
|
if (isSkipUnknownTags()) {
|
|
if (inputChunked == null) {
|
|
inputChunked = new InputChunked(input, 1024);
|
|
}
|
|
inputChunked.nextChunks();
|
|
a.C0053a aVar = a.a;
|
|
} else {
|
|
StringBuilder L = c.d.b.a.a.L("Unknown field tag: ", readVarInt2, " (");
|
|
L.append(getType().getName());
|
|
L.append(")");
|
|
throw new KryoException(L.toString());
|
|
}
|
|
} else if (z2) {
|
|
if (inputChunked == null) {
|
|
inputChunked = new InputChunked(input, 1024);
|
|
}
|
|
cachedField.read(inputChunked, create);
|
|
inputChunked.nextChunks();
|
|
} else {
|
|
cachedField.read(input, create);
|
|
}
|
|
}
|
|
return create;
|
|
}
|
|
|
|
@Override // com.esotericsoftware.kryo.serializers.FieldSerializer
|
|
public void removeField(FieldSerializer.CachedField cachedField) {
|
|
super.removeField(cachedField);
|
|
initializeCachedFields();
|
|
}
|
|
|
|
@Override // com.esotericsoftware.kryo.serializers.FieldSerializer
|
|
public void removeField(String str) {
|
|
super.removeField(str);
|
|
initializeCachedFields();
|
|
}
|
|
|
|
@Deprecated
|
|
public void setIgnoreUnknownTags(boolean z2) {
|
|
}
|
|
|
|
public void setSkipUnknownTags(boolean z2) {
|
|
((TaggedFieldSerializerConfig) this.config).setSkipUnknownTags(z2);
|
|
rebuildCachedFields();
|
|
}
|
|
|
|
@Override // com.esotericsoftware.kryo.serializers.FieldSerializer, com.esotericsoftware.kryo.Serializer
|
|
public void write(Kryo kryo, Output output, T t) {
|
|
FieldSerializer.CachedField[] fields = getFields();
|
|
output.writeVarInt(this.writeFieldCount, true);
|
|
int length = fields.length;
|
|
OutputChunked outputChunked = null;
|
|
for (int i = 0; i < length; i++) {
|
|
if (!this.deprecated[i]) {
|
|
output.writeVarInt(this.tags[i], true);
|
|
if (this.annexed[i]) {
|
|
if (outputChunked == null) {
|
|
outputChunked = new OutputChunked(output, 1024);
|
|
}
|
|
fields[i].write(outputChunked, t);
|
|
outputChunked.endChunks();
|
|
} else {
|
|
fields[i].write(output, t);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|