Code Monkey home page Code Monkey logo

magic-byte's Issues

dynamicSize & dynamicSizeOf 不能在一个类中同时存在吗?

有两点疑问:
1)dynamicSize 是标记动态计算的(总数-其他标记了长度=剩下的,就是它的数据), dynamicSizeOf 是标记从哪个成员上取长度的。它俩应该不冲突的。 我注释了检测,运行后的结果符合我的预期,但是不确定是否存在其他问题。
2)dynamicSize 必须带有 size 属性,然而size会自动裁剪。但是这个动态计算的长度是不固定的,我也不能确定size预设多少,只能将size标记足够大吗?对内存使用有影响吗?

如果 dynamicsizeof 指向的属性名重名了,会导致序列化结果错误

如果我的属性和内部类属性都有一个叫 length 的字段,在使用的时候就会导致序列化的时候只序列化了 length 字段,他标记的字段就不会被序列化
代码示例如下:

@MagicClass
class A {

@MagicField(order = 1)
private int length;

@MagicField(order = 2, dynamicSizeOf = "length")
private String value;

@MagicField(order = 3)
private int dataLength;

@MagicField(order = 4, dynamicSizeOf = "dataLength")
private List<B> data;

@MagicClass
public static class B {

@MagicField(order = 1)
private int length;

@MagicField(order = 2, dynamicSizeOf = "length")
private byte[] data;
}

}

这个在 2.4.0 之前的实现是不会出问题的,换成 2.4.0 之后才出的问题。导致我序列化的时候 length 序列化完了就直接跳到 dataLength 了(但是 length 的值是对的),没有序列化 value 的内容,当我把两个 length 属性的名字改成不一样的之后问题就解决了

希望增加时间类的序列化支持

增加对时间类:Date、Instant、LocalDate、LocalTime、LocalDateTime等的支持,默认按照 yyyy-MM-dd HH:mm:ss 格式及长度转换数据,或者根据指定的时间格式转换对应的值,也可以自己设定长度。同时除了这种方式还可以指定按照 int 或者 long 直接将时间转为秒或者毫秒的方式转换

支持“yyyy-MM-dd HH:mm:ss” 等格式的时间转换

由于协议比较老,部分地方使用的还是 yyyy-MM-dd HH:mm:ss 格式的字符串传的时间信息,而不是使用的秒数,所以希望可以以字符串的形式支持这种格式的时间和二进制之间的转换。也可以将这种转换提供为默认的实现了 MConverter 接口的自定义转换类的方式提供支持

针对 dynamicSize & dynamicSizeOf 不能在一个类中同时存在,做的修订,不确定是否存在隐藏问题

在 CollectionReader.java 文件,readFormBuffer 方法中,

if(TypeEnum.LIST == this.fieldMetaInfo.getType()) {
long allocSize = count * fieldMetaInfo.getGenericsField().getElementBytes();
ExceptionUtil.throwIFOOM(allocSize, fieldMetaInfo.getGenericsField().getFullName());

        //FIXME : 取消了count
        //List<Object> list = new ArrayList<>(count);
        List<Object> list = new ArrayList<>();

        for(int i=0; i<count; i++) {

            //FIXME 添加了if判断,尝试解决如下问题:
            //FIXME 针对List<T> dySize = true,  并且T中含有dySizeOf的问题
            //FIXME 针对 类下同时存在  ArrayList<Byte> dySizeOf 和  List<T> dySize = true, order=最后  的问题
            //TODO 需要构建大量的测试类...
            //TODO 需要测试 Size 过大 或者 过小问题
            //目前简单测试无问题
            //<1> 注释掉dySize 和 dySizeOf同时存在的检测
            //<2>
            //T中包含dySizeOf且没有计算,导致T.length长度偏小
            //suffixBytes 好像永远是0 或者小于0?,故导致fillBytes偏大或者正常
            //故fillBytes/T.length 计算出来的count偏大,但是buffer的读取有效数据是不变的
            //故根据buffer是否存在有效数据,跳出循环; 否则在List中会返回很多空T
            if(buffer.capacity() - buffer.position() <= 0) break;

            list.add( fieldMetaInfo.getGenericsField().getReader().readFormBuffer(buffer, entity));
        }

        return list;
    }

经过简单测试,序列化和反序列化 没有问题。因为没有全部翻阅内部处理流程, 就得作者从代码流程处理的角度考虑了。

建议 dynamicSizeOf 支持表达式

原先只考虑过长度是另一个属性的情况,所以直接指定对应的 order 即可拿到长度,但是如果长度被封在了一个 bean 里,那么直接指定 order 是那个封装的对象,长度在封装的对象里里面,也就没法取了

异常栈无法看出报错位置

目前的异常栈在报错的时候只会打印一个报错信息,如果是配置序列化没配对的情况则无法看到具体序列化或者反序列化到哪个类的哪个属性的时候出现的问题

自定义序列化器 对于 属性List<> 不会触发

@MagicClass
public class Staff4 {
@magicfield(order = 1)
private int id;
@magicfield(order = 2, calcLength = true)
private int length;
@MagicConverter(converter = CustomBook3Converter.class, attachParams = "1")
@magicfield(order = 5, size = 2)
private List book; // 序列化器 不会触发
@MagicConverter(converter = CustomBook3Converter.class, attachParams = "2")
@magicfield(order = 7, size = 2)
private List book2; // 如果定义改为 private Book3 book2; 则序列化器会触发。
@magicfield(order = 14, size = 4)
private String name;

ClassParser

Hello Ray,

I have some doubt about the line 94 of the ClassParser
dynamicRef.setDynamicRef(fieldMetaInfo);
why do you set the dynamicRef to the fieldMetaInfo ?

dynamicSize & dynamicSizeOf only use one in the class

class A {
/**
* size 必须设置,为了保险起见,默认给了100个数量,应该够了...
* 没有长度标识,只能动态计算,剩下的就是它
/
@magicfield(order = 4, size = 100, dynamicSize = true) //动态长度,从数据中获取...
protected List《B》 list;
}
class B{
/
*
* 值长度,将值转化为byte[]后的值长度...即:value.size()
*/
@magicfield(order = 2)
private int len;

/**
 * 真实数据
 * 需要自行将数据格式转为byte..
 */
@MagicField(order = 3, dynamicSizeOf = 2)
private ArrayList<Byte> value;

}
这种情况下,只能将B改为Byte,然后每次都得分为多次进行编解码吗?或者写很多自定义序列化器?
因为 Class B 有很多种定义 。

对不同版本协议的支持

  1. 可能项目需要兼容多个版本的协议,不同版本间的字段不相同,但是目前的状态一个类无法根据版本选择性的对类中的一部分属性进行序列化,希望可以增加
  2. 除此之外某些版本不支持的属性也希望可以配置默认值在反序列化之后自动就有值了

如何支持二维的数组呢 ,就是吧这样的二维的数据 怎么放入

 如何支持二维的数组呢  ,就是吧这样的二维的数据 怎么放入

@magicfield(order = 15, size = 4)
private List<List> param = List.of(
List.of(new UserInfo(), new UserInfo()),
List.of(new UserInfo(), new UserInfo()),
List.of(new UserInfo(), new UserInfo()),
List.of(new UserInfo(), new UserInfo())
);

@MagicClass(byteOrder = ByteOrder.LITTLE_ENDIAN)
@DaTa
public static class UserInfo {

    @MagicField(order = 7)
    private short name;

    @MagicField(order = 9)
    private byte age;

}

 如何支持二维的数组呢  ,就是吧这样的二维的数据 怎么放入

 [
  [{"name":"t","age":1},{"name":"t","age":1}],
  [{"name":"t","age":1},{"name":"t","age":1}],
  [{"name":"t","age":1},{"name":"t","age":1}]

]

序列化时 dynamicSizeOf 对应属性值与数组、列表长度不一致时能通过检查无 warn 警告或抛出异常

    @MagicField(order = 1)
    private int teacherLength;

    @MagicField(order = 2, dynamicSizeOf = 1)
    private Teacher[] teacher;

    @MagicField(order = 3)
    private int studentLength;

    @MagicField(order = 4, dynamicSizeOf = 3)
    private List<Student> studentList;

    public static List<Classes> build(int count) {
        List<Classes> classes = new ArrayList<>();
        for (int i = 0; i <count; i++) {
            Classes classes1 = new Classes();
            classes1.setTeacher(Teacher.build(2).toArray(new Teacher[1]));
            classes1.setStudentList(Student.build(2));
            classes1.setStudentLength(0);
            classes1.setTeacherLength(0);
            classes.add(classes1);
        }
        return classes;
    }

teacherLength studentLength 强制赋值为 0,序列化结果
image
符合预期,但是序列化的过程中没有提示这里有不一致的情况或者抛出异常,不便于在实际使用时定位问题

BUG:子类继承父类的时候序列化结果为空数组

@MagicClass
public class ParentClassA {

    @MagicField(order = 1)
    private int number;

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
}

@MagicClass
public class ChildClassA extends ParentClassA {

}

    /**
     * 测试constom converter 配置 dynamicsize 使用
     *
     * @throws ParseException
     */
    @Test
    public void testCustomConverterOfDynamicSize() throws ParseException {
        ChildClassA classA = new ChildClassA();
        classA.setNumber(1);

        byte[] data = MagicByte.unpackToByte(classA);
        Assert.assertEquals(4, data.length);

    }

java.lang.AssertionError:
预期:4
实际:0
<点击以查看差异>

使用日志门面代替控制台打印

e.printStackTrace() 只能输出到控制台,没法通过日志门面向各个日志框架写到日志文件中。我感觉 lombok 可以不引入,slf4j 的的引入并不会造成太大的影响,而且 slf4j 属于日志门面,适配各个日志框架,灵活性要更高一些,引入之后也不会对项目造成影响。而且,一般做项目大多数都是搭配日志框架输出的,很少直接用控制台输出的,这样定位问题也不方便。

动态嵌套对象的序列化和反序列化

根据我需要,我分数据头和数据体两部分,头的格式是固定的,数据体根据也不同结构也不一样,我能否直接通过仅在一个对象里封装头和数据体,来进行序列化和反序列化,就像下面代码的样子。或者别的方法来实现动态选择不同的数据体格式做序列化和反序列化?我不想先从二进制解出来一个头,然后拿着剩余的二进制数据再判断解析数据体,太麻烦了。

注:我知道 readme 写了不支持 Object,所以我下面的代码里给 Object 加个自定义转换器的注解,能否实现动态序列化转换?

@MagicClass(byteOrder = ByteOrder.BIG_ENDIAN)
public class School {
    // 一个对象
    @MagicField(order = 1)
    private Header header;
    
    @MagicField(order = 3)
    @MagicConverter()
    private Object age;
  
}

BUG:作为属性的类的属性如果都使用了 @MagicConverter 将会导致反序列结果不正确

测试代码参考合并请求 #56

@MagicClass
public class CustomClassA {

    @MagicField(order = 1)
    private int number;

    @MagicField(order = 2)
    private B b;

    @MagicClass
    public static class B {

        @MagicField(order = 1)
        @MagicConverter(converter = TypeEnumConverter.class)
        private TypeEnum typeEnum;
    }

    public enum TypeEnum {
        A, B
    }

目前通过调试追踪代码看到,在这种使用情况下,生成的属性 b 的 elementbytes 的值为 0,导致反序列化的时候跳过了对应属性的反序列化,导致反序列化结果里 b 的值为 null

提个建议,MagicField 属性的converter参数可以接受你的ConverterUtil方法

应用场景 就是 我的其中一个字段需要用 ushort去接。但是java中又没有ushort,ConverterUtil.byteToNumber(byte[]),你有提供了类似的工具类。那么结合起来岂不是很爽。如果能像我说的 那样直接转换的话,会方便许多。
image
例如这么写。直接在属性那块就把heading的值矫正过来了。

可以设置默认全局端序

一般端序都是一个项目都用同一个,没必要在 @MagicClass(byteOrder = ByteOrder.BIG_ENDIAN) 中挨个设置,可以全局统一设置默认端序,如果有单独需要可以在注解里改

dynamicSizof wiki 没更新

dynamicSizof wiki 没更新,新的 dynamicSizof 的改动是破坏性的,旧代码都要进行修改 >_<

探讨消息注册

  1. 在合并请求 #32 提交的测试用例可以正常序列化数据,但是反序列化后的对象为 null。
  2. wiki 里 https://github.com/MisterChangRay/magic-byte/wiki/%E6%95%B0%E6%8D%AE%E5%AE%9E%E4%BD%93%E5%AE%9A%E4%B9%89%E7%9A%84%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5#2-%E8%87%AA%E8%A1%8C%E8%A7%A3%E6%9E%90%E6%95%B0%E6%8D%AE%E5%92%8C%E4%BB%A3%E7%A0%81 的测试用例是不是有问题,先 Head pack = MagicByte.pack(deviceUploadMessage, Head.class); ,然后 HeartbeatCmd pack1 = MagicByte.pack(deviceUploadMessage, HeartbeatCmd.class); 用同一个二进制数据从头开始解析,数据结果是不对的,因为需要偏移起始位置,但是又要先获得 Head 的全长再去偏移生成对象,比较繁琐

无法计算接口类的长度

如果 @magicfield 注解的属性类型是接口类则计算的长度为 0,因为在计算长度的时候是通过类的属性计算的,而不是通过实际类型动态计算的

能否对整个 list 设置自定义序列化

目前的自定义序列化是对 list 遍历,然后对 list 里每一个 item 单独做序列化处理的,但是我希望可以对整个 list 做序列化,也就是直接把 list 给我,我来对 list 做整体的处理

dynamicSize 支持接口类

如果 dynamicSize 可以支持 Object,是不是就可以运行时自动计算类型为接口类的属性的长度了

如果是动态的有办法呢?

如:
当第0个字节是 0x01的时候,则第1 ~ 4个字节 需要解析为:对象中的姓名
当第0个字节是0x02的时候,则第1 ~ 3个字节需要解析为:对象中的地址

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.