protobuf
This commit is contained in:
@@ -99,22 +99,22 @@ public class ArrayDecoder<R extends Reader, T> implements TagDecodeable<R, T[]>
|
||||
}
|
||||
}
|
||||
}
|
||||
final Decodeable<R, T> localdecoder = getComponentDecoder(this.componentDecoder, typevals);
|
||||
final Decodeable<R, T> localDecoder = getComponentDecoder(this.componentDecoder, typevals);
|
||||
final List<T> result = new ArrayList();
|
||||
boolean first = true;
|
||||
if (len == Reader.SIGN_NOLENGTH) {
|
||||
int startPosition = in.position();
|
||||
while (hasNext(in, member, startPosition, contentLength, first)) {
|
||||
R itemReader = getItemReader(in, member, first);
|
||||
if (itemReader == null) {
|
||||
if (itemReader == null) { // 元素读取完毕
|
||||
break;
|
||||
}
|
||||
result.add(readMemberValue(itemReader, member, localdecoder, first));
|
||||
result.add(readMemberValue(itemReader, member, localDecoder, first));
|
||||
first = false;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
result.add(localdecoder.convertFrom(in));
|
||||
result.add(localDecoder.convertFrom(in));
|
||||
}
|
||||
}
|
||||
in.readArrayE();
|
||||
|
||||
@@ -104,22 +104,22 @@ public class CollectionDecoder<R extends Reader, T> implements TagDecodeable<R,
|
||||
}
|
||||
}
|
||||
}
|
||||
final Decodeable<R, T> localdecoder = getComponentDecoder(this.componentDecoder, typevals);
|
||||
final Decodeable<R, T> localDecoder = getComponentDecoder(this.componentDecoder, typevals);
|
||||
final Collection<T> result = this.creator.create();
|
||||
boolean first = true;
|
||||
if (len == Reader.SIGN_NOLENGTH) {
|
||||
int startPosition = in.position();
|
||||
while (hasNext(in, member, startPosition, contentLength, first)) {
|
||||
R itemReader = getItemReader(in, member, first);
|
||||
if (itemReader == null) {
|
||||
if (itemReader == null) { // 元素读取完毕
|
||||
break;
|
||||
}
|
||||
result.add(readMemberValue(itemReader, member, localdecoder, first));
|
||||
result.add(readMemberValue(itemReader, member, localDecoder, first));
|
||||
first = false;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
result.add(localdecoder.convertFrom(in));
|
||||
result.add(localDecoder.convertFrom(in));
|
||||
}
|
||||
}
|
||||
in.readArrayE();
|
||||
|
||||
@@ -107,10 +107,18 @@ public final class DeMember<R extends Reader, T, F> {
|
||||
this.attribute.set(obj, decoder.convertFrom(in));
|
||||
}
|
||||
|
||||
public final void readByTag(R in, T obj) {
|
||||
this.attribute.set(obj, ((TagDecodeable<R, F>) decoder).convertFrom(in, this));
|
||||
}
|
||||
|
||||
public final F read(R in) {
|
||||
return decoder.convertFrom(in);
|
||||
}
|
||||
|
||||
public final F readByTag(R in) {
|
||||
return ((TagDecodeable<R, F>) decoder).convertFrom(in, this);
|
||||
}
|
||||
|
||||
public Attribute<T, F> getAttribute() {
|
||||
return this.attribute;
|
||||
}
|
||||
@@ -183,5 +191,4 @@ public final class DeMember<R extends Reader, T, F> {
|
||||
return "DeMember{" + "attribute=" + attribute.field() + ", position=" + position + ", tag=" + tag + ", decoder="
|
||||
+ (decoder == null ? null : decoder.getClass().getName()) + '}';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -85,22 +85,22 @@ public class StreamDecoder<R extends Reader, T> implements TagDecodeable<R, Stre
|
||||
}
|
||||
}
|
||||
}
|
||||
final Decodeable<R, T> localdecoder = getComponentDecoder(this.componentDecoder, typevals);
|
||||
final Decodeable<R, T> localDecoder = getComponentDecoder(this.componentDecoder, typevals);
|
||||
final List<T> result = new ArrayList();
|
||||
boolean first = true;
|
||||
if (len == Reader.SIGN_NOLENGTH) {
|
||||
int startPosition = in.position();
|
||||
while (hasNext(in, member, startPosition, contentLength, first)) {
|
||||
R itemReader = getItemReader(in, member, first);
|
||||
if (itemReader == null) {
|
||||
if (itemReader == null) { // 元素读取完毕
|
||||
break;
|
||||
}
|
||||
result.add(readMemberValue(itemReader, member, localdecoder, first));
|
||||
result.add(readMemberValue(itemReader, member, localDecoder, first));
|
||||
first = false;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
result.add(localdecoder.convertFrom(in));
|
||||
result.add(localDecoder.convertFrom(in));
|
||||
}
|
||||
}
|
||||
in.readArrayE();
|
||||
|
||||
@@ -9,28 +9,22 @@ import java.lang.reflect.Type;
|
||||
import org.redkale.convert.*;
|
||||
|
||||
/**
|
||||
* 非基本类型的数组反序列化
|
||||
*
|
||||
* @author zhangjx
|
||||
* @param <T> T
|
||||
*/
|
||||
public class ProtobufArrayDecoder<T> extends ArrayDecoder<ProtobufReader, T> {
|
||||
|
||||
protected final boolean simple;
|
||||
|
||||
private final boolean string;
|
||||
|
||||
private final boolean enumtostring;
|
||||
protected final boolean componentSimpled;
|
||||
|
||||
public ProtobufArrayDecoder(ProtobufFactory factory, Type type) {
|
||||
super(factory, type);
|
||||
this.enumtostring = factory.enumtostring;
|
||||
Type comtype = this.getComponentType();
|
||||
this.string = String.class == comtype;
|
||||
this.simple = ProtobufFactory.isNoLenBytesType(comtype);
|
||||
this.componentSimpled = getComponentDecoder() instanceof SimpledCoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProtobufReader getItemReader(ProtobufReader in, DeMember member, boolean first) {
|
||||
if (simple) return in;
|
||||
return ProtobufFactory.getItemReader(string, simple, in, member, enumtostring, first);
|
||||
return ProtobufFactory.getItemReader(in, member, componentSimpled, first);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
*/
|
||||
package org.redkale.convert.pb;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.*;
|
||||
import java.util.stream.Stream;
|
||||
import org.redkale.convert.SimpledCoder;
|
||||
import org.redkale.util.*;
|
||||
|
||||
@@ -14,7 +15,9 @@ import org.redkale.util.*;
|
||||
* @author zhangjx
|
||||
*/
|
||||
public abstract class ProtobufCoders {
|
||||
|
||||
|
||||
private static final Creator<List> LIST_CREATOR = Creator.load(List.class);
|
||||
|
||||
private ProtobufCoders() {
|
||||
// do nothing
|
||||
}
|
||||
@@ -468,4 +471,208 @@ public abstract class ProtobufCoders {
|
||||
return in.readDoubles(creator);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProtobufAtomicIntegerCollectionSimpledCoder
|
||||
extends SimpledCoder<ProtobufReader, ProtobufWriter, Collection<AtomicInteger>>
|
||||
implements ProtobufPrimitivable {
|
||||
|
||||
private final Creator<? extends Collection> creator;
|
||||
|
||||
public ProtobufAtomicIntegerCollectionSimpledCoder(Creator<? extends Collection> creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertTo(ProtobufWriter out, Collection<AtomicInteger> values) {
|
||||
out.writeAtomicIntegers(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<AtomicInteger> convertFrom(ProtobufReader in) {
|
||||
return in.readAtomicIntegers(creator);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProtobufAtomicLongCollectionSimpledCoder
|
||||
extends SimpledCoder<ProtobufReader, ProtobufWriter, Collection<AtomicLong>>
|
||||
implements ProtobufPrimitivable {
|
||||
|
||||
private final Creator<? extends Collection> creator;
|
||||
|
||||
public ProtobufAtomicLongCollectionSimpledCoder(Creator<? extends Collection> creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertTo(ProtobufWriter out, Collection<AtomicLong> values) {
|
||||
out.writeAtomicLongs(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<AtomicLong> convertFrom(ProtobufReader in) {
|
||||
return in.readAtomicLongs(creator);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProtobufBoolStreamSimpledCoder
|
||||
extends SimpledCoder<ProtobufReader, ProtobufWriter, Stream<Boolean>> implements ProtobufPrimitivable {
|
||||
|
||||
public static final ProtobufBoolStreamSimpledCoder instance = new ProtobufBoolStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
public void convertTo(ProtobufWriter out, Stream<Boolean> values) {
|
||||
out.writeBools(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Boolean> convertFrom(ProtobufReader in) {
|
||||
return in.readBools(LIST_CREATOR).stream();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProtobufByteStreamSimpledCoder
|
||||
extends SimpledCoder<ProtobufReader, ProtobufWriter, Stream<Byte>> implements ProtobufPrimitivable {
|
||||
|
||||
public static final ProtobufByteStreamSimpledCoder instance = new ProtobufByteStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
public void convertTo(ProtobufWriter out, Stream<Byte> values) {
|
||||
out.writeBytes(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Byte> convertFrom(ProtobufReader in) {
|
||||
return in.readBytes(LIST_CREATOR).stream();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProtobufCharStreamSimpledCoder
|
||||
extends SimpledCoder<ProtobufReader, ProtobufWriter, Stream<Character>> implements ProtobufPrimitivable {
|
||||
|
||||
public static final ProtobufCharStreamSimpledCoder instance = new ProtobufCharStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
public void convertTo(ProtobufWriter out, Stream<Character> values) {
|
||||
out.writeChars(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Character> convertFrom(ProtobufReader in) {
|
||||
return in.readChars(LIST_CREATOR).stream();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProtobufShortStreamSimpledCoder
|
||||
extends SimpledCoder<ProtobufReader, ProtobufWriter, Stream<Short>> implements ProtobufPrimitivable {
|
||||
|
||||
public static final ProtobufShortStreamSimpledCoder instance = new ProtobufShortStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
public void convertTo(ProtobufWriter out, Stream<Short> values) {
|
||||
out.writeShorts(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Short> convertFrom(ProtobufReader in) {
|
||||
return in.readShorts(LIST_CREATOR).stream();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProtobufIntStreamSimpledCoder
|
||||
extends SimpledCoder<ProtobufReader, ProtobufWriter, Stream<Integer>> implements ProtobufPrimitivable {
|
||||
|
||||
public static final ProtobufIntStreamSimpledCoder instance = new ProtobufIntStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
public void convertTo(ProtobufWriter out, Stream<Integer> values) {
|
||||
out.writeInts(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Integer> convertFrom(ProtobufReader in) {
|
||||
return in.readInts(LIST_CREATOR).stream();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProtobufFloatStreamSimpledCoder
|
||||
extends SimpledCoder<ProtobufReader, ProtobufWriter, Stream<Float>> implements ProtobufPrimitivable {
|
||||
|
||||
public static final ProtobufFloatStreamSimpledCoder instance = new ProtobufFloatStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
public void convertTo(ProtobufWriter out, Stream<Float> values) {
|
||||
out.writeFloats(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Float> convertFrom(ProtobufReader in) {
|
||||
return in.readFloats(LIST_CREATOR).stream();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProtobufLongStreamSimpledCoder
|
||||
extends SimpledCoder<ProtobufReader, ProtobufWriter, Stream<Long>> implements ProtobufPrimitivable {
|
||||
|
||||
public static final ProtobufLongStreamSimpledCoder instance = new ProtobufLongStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
public void convertTo(ProtobufWriter out, Stream<Long> values) {
|
||||
out.writeLongs(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Long> convertFrom(ProtobufReader in) {
|
||||
return in.readLongs(LIST_CREATOR).stream();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProtobufDoubleStreamSimpledCoder
|
||||
extends SimpledCoder<ProtobufReader, ProtobufWriter, Stream<Double>> implements ProtobufPrimitivable {
|
||||
|
||||
public static final ProtobufDoubleStreamSimpledCoder instance = new ProtobufDoubleStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
public void convertTo(ProtobufWriter out, Stream<Double> values) {
|
||||
out.writeDoubles(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Double> convertFrom(ProtobufReader in) {
|
||||
return in.readDoubles(LIST_CREATOR).stream();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProtobufAtomicIntegerStreamSimpledCoder
|
||||
extends SimpledCoder<ProtobufReader, ProtobufWriter, Stream<AtomicInteger>>
|
||||
implements ProtobufPrimitivable {
|
||||
|
||||
public static final ProtobufAtomicIntegerStreamSimpledCoder instance =
|
||||
new ProtobufAtomicIntegerStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
public void convertTo(ProtobufWriter out, Stream<AtomicInteger> values) {
|
||||
out.writeAtomicIntegers(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<AtomicInteger> convertFrom(ProtobufReader in) {
|
||||
return in.readAtomicIntegers(LIST_CREATOR).stream();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProtobufAtomicLongStreamSimpledCoder
|
||||
extends SimpledCoder<ProtobufReader, ProtobufWriter, Stream<AtomicLong>> implements ProtobufPrimitivable {
|
||||
|
||||
public static final ProtobufAtomicLongStreamSimpledCoder instance = new ProtobufAtomicLongStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
public void convertTo(ProtobufWriter out, Stream<AtomicLong> values) {
|
||||
out.writeAtomicLongs(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<AtomicLong> convertFrom(ProtobufReader in) {
|
||||
return in.readAtomicLongs(LIST_CREATOR).stream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,23 +14,15 @@ import org.redkale.convert.*;
|
||||
*/
|
||||
public class ProtobufCollectionDecoder<T> extends CollectionDecoder<ProtobufReader, T> {
|
||||
|
||||
protected final boolean simple;
|
||||
|
||||
private final boolean string;
|
||||
|
||||
private final boolean enumtostring;
|
||||
protected final boolean componentSimpled;
|
||||
|
||||
public ProtobufCollectionDecoder(ProtobufFactory factory, Type type) {
|
||||
super(factory, type);
|
||||
this.enumtostring = factory.enumtostring;
|
||||
Type comtype = this.getComponentType();
|
||||
this.string = String.class == comtype;
|
||||
this.simple = ProtobufFactory.isNoLenBytesType(comtype);
|
||||
this.componentSimpled = getComponentDecoder() instanceof SimpledCoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProtobufReader getItemReader(ProtobufReader in, DeMember member, boolean first) {
|
||||
if (simple) return in;
|
||||
return ProtobufFactory.getItemReader(string, simple, in, member, enumtostring, first);
|
||||
return ProtobufFactory.getItemReader(in, member, componentSimpled, first);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,11 +57,11 @@ public class ProtobufEnumSimpledCoder<R extends ProtobufReader, W extends Protob
|
||||
public E convertFrom(final R in) {
|
||||
if (enumtostring) {
|
||||
String value = in.readSmallString();
|
||||
if (value == null) return null;
|
||||
return (E) Enum.valueOf((Class<E>) type, value);
|
||||
return value == null ? null : (E) Enum.valueOf((Class<E>) type, value);
|
||||
} else {
|
||||
int value = in.readRawVarint32();
|
||||
return values.get(value);
|
||||
}
|
||||
int value = ((ProtobufReader) in).readRawVarint32();
|
||||
return values.get(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -12,30 +12,42 @@ import java.util.concurrent.atomic.*;
|
||||
import java.util.stream.Stream;
|
||||
import org.redkale.convert.*;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufAtomicIntegerArraySimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufAtomicIntegerCollectionSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufAtomicIntegerStreamSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufAtomicLongArraySimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufAtomicLongCollectionSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufAtomicLongStreamSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufBoolArraySimpledCoder2;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufBoolCollectionSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufBoolStreamSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufByteArraySimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufByteArraySimpledCoder2;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufByteCollectionSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufByteStreamSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufCharArraySimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufCharArraySimpledCoder2;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufCharCollectionSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufCharStreamSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufDoubleArraySimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufDoubleArraySimpledCoder2;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufDoubleCollectionSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufDoubleStreamSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufFloatArraySimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufFloatArraySimpledCoder2;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufFloatCollectionSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufFloatStreamSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufIntArraySimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufIntArraySimpledCoder2;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufIntCollectionSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufIntStreamSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufLongArraySimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufLongArraySimpledCoder2;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufLongCollectionSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufLongStreamSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufShortArraySimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufShortArraySimpledCoder2;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufShortCollectionSimpledCoder;
|
||||
import org.redkale.convert.pb.ProtobufCoders.ProtobufShortStreamSimpledCoder;
|
||||
import org.redkale.util.*;
|
||||
|
||||
/** @author zhangjx */
|
||||
@@ -202,6 +214,12 @@ public class ProtobufFactory extends ConvertFactory<ProtobufReader, ProtobufWrit
|
||||
} else if (componentType == Double.class) {
|
||||
Creator<? extends Collection> creator = loadCreator((Class) pt.getRawType());
|
||||
return (Decodeable) new ProtobufDoubleCollectionSimpledCoder(creator);
|
||||
} else if (componentType == AtomicInteger.class) {
|
||||
Creator<? extends Collection> creator = loadCreator((Class) pt.getRawType());
|
||||
return (Decodeable) new ProtobufAtomicIntegerCollectionSimpledCoder(creator);
|
||||
} else if (componentType == AtomicLong.class) {
|
||||
Creator<? extends Collection> creator = loadCreator((Class) pt.getRawType());
|
||||
return (Decodeable) new ProtobufAtomicLongCollectionSimpledCoder(creator);
|
||||
}
|
||||
}
|
||||
return new ProtobufCollectionDecoder(this, type);
|
||||
@@ -214,6 +232,31 @@ public class ProtobufFactory extends ConvertFactory<ProtobufReader, ProtobufWrit
|
||||
|
||||
@Override
|
||||
protected <E> Decodeable<ProtobufReader, E> createStreamDecoder(Type type) {
|
||||
if (type instanceof ParameterizedType) {
|
||||
ParameterizedType pt = (ParameterizedType) type;
|
||||
Type componentType = pt.getActualTypeArguments()[0];
|
||||
if (componentType == Boolean.class) {
|
||||
return (Decodeable) ProtobufBoolStreamSimpledCoder.instance;
|
||||
} else if (componentType == Byte.class) {
|
||||
return (Decodeable) ProtobufByteStreamSimpledCoder.instance;
|
||||
} else if (componentType == Character.class) {
|
||||
return (Decodeable) ProtobufCharStreamSimpledCoder.instance;
|
||||
} else if (componentType == Short.class) {
|
||||
return (Decodeable) ProtobufShortStreamSimpledCoder.instance;
|
||||
} else if (componentType == Integer.class) {
|
||||
return (Decodeable) ProtobufIntStreamSimpledCoder.instance;
|
||||
} else if (componentType == Float.class) {
|
||||
return (Decodeable) ProtobufFloatStreamSimpledCoder.instance;
|
||||
} else if (componentType == Long.class) {
|
||||
return (Decodeable) ProtobufLongStreamSimpledCoder.instance;
|
||||
} else if (componentType == Double.class) {
|
||||
return (Decodeable) ProtobufDoubleStreamSimpledCoder.instance;
|
||||
} else if (componentType == AtomicInteger.class) {
|
||||
return (Decodeable) ProtobufAtomicIntegerStreamSimpledCoder.instance;
|
||||
} else if (componentType == AtomicLong.class) {
|
||||
return (Decodeable) ProtobufAtomicLongStreamSimpledCoder.instance;
|
||||
}
|
||||
}
|
||||
return new ProtobufStreamDecoder(this, type);
|
||||
}
|
||||
|
||||
@@ -260,14 +303,13 @@ public class ProtobufFactory extends ConvertFactory<ProtobufReader, ProtobufWrit
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static ProtobufReader getItemReader(
|
||||
boolean string, boolean simple, ProtobufReader in, DeMember member, boolean enumtostring, boolean first) {
|
||||
if (string) {
|
||||
protected static ProtobufReader getItemReader(ProtobufReader in, DeMember member, boolean simpled, boolean first) {
|
||||
if (simpled) {
|
||||
if (member == null || first) {
|
||||
return in;
|
||||
}
|
||||
int tag = in.readTag();
|
||||
if (tag != member.getTag()) {
|
||||
if (tag != member.getTag()) { // 元素结束
|
||||
in.backTag(tag);
|
||||
return null;
|
||||
}
|
||||
@@ -275,7 +317,7 @@ public class ProtobufFactory extends ConvertFactory<ProtobufReader, ProtobufWrit
|
||||
} else {
|
||||
if (!first && member != null) {
|
||||
int tag = in.readTag();
|
||||
if (tag != member.getTag()) {
|
||||
if (tag != member.getTag()) { // 元素结束
|
||||
in.backTag(tag);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@ package org.redkale.convert.pb;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import org.redkale.convert.*;
|
||||
import org.redkale.util.Attribute;
|
||||
import org.redkale.util.Utility;
|
||||
import org.redkale.util.*;
|
||||
|
||||
/**
|
||||
* @author zhangjx
|
||||
@@ -48,7 +47,7 @@ public class ProtobufObjectDecoder<T> extends ObjectDecoder<ProtobufReader, T> {
|
||||
protected Object readDeMemberValue(ProtobufReader in, DeMember member, boolean first) {
|
||||
Decodeable decoder = member.getDecoder();
|
||||
if (decoder instanceof TagDecodeable) {
|
||||
return ((TagDecodeable) decoder).convertFrom(in, member);
|
||||
return member.readByTag(in);
|
||||
} else {
|
||||
return member.read(in);
|
||||
}
|
||||
@@ -58,7 +57,7 @@ public class ProtobufObjectDecoder<T> extends ObjectDecoder<ProtobufReader, T> {
|
||||
protected void readDeMemberValue(ProtobufReader in, DeMember member, T result, boolean first) {
|
||||
Decodeable decoder = member.getDecoder();
|
||||
if (decoder instanceof TagDecodeable) {
|
||||
member.getAttribute().set(result, ((TagDecodeable) decoder).convertFrom(in, member));
|
||||
member.readByTag(in, result);
|
||||
} else {
|
||||
member.read(in, result);
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ package org.redkale.convert.pb;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.*;
|
||||
import org.redkale.convert.*;
|
||||
import org.redkale.util.Creator;
|
||||
|
||||
@@ -177,26 +176,7 @@ public class ProtobufReader extends Reader {
|
||||
if (member == null && decoder == null) {
|
||||
return -1; // 为byte[]
|
||||
}
|
||||
if (member != null) {
|
||||
if (member.getDecoder() instanceof ProtobufArrayDecoder) {
|
||||
ProtobufArrayDecoder pdecoder = (ProtobufArrayDecoder) member.getDecoder();
|
||||
if (pdecoder.simple) {
|
||||
return readRawVarint32();
|
||||
}
|
||||
} else if (member.getDecoder() instanceof ProtobufCollectionDecoder) {
|
||||
ProtobufCollectionDecoder pdecoder = (ProtobufCollectionDecoder) member.getDecoder();
|
||||
if (pdecoder.simple) {
|
||||
return readRawVarint32();
|
||||
}
|
||||
} else if (member.getDecoder() instanceof ProtobufStreamDecoder) {
|
||||
ProtobufStreamDecoder pdecoder = (ProtobufStreamDecoder) member.getDecoder();
|
||||
if (pdecoder.simple) {
|
||||
return readRawVarint32();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return readRawVarint32(); // readUInt32
|
||||
return member != null ? -1 : readRawVarint32(); // readUInt32
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -479,7 +459,10 @@ public class ProtobufReader extends Reader {
|
||||
|
||||
@Override
|
||||
public final String readString() {
|
||||
return new String(readByteArray(), StandardCharsets.UTF_8);
|
||||
final int size = readRawVarint32();
|
||||
String val = new String(content, position + 1, size, StandardCharsets.UTF_8);
|
||||
position += size;
|
||||
return val;
|
||||
}
|
||||
|
||||
protected final int readTag() {
|
||||
@@ -499,6 +482,10 @@ public class ProtobufReader extends Reader {
|
||||
return this.content[this.position];
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return (this.position + 1) < this.content.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断对象是否存在下一个属性或者数组是否存在下一个元素
|
||||
*
|
||||
|
||||
@@ -14,23 +14,15 @@ import org.redkale.convert.*;
|
||||
*/
|
||||
public class ProtobufStreamDecoder<T> extends StreamDecoder<ProtobufReader, T> {
|
||||
|
||||
protected final boolean simple;
|
||||
|
||||
private final boolean string;
|
||||
|
||||
private final boolean enumtostring;
|
||||
protected final boolean componentSimpled;
|
||||
|
||||
public ProtobufStreamDecoder(ConvertFactory factory, Type type) {
|
||||
super(factory, type);
|
||||
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
|
||||
Type comtype = this.getComponentType();
|
||||
this.string = String.class == comtype;
|
||||
this.simple = ProtobufFactory.isNoLenBytesType(comtype);
|
||||
this.componentSimpled = getComponentDecoder() instanceof SimpledCoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProtobufReader getItemReader(ProtobufReader in, DeMember member, boolean first) {
|
||||
if (simple) return in;
|
||||
return ProtobufFactory.getItemReader(string, simple, in, member, enumtostring, first);
|
||||
return ProtobufFactory.getItemReader(in, member, componentSimpled, first);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,157 +294,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
||||
|
||||
@Override
|
||||
public int writeArrayB(int size, Encodeable encoder, Encodeable componentEncoder, Object obj) {
|
||||
if (obj == null) {
|
||||
writeNull();
|
||||
return 0;
|
||||
} else if (size < 1) {
|
||||
// writeUInt32(0);
|
||||
return 0;
|
||||
} else if (obj instanceof byte[]) {
|
||||
int length = ((byte[]) obj).length;
|
||||
writeLength(length);
|
||||
writeTo((byte[]) obj);
|
||||
return length;
|
||||
} else {
|
||||
final Class type = obj.getClass();
|
||||
ProtobufWriter tmp = pollChild();
|
||||
if (type == boolean[].class) {
|
||||
for (boolean item : (boolean[]) obj) {
|
||||
tmp.writeBoolean(item);
|
||||
}
|
||||
} else if (type == Boolean[].class) {
|
||||
for (Boolean item : (Boolean[]) obj) {
|
||||
tmp.writeBoolean(item != null && item);
|
||||
}
|
||||
} else if (type == short[].class) {
|
||||
for (short item : (short[]) obj) {
|
||||
tmp.writeShort(item);
|
||||
}
|
||||
} else if (type == Short[].class) {
|
||||
for (Short item : (Short[]) obj) {
|
||||
tmp.writeShort(item == null ? 0 : item);
|
||||
}
|
||||
} else if (type == char[].class) {
|
||||
for (char item : (char[]) obj) {
|
||||
tmp.writeChar(item);
|
||||
}
|
||||
} else if (type == Character[].class) {
|
||||
for (Character item : (Character[]) obj) {
|
||||
tmp.writeChar(item == null ? 0 : item);
|
||||
}
|
||||
} else if (type == int[].class) {
|
||||
for (int item : (int[]) obj) {
|
||||
tmp.writeInt(item);
|
||||
}
|
||||
} else if (type == Integer[].class) {
|
||||
for (Integer item : (Integer[]) obj) {
|
||||
tmp.writeInt(item == null ? 0 : item);
|
||||
}
|
||||
} else if (type == float[].class) {
|
||||
for (float item : (float[]) obj) {
|
||||
tmp.writeFloat(item);
|
||||
}
|
||||
} else if (type == Float[].class) {
|
||||
for (Float item : (Float[]) obj) {
|
||||
tmp.writeFloat(item == null ? 0F : item);
|
||||
}
|
||||
} else if (type == long[].class) {
|
||||
for (long item : (long[]) obj) {
|
||||
tmp.writeLong(item);
|
||||
}
|
||||
} else if (type == Long[].class) {
|
||||
for (Long item : (Long[]) obj) {
|
||||
tmp.writeLong(item == null ? 0L : item);
|
||||
}
|
||||
} else if (type == double[].class) {
|
||||
for (double item : (double[]) obj) {
|
||||
tmp.writeDouble(item);
|
||||
}
|
||||
} else if (type == Double[].class) {
|
||||
for (Double item : (Double[]) obj) {
|
||||
tmp.writeDouble(item == null ? 0D : item);
|
||||
}
|
||||
} else if (type == AtomicInteger[].class) {
|
||||
for (AtomicInteger item : (AtomicInteger[]) obj) {
|
||||
tmp.writeInt(item == null ? 0 : item.get());
|
||||
}
|
||||
} else if (type == AtomicLong[].class) {
|
||||
for (AtomicLong item : (AtomicLong[]) obj) {
|
||||
tmp.writeLong(item == null ? 0L : item.get());
|
||||
}
|
||||
} else if (encoder instanceof ProtobufCollectionDecoder) {
|
||||
ProtobufCollectionDecoder listEncoder = (ProtobufCollectionDecoder) encoder;
|
||||
Type componentType = listEncoder.getComponentType();
|
||||
if (listEncoder.simple) {
|
||||
if (componentType == Boolean.class) {
|
||||
for (Boolean item : (Collection<Boolean>) obj) {
|
||||
tmp.writeBoolean(item);
|
||||
}
|
||||
} else if (componentType == Short.class) {
|
||||
for (Short item : (Collection<Short>) obj) {
|
||||
tmp.writeShort(item);
|
||||
}
|
||||
} else if (componentType == Integer.class) {
|
||||
for (Integer item : (Collection<Integer>) obj) {
|
||||
tmp.writeInt(item);
|
||||
}
|
||||
} else if (componentType == Float.class) {
|
||||
for (Float item : (Collection<Float>) obj) {
|
||||
tmp.writeFloat(item);
|
||||
}
|
||||
} else if (componentType == Long.class) {
|
||||
for (Long item : (Collection<Long>) obj) {
|
||||
tmp.writeLong(item);
|
||||
}
|
||||
} else if (componentType == Double.class) {
|
||||
for (Double item : (Collection<Double>) obj) {
|
||||
tmp.writeDouble(item);
|
||||
}
|
||||
} else if (componentType == AtomicInteger.class) {
|
||||
for (AtomicInteger item : (Collection<AtomicInteger>) obj) {
|
||||
tmp.writeInt(item == null ? 0 : item.get());
|
||||
}
|
||||
} else if (componentType == AtomicLong.class) {
|
||||
for (AtomicLong item : (Collection<AtomicLong>) obj) {
|
||||
tmp.writeLong(item == null ? 0L : item.get());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else if (encoder instanceof ProtobufStreamDecoder) {
|
||||
ProtobufStreamDecoder streamEncoder = (ProtobufStreamDecoder) encoder;
|
||||
Type componentType = streamEncoder.getComponentType();
|
||||
if (streamEncoder.simple) {
|
||||
if (componentType == Boolean.class) {
|
||||
((Stream<Boolean>) obj).forEach(tmp::writeBoolean);
|
||||
} else if (componentType == Short.class) {
|
||||
((Stream<Short>) obj).forEach(tmp::writeShort);
|
||||
} else if (componentType == Integer.class) {
|
||||
((Stream<Integer>) obj).forEach(tmp::writeInt);
|
||||
} else if (componentType == Float.class) {
|
||||
((Stream<Float>) obj).forEach(tmp::writeFloat);
|
||||
} else if (componentType == Long.class) {
|
||||
((Stream<Long>) obj).forEach(tmp::writeLong);
|
||||
} else if (componentType == Double.class) {
|
||||
((Stream<Double>) obj).forEach(tmp::writeDouble);
|
||||
} else if (componentType == AtomicInteger.class) {
|
||||
((Stream<AtomicInteger>) obj).forEach(item -> tmp.writeInt(item == null ? 0 : item.get()));
|
||||
} else if (componentType == AtomicLong.class) {
|
||||
((Stream<AtomicLong>) obj).forEach(item -> tmp.writeLong(item == null ? 0L : item.get()));
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
int length = tmp.count();
|
||||
writeLength(length);
|
||||
writeTo(tmp.toArray());
|
||||
offerChild(tmp);
|
||||
return length;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -609,6 +459,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBools(Stream<Boolean> value) {
|
||||
if (value != null) {
|
||||
writeBools(value.toArray(s -> new Boolean[s]));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBytes(byte[] value) {
|
||||
byte[] array = value;
|
||||
if (array != null && array.length > 0) {
|
||||
@@ -637,6 +493,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBytes(Stream<Byte> value) {
|
||||
if (value != null) {
|
||||
writeBytes(value.toArray(s -> new Byte[s]));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeChars(char[] value) {
|
||||
char[] array = value;
|
||||
if (array != null && array.length > 0) {
|
||||
@@ -679,6 +541,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeChars(Stream<Character> value) {
|
||||
if (value != null) {
|
||||
writeChars(value.toArray(s -> new Character[s]));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeShorts(short[] value) {
|
||||
short[] array = value;
|
||||
if (array != null && array.length > 0) {
|
||||
@@ -721,6 +589,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeShorts(Stream<Short> value) {
|
||||
if (value != null) {
|
||||
writeShorts(value.toArray(s -> new Short[s]));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeInts(int[] value) {
|
||||
int[] array = value;
|
||||
if (array != null && array.length > 0) {
|
||||
@@ -763,6 +637,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeInts(Stream<Integer> value) {
|
||||
if (value != null) {
|
||||
writeInts(value.toArray(s -> new Integer[s]));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeFloats(float[] value) {
|
||||
float[] array = value;
|
||||
if (array != null && array.length > 0) {
|
||||
@@ -796,6 +676,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeFloats(Stream<Float> value) {
|
||||
if (value != null) {
|
||||
writeFloats(value.toArray(s -> new Float[s]));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeLongs(long[] value) {
|
||||
long[] array = value;
|
||||
if (array != null && array.length > 0) {
|
||||
@@ -838,6 +724,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeLongs(Stream<Long> value) {
|
||||
if (value != null) {
|
||||
writeLongs(value.toArray(s -> new Long[s]));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeDoubles(double[] value) {
|
||||
double[] array = value;
|
||||
if (array != null && array.length > 0) {
|
||||
@@ -871,6 +763,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeDoubles(Stream<Double> value) {
|
||||
if (value != null) {
|
||||
writeDoubles(value.toArray(s -> new Double[s]));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeAtomicIntegers(AtomicInteger[] value) {
|
||||
AtomicInteger[] array = value;
|
||||
if (array != null && array.length > 0) {
|
||||
@@ -899,6 +797,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeAtomicIntegers(Stream<AtomicInteger> value) {
|
||||
if (value != null) {
|
||||
writeAtomicIntegers(value.toArray(s -> new AtomicInteger[s]));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeAtomicLongs(AtomicLong[] value) {
|
||||
AtomicLong[] array = value;
|
||||
if (array != null && array.length > 0) {
|
||||
@@ -927,6 +831,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeAtomicLongs(Stream<AtomicLong> value) {
|
||||
if (value != null) {
|
||||
writeAtomicLongs(value.toArray(s -> new AtomicLong[s]));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeWrapper(StringWrapper value) {
|
||||
if (value != null) {
|
||||
@@ -1407,92 +1317,20 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
if (tiny()) {
|
||||
if (member.isStringType()) {
|
||||
if (((CharSequence) value).length() == 0) {
|
||||
return;
|
||||
}
|
||||
} else if (member.isBoolType()) {
|
||||
if (!((Boolean) value)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Type mtype = member.getAttribute().type();
|
||||
if (mtype == boolean[].class && ((boolean[]) value).length < 1) {
|
||||
return;
|
||||
}
|
||||
if (mtype == byte[].class && ((byte[]) value).length < 1) {
|
||||
return;
|
||||
}
|
||||
if (mtype == short[].class && ((short[]) value).length < 1) {
|
||||
return;
|
||||
}
|
||||
if (mtype == char[].class && ((char[]) value).length < 1) {
|
||||
return;
|
||||
}
|
||||
if (mtype == int[].class && ((int[]) value).length < 1) {
|
||||
return;
|
||||
}
|
||||
if (mtype == float[].class && ((float[]) value).length < 1) {
|
||||
return;
|
||||
}
|
||||
if (mtype == long[].class && ((long[]) value).length < 1) {
|
||||
return;
|
||||
}
|
||||
if (mtype == double[].class && ((double[]) value).length < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Encodeable encoder = member.getEncoder();
|
||||
if (encoder == null) {
|
||||
return;
|
||||
}
|
||||
if (encoder instanceof MapEncoder) {
|
||||
if (!((Map) value).isEmpty()) {
|
||||
((MapEncoder) encoder).convertTo(this, member, (Map) value);
|
||||
}
|
||||
} else if (encoder instanceof ProtobufArrayEncoder) {
|
||||
ProtobufArrayEncoder arrayEncoder = (ProtobufArrayEncoder) encoder;
|
||||
if (arrayEncoder.simple) {
|
||||
if (((Object[]) value).length < 1) {
|
||||
this.writeFieldName(member);
|
||||
ProtobufWriter tmp = pollChild();
|
||||
arrayEncoder.convertTo(tmp, member, (Object[]) value);
|
||||
// int length = tmp.count();
|
||||
// this.writeUInt32(length);
|
||||
this.writeTo(tmp.toArray());
|
||||
offerChild(tmp);
|
||||
}
|
||||
} else {
|
||||
arrayEncoder.convertTo(this, member, (Object[]) value);
|
||||
}
|
||||
arrayEncoder.convertTo(this, member, (Object[]) value);
|
||||
} else if (encoder instanceof ProtobufCollectionEncoder) {
|
||||
ProtobufCollectionEncoder collectionEncoder = (ProtobufCollectionEncoder) encoder;
|
||||
if (collectionEncoder.simple) {
|
||||
if (!((Collection) value).isEmpty()) {
|
||||
this.writeFieldName(member);
|
||||
ProtobufWriter tmp = pollChild();
|
||||
collectionEncoder.convertTo(tmp, member, (Collection) value);
|
||||
this.writeLength(tmp.count());
|
||||
this.writeTo(tmp.toArray());
|
||||
offerChild(tmp);
|
||||
}
|
||||
} else {
|
||||
collectionEncoder.convertTo(this, member, (Collection) value);
|
||||
}
|
||||
collectionEncoder.convertTo(this, member, (Collection) value);
|
||||
} else if (encoder instanceof ProtobufStreamEncoder) {
|
||||
ProtobufStreamEncoder streamEncoder = (ProtobufStreamEncoder) encoder;
|
||||
if (streamEncoder.simple) {
|
||||
this.writeFieldName(member);
|
||||
ProtobufWriter tmp = pollChild();
|
||||
streamEncoder.convertTo(tmp, member, (Stream) value);
|
||||
this.writeLength(tmp.count());
|
||||
this.writeTo(tmp.toArray());
|
||||
offerChild(tmp);
|
||||
} else {
|
||||
streamEncoder.convertTo(this, member, (Stream) value);
|
||||
}
|
||||
streamEncoder.convertTo(this, member, (Stream) value);
|
||||
} else {
|
||||
this.writeFieldName(member);
|
||||
encoder.convertTo(this, value);
|
||||
|
||||
Reference in New Issue
Block a user