DataType添加类型HEX(十六进制字符串),删除BCD实现,改用Netty中StringUtil

master
剑器近 2021-07-21 09:35:56 +08:00
parent a2f5abb6f4
commit 7c1f0bce6c
9 changed files with 180 additions and 51 deletions

View File

@ -62,7 +62,7 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
<version>4.1.65.Final</version>
<version>4.1.66.Final</version>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@ -19,6 +19,8 @@ public enum DataType {
BYTES(-1),
/** BCD8421码 */
BCD8421(-1),
/** 十六进制字符串 */
HEX(-1),
/** 字符串 */
STRING(-1),
/** 对象 */

View File

@ -14,7 +14,7 @@ import java.util.Map;
*/
public class DefaultLoadStrategy extends LoadStrategy {
private Map<String, Map<Integer, RuntimeSchema<?>>> typeClassMapping = new HashMap(140);
private Map<String, Map<Integer, RuntimeSchema<?>>> typeClassMapping = new HashMap(256);
public DefaultLoadStrategy() {
}

View File

@ -52,6 +52,9 @@ public abstract class FieldFactory {
else
fieldSchema = ArraySchema.ByteArraySchema.INSTANCE;
break;
case HEX:
fieldSchema = StringSchema.HEX.INSTANCE;
break;
case STRING:
fieldSchema = StringSchema.Chars.getInstance(field.pad(), field.charset());
break;

View File

@ -1,8 +1,6 @@
package io.github.yezhihao.protostar;
import io.netty.buffer.ByteBuf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
@ -11,8 +9,6 @@ import org.slf4j.LoggerFactory;
*/
public interface Schema<T> {
Logger log = LoggerFactory.getLogger(Schema.class.getSimpleName());
T readFrom(ByteBuf input);
void writeTo(ByteBuf output, T message);

View File

@ -1,15 +1,20 @@
package io.github.yezhihao.protostar.schema;
import io.github.yezhihao.protostar.Schema;
import io.github.yezhihao.protostar.util.Bcd;
import io.github.yezhihao.protostar.util.Cache;
import io.github.yezhihao.protostar.util.CharsBuilder;
import io.netty.buffer.ByteBuf;
import io.netty.util.internal.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
import java.util.Arrays;
public class StringSchema {
private static final Logger log = LoggerFactory.getLogger(StringSchema.class.getSimpleName());
public static class Chars implements Schema<String> {
private static final Cache<String, Chars> cache = new Cache<>();
@ -65,7 +70,7 @@ public class StringSchema {
output.writeBytes(bytes);
} else if (srcPos < 0) {
output.writeBytes(bytes, -srcPos, length);
log.error("字符长度超出限制: 长度[{}],数据长度[{}],{}", length, bytes.length, value);
log.info("字符长度超出限制: 长度[{}],数据长度[{}],{}", length, bytes.length, value);
} else {
output.writeBytes(bytes);
}
@ -75,7 +80,6 @@ public class StringSchema {
}
}
public static class BCD implements Schema<String> {
public static final Schema INSTANCE = new BCD();
@ -91,12 +95,10 @@ public class StringSchema {
public String readFrom(ByteBuf input, int length) {
byte[] bytes = new byte[length];
input.readBytes(bytes);
char[] chars = Bcd.toChars(bytes);
int i = Bcd.indexOf(chars, '0');
if (i == 0)
return new String(chars);
return new String(chars, i, chars.length - i);
CharsBuilder cb = new CharsBuilder(length << 1);
StringUtil.toHexStringPadded(cb, bytes);
return cb.leftStrip('0');
}
@Override
@ -115,9 +117,53 @@ public class StringSchema {
chars[--i] = '0';
} else {
value.getChars(-i, charLength - i, chars, 0);
log.warn("字符长度超出限制: 长度[{}],[{}]", charLength, value);
log.info("字符长度超出限制: 长度[{}],[{}]", charLength, value);
}
byte[] src = Bcd.from(chars);
byte[] src = StringUtil.decodeHexDump(new CharsBuilder(chars));
output.writeBytes(src);
}
}
public static class HEX implements Schema<String> {
public static final Schema INSTANCE = new HEX();
private HEX() {
}
@Override
public String readFrom(ByteBuf input) {
return readFrom(input, input.readableBytes());
}
@Override
public String readFrom(ByteBuf input, int length) {
byte[] bytes = new byte[length];
input.readBytes(bytes);
CharsBuilder cb = new CharsBuilder(length << 1);
StringUtil.toHexStringPadded(cb, bytes);
return cb.toString();
}
@Override
public void writeTo(ByteBuf output, String value) {
writeTo(output, value.length() >> 1, value);
}
@Override
public void writeTo(ByteBuf output, int length, String value) {
int charLength = length << 1;
char[] chars = new char[charLength];
int i = charLength - value.length();
if (i >= 0) {
value.getChars(0, charLength - i, chars, i);
while (i > 0)
chars[--i] = '0';
} else {
value.getChars(-i, charLength - i, chars, 0);
log.info("字符长度超出限制: 长度[{}],[{}]", charLength, value);
}
byte[] src = StringUtil.decodeHexDump(new CharsBuilder(chars));
output.writeBytes(src);
}
}

View File

@ -17,35 +17,6 @@ public class Bcd {
public static final int YEAR_RANGE = YEAR - 30;
public static final int HUNDRED_YEAR = YEAR_RANGE / 100 * 100;
/** BCD转String */
public static String toString(byte[] bcd) {
return new String(toChars(bcd));
}
/** BCD转char[] */
public static char[] toChars(byte[] bcd) {
char[] chars = new char[bcd.length * 2];
for (int i = 0, j = 0; i < bcd.length; i++) {
chars[j++] = (char) (48 + (bcd[i] >> 4 & 0xf));
chars[j++] = (char) (48 + (bcd[i] & 0xf));
}
return chars;
}
/** String转BCD */
public static byte[] from(String str) {
return from(str.toCharArray());
}
/** char[]转BCD */
public static byte[] from(char[] chars) {
byte[] bcd = new byte[chars.length / 2];
for (int i = 0, j = 0; i < bcd.length; i++) {
bcd[i] = (byte) ((chars[j++] - 48 << 4) | ((chars[j++] - 48 & 0xf)));
}
return bcd;
}
/** 时间转BCD (yyMMddHHmmss) */
public static byte[] from(LocalDateTime dateTime) {
byte[] bcd = new byte[6];
@ -113,10 +84,4 @@ public class Bcd {
public static int num(byte bcd) {
return (bcd >> 4 & 0xf) * 10 + (bcd & 0xf);
}
public static int indexOf(char[] chars, char pad) {
int i = 0, len = chars.length;
while (i < len && chars[i] == pad) i++;
return i;
}
}

View File

@ -0,0 +1,82 @@
package io.github.yezhihao.protostar.util;
import java.util.Arrays;
public class CharsBuilder implements CharSequence, Appendable {
private char[] value;
private int pos;
public CharsBuilder(int length) {
this.value = new char[length];
}
public CharsBuilder(char[] chars) {
this.value = chars;
}
@Override
public Appendable append(CharSequence s) {
return append(s, 0, s.length());
}
@Override
public Appendable append(CharSequence s, int start, int end) {
int len = end - start;
for (int i = start, j = pos; i < end; i++, j++)
value[j] = s.charAt(i);
pos += len;
return this;
}
@Override
public Appendable append(char c) {
value[pos++] = c;
return this;
}
@Override
public char charAt(int index) {
return value[index];
}
@Override
public CharSequence subSequence(int start, int end) {
if (start == end) {
return new CharsBuilder(Math.min(16, value.length));
}
return new CharsBuilder(Arrays.copyOfRange(value, start, end));
}
@Override
public int length() {
return value.length;
}
@Override
public String toString() {
return new String(value);
}
public String leftStrip(char c) {
int i = leftOf(value, c);
return new String(value, i, value.length - i);
}
public String rightStrip(char c) {
int i = rightOf(value, c);
return new String(value, 0, i);
}
public static int leftOf(char[] chars, char pad) {
int i = 0, len = chars.length;
while (i < len && chars[i] == pad) i++;
return i;
}
public static int rightOf(char[] chars, char pad) {
int i = 0, len = chars.length;
while ((i < len) && (chars[len - 1] <= pad)) len--;
return len;
}
}

View File

@ -0,0 +1,35 @@
package io.github.yezhihao.protostar.convert;
import io.github.yezhihao.protostar.PrepareLoadStrategy;
import io.github.yezhihao.protostar.converter.MapConverter;
import io.github.yezhihao.protostar.schema.NumberSchema;
import io.github.yezhihao.protostar.schema.StringSchema;
import io.netty.buffer.ByteBuf;
public class AttributeConverterV2 extends MapConverter<Integer, Object> {
@Override
protected void addSchemas(PrepareLoadStrategy schemaRegistry) {
schemaRegistry
.addSchema(1, NumberSchema.Int32.INSTANCE)
.addSchema(2, StringSchema.Chars.getInstance((byte) 0, "UTF-8"))
.addSchema(3, Attr1.class)
.addSchema(4, Attr2.Schema.INSTANCE);
}
@Override
protected Integer readKey(ByteBuf input) {
return (int) input.readUnsignedByte();
}
@Override
protected void writeKey(ByteBuf output, Integer key) {
output.writeByte(key);
}
@Override
protected int valueSize() {
return 1;
}
}