gu.sql2java.json.BitSetFastjsonCodec Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sql2java-base Show documentation
Show all versions of sql2java-base Show documentation
sql2java common class package
package gu.sql2java.json;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.BitSet;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.JSONLexer;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.alibaba.fastjson.serializer.IntegerCodec;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.LongCodec;
import com.alibaba.fastjson.serializer.ObjectArrayCodec;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.PrimitiveArraySerializer;
import com.alibaba.fastjson.serializer.SerializeWriter;
/**
* {@link BitSet} 的FASTJSON序列化和反序列化实现
* @author guyadong
* @since 3.30.1
*/
public class BitSetFastjsonCodec implements ObjectSerializer, ObjectDeserializer{
public static final BitSetFastjsonCodec INSTANCE = new BitSetFastjsonCodec();
private BitSetSerializeType bitSetSerializeType = BitSetSerializeType.ARRAY;
final ObjectArrayCodec longArrayCodec = new ObjectArrayCodec();
/** 最大bit位限制,大于等于此值的索引位值在序列化和反序列化时被忽略 */
private Integer bitLimit;
public BitSetFastjsonCodec() {
}
public BitSetFastjsonCodec(BitSetSerializeType bitSetSerializeType) {
this.bitSetSerializeType(bitSetSerializeType);
}
public BitSetFastjsonCodec(Integer bitLimit) {
if(null != bitLimit && bitLimit < 0) {
throw new IllegalArgumentException("bitLimit < 0: " + bitLimit);
}
this.bitLimit = bitLimit;
}
/**
* 将索引大于等于length的位清0
* @param bitSet
* @param length
* @return 输入参数为{@code null}返回原值,否则返回清0后的新对象
*/
public static BitSet leftSet(BitSet bitSet,Integer length) {
if(null != bitSet && null != length) {
if(length < bitSet.length()) {
return bitSet.get(0,length);
}
}
return bitSet;
}
@SuppressWarnings({ "unchecked" })
@Override
public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
JSONLexer lexer = parser.lexer;
switch(lexer.token()) {
case JSONToken.NULL:
lexer.nextToken(JSONToken.COMMA);
return null;
case JSONToken.LITERAL_STRING:{
/** 递归 */
String stringLiteral = lexer.stringVal();
DefaultJSONParser _parser = new DefaultJSONParser(stringLiteral, parser.getConfig());
BitSet bitSet = deserialze(_parser, type, fieldName);
lexer.nextToken(JSONToken.COMMA);
return (T) bitSet;
}
case JSONToken.HEX:{
byte[] bytes = lexer.bytesValue();
lexer.nextToken(JSONToken.COMMA);
return (T) leftSet(BitSet.valueOf(bytes), bitLimit);
}
case JSONToken.LBRACKET:{
long[] longs = longArrayCodec.deserialze(parser, long[].class, fieldName);
return (T) leftSet(BitSet.valueOf(longs), bitLimit);
}
case JSONToken.LBRACE:{
lexer.nextToken();
BitSet bitSet = new BitSet();
while(lexer.token() != JSONToken.RBRACE) {
if (lexer.token() == JSONToken.COMMA) {
lexer.nextToken();
continue;
}
Integer bitIndex = IntegerCodec.instance.deserialze(parser, Integer.class, fieldName);
if(null != bitIndex) {
bitSet.set(bitIndex);
}
}
lexer.nextToken(JSONToken.COMMA);
return (T) leftSet(bitSet, bitLimit);
}
default: {
Long value = LongCodec.instance.deserialze(parser, Long.class, fieldName);
return (T) leftSet(BitSet.valueOf(new long[] {value}), bitLimit);
}
}
}
@Override
public int getFastMatchToken() {
return JSONToken.LBRACKET;
}
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
throws IOException {
if (null==object || ! (object instanceof BitSet)) {
serializer.writeNull();
return;
}
SerializeWriter out = serializer.out;
BitSet bitSet = (BitSet)object;
if(null != bitLimit) {
bitSet = leftSet(bitSet, bitLimit);
if(bitLimit <= Long.SIZE) {
out.writeLong(bitSet.toLongArray()[0]);
return;
}
}
switch(bitSetSerializeType) {
case ARRAY:
PrimitiveArraySerializer.instance.write(serializer, bitSet.toLongArray(), fieldName, fieldType, features);
break;
case TO_STRING:
out.write(bitSet.toString());
break;
case HEX:
out.writeHex(bitSet.toByteArray());
break;
default:
throw new UnsupportedOperationException();
}
}
public BitSetFastjsonCodec bitSetSerializeType(BitSetSerializeType bitSetSerializeType) {
if(null != bitSetSerializeType) {
this.bitSetSerializeType = bitSetSerializeType;
}
return this;
}
public static class I8 extends BitSetFastjsonCodec{
public I8() {
super(Byte.SIZE);
}
}
public static class I16 extends BitSetFastjsonCodec{
public I16() {
super(Short.SIZE);
}
}
public static class I32 extends BitSetFastjsonCodec{
public I32() {
super(Integer.SIZE);
}
}
public static class I64 extends BitSetFastjsonCodec{
public I64() {
super(Long.SIZE);
}
}
/**
* {@link BitSet}序列化字符类型
* @author guyadong
*
*/
public enum BitSetSerializeType{
/** []整数数组 */ARRAY,
/** {}包含的整数序列 */TO_STRING,
/** 十六进制字符串 */HEX
}
}