首页 > 其他分享 >FAST协议详解3 可null(空)类型

FAST协议详解3 可null(空)类型

时间:2023-08-29 13:58:57浏览次数:43  
标签:10000011 123 10000000 10000001 FAST 详解 message null

一、概述

所谓可null、可空,其实是一个特性的两个方面,某些情况下,我们不需要传递某个字段的值,则可以将该字段“空”起来,不赋值,则接收方在收到该字段时会自动解析为null值。所以空是对于发送方而言,而null则是对于接收方而言,但FAST流中并不会因为没有对该字段赋值就可以节省下一个字节,而是需要传递一个特殊值来告知接收方这个字段未赋值,接收方应解析为null。不同的数据类型为适应可null(空)的特性有一些较奇怪的变换,下面看实例。

这里先回顾一下scalar这个类,可见是通过修改optional来设置字段是否可空。

 

 

 

二、不同数据类型的可null(空)

数据类型

说明

INTEGER整数

可空整数,编码后数值+1。比如我要传递1,则实际传递的是2,解码方收到后自行减去1。原因是要用0值代表null。但传递负值时就不需要再自行减1了。

ASCII字符串

可空字符串,编码后数值不变。但需要区分null、空字符串、\0。

10000000->null

00000000 10000000->空字符串

00000000 00000000 10000000->\0

STRING字符串

同上

BYTEVECTOR字节向量

字节向量分为长度和数据两部分,其中长度部分若为10000000则表明字段为null,而10000001则表明字节向量长度为0,故而长度部分在解码后需要自行减去1。

DECIMAL浮点数

浮点数的传输也分为两部分,第一部分是小数点位数,第二部分是数值。 其中小数点位数部分若为10000000则表明字段为null,但正常传递浮点数时位数部分不需要再减去1,比如-2是“11111110”,只有传递1这样无小数点的数值时,由于其小数点位数为“10000000”,必须要再加1。所以小数点位数部分在负值时不需要自行减1,在正直时需要自行减1。

 

三、可null(空)实例

1、INTEGER整数

 

上述代码运行结果如下:

msg111= -> {123, 1, null, 3}

outByteStr=11000000,11111011,10000001,10000000,10000011,

可以看到第二个字段传输的值是10000000,在这里会解析为null

 

问题:如何传递非空值?

 

上述代码运行结果如下:

msg111= -> {123, 1, 2, 3}

outByteStr=11000000,11111011,10000001,10000011,10000011,

可以看到,第二个字段值是2,但传输的是10000011(0000011->3),对于可空字段,解码时需要自行减去1,因为null把10000000占了,传递0需要使用1000001。

 

问题:如何传递负值?

 

上述代码运行结果如下:

msg111= -> {123, 1, -2, 3}

outByteStr=11000000,11111011,10000001,11111110,10000011,

可以看到,对于负值是直接传递的,不需要加一或者减一。

 

2、ASCII字符串

 

上述代码运行结果如下:

msg111= -> {123, 1, 123, 3}

outByteStr=11000000,11111011,10000001,00110001,00110010,10110011,10000011,

可见对于字符串,数值转换并未有改变。

 

问题:如何传输null

做如下修改:

Message message = new Message(template);

message.setInteger(1, 1);

//message.setString(2, "123");

message.setInteger(3, 3);

运行结果如下:

msg111= -> {123, 1, null, 3}

outByteStr=11000000,11111011,10000001,10000000,10000011,

可见,是通过10000000来传输null值

 

问题:如何传输空字符串

做如下修改:

Message message = new Message(template);

message.setInteger(1, 1);

message.setString(2, "");

message.setInteger(3, 3);

运行结果如下:

msg111= -> {123, 1, , 3}

outByteStr=11000000,11111011,10000001,00000000,10000000,10000011,

可见是通过00000000,10000000来传输空字符串。

 

问题:如何传输\0字符

做如下修改:

Message message = new Message(template);

message.setInteger(1, 1);

message.setString(2, "\0");

message.setInteger(3, 3);

运行结果如下:

msg111= -> {123, 1,  , 3}

outByteStr=11000000,11111011,10000001,00000000,00000000,10000000,10000011,

可见是通过00000000,00000000,10000000来传输\0字符

 

3、STRING字符串

同ASCII字符串

 

4、BYTEVECTOR字节向量

 

上述代码运行结果如下:

msg111= -> {123, 1, 123, 3}

outByteStr=11000000,11111011,10000001,10000100,00110001,00110010,00110011,10000011,

注意这里00000100的值是4,而123字符串的实际长度是3,所以这里需要减去1。

 

问题:如何传递null

做如下修改:

Message message = new Message(template);

message.setInteger(1, 1);

//message.setByteVector(2, "123".getBytes("GBK"));

message.setInteger(3, 3); 

运行结果如下:

msg111= -> {123, 1, null, 3}

outByteStr=11000000,11111011,10000001,10000000,10000011,

当字段不设值时,使用10000000来代表null。

 

5、DECIMAL浮点数

 

上述代码运行结果如下:

msg111= -> {123, 1, 0.01, 3}

outByteStr=11000000,11111011,10000001,11111110,10000001,10000011,

可以看到,小数点位数值是-2,没有因为可null属性而需要加一或减一。

 

问题:如何传递null值

代码修改如下:

Message message = new Message(template);

message.setInteger(1, 1);

//message.setDecimal(2, 0.01);

message.setInteger(3, 3);

运行结果如下:

msg111= -> {123, 1, null, 3}

outByteStr=11000000,11111011,10000001,10000000,10000011,

与BYTEVECTOR类似,小数点位数这里传递10000000即代表null,对于无可null属性的浮点数,10000000则表示无小数点。

 

问题:无小数点如何表现

代码修改如下:

Message message = new Message(template);

message.setInteger(1, 1);

message.setDecimal(2, 2);

message.setInteger(3, 3);

运行结果如下:

msg111= -> {123, 1, 2, 3}

outByteStr=11000000,11111011,10000001,10000001,10000010,10000011,

可以看到,小数点位数这里值是正数1,因为10000000已经用于表示null了,所以正数都要减去1,实际表明的是无小数点。

 

四、回顾

总的看来,其实空也是一个需要传递的值,而为了区分空(null)与0,对于正数将全部数值都+1,对于负数则无影响。对于字节向量和浮点数则是在字节向量的长度和小数点位数这里进行区分,字符串则无影响,但需要注意区分null、空字符串、\0字符。

 

标签:10000011,123,10000000,10000001,FAST,详解,message,null
From: https://www.cnblogs.com/cation/p/17664535.html

相关文章

  • Gson与FastJson详解
    Gson与FastJson详解Java与JSON做什么?将Java中的对象快速的转换为JSON格式的字符串.将JSON格式的字符串,转换为Java的对象.Gson将对象转换为JSON字符串转换JSON字符串的步骤:引入JAR包在需要转换JSON字符串的位置编写如下代码即可:Stringjson=newGson().toJSON(......
  • 智能指针详解
    文章目录一、智能指针背后的设计思想二、普通指针存在的问题三、shared_ptr类1、make_shared函数2、shared_ptr的拷贝和赋值3、shared_ptr自动销毁所管理的对象4、使用动态内存的原因:5、使用shared_ptr的一个例子:四、shared_ptr的实现和循环引用问题五、weak_ptr类1、weak_ptr详解......
  • Web服务器项目详解
    文章目录一、新连接到来的处理流程二、Channel、TcpConnection、TcpServer、Poller、EventLoop类详解1、Channel类2、TcpConnection类3、TcpServer类4、Poller类5、EventLoop类三、这几个类之间的关系一、新连接到来的处理流程一个新的连接到来后,首先被MainReactor接收,然后通过轮......
  • ByteBuf用法详解文档
    来源:http://www.taodudu.cc/news/show-3638306.html?action=onClick_____________________________________________________________________________________________ ByteBufbytebuf文档点这里基本信息:ByteBuf类java.lang.Objectio.netty.buffer.ByteBuf所有已实......
  • 软件测试|SQL中的UNION和UNION ALL详解
    简介在SQL(结构化查询语言)中,UNION和UNIONALL是用于合并查询结果集的两个关键字。它们在数据库查询中非常常用,但它们之间有一些重要的区别。在本文中,我们将深入探讨UNION和UNIONALL的含义、用法以及它们之间的区别。UNION操作UNION用于合并两个或多个查询的结果集,并返回一个唯一的......
  • 软件测试|Python中的变量与关键字详解
    简介在Python编程中,变量和关键字是非常重要的概念。它们是构建和控制程序的基本要素。本文将深入介绍Python中的变量和关键字,包括它们的定义、使用方法以及一些常见注意事项。变量变量的定义变量是用于存储数据值的名称。在Python中,变量无需声明,可以直接赋值使用。变量可以存储不同......
  • 共用体详解
    共用体同结构体的定义形式上相同,只是把关键字struct改为union。有时需要把几种不同类型的变量放在同有一内存区域中,见图12-6,把一个整型变量,一个字符变量,一个实型变量放在同一内存区域中,尽管三个变量占用字节数各不相同,但起始地址都一样(例如1000)它要用“覆盖’’技术,使多个变量互相......
  • cron表达式详解
    Cron表达式是一种用于指定定时任务执行时间的字符串表达式。它由6个或7个字段组成,每个字段代表一个时间单位或一个时间段。下面是对Cron表达式的详细解释:秒(可选):0-59之间的整数,表示每分钟的哪一秒执行任务。例如,0表示每分钟的第0秒执行任务。分钟:0-59之间的整数,表示每小时的......
  • 19.Linux中write函数详解
    19.Linux中write函数详解头文件:#include<unistd.h>函数原型:write(intfd,constvoid*buf,size_tcount);函数说明:write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。返回值:如果顺利write()会返回实际写入的字节数(len)。当有错误发生时则返回-1,错......
  • ImportBeanDefinitionRegistrar手动控制BeanDefinition创建注册详解
    目录一、什么是ImportBeanDefinitionRegistrar二、ImportBeanDefinitionRegistrar使用很简单registerFilters()方法三、ImportBeanDefinitionRegistrar原理一、什么是ImportBeanDefinitionRegistrarImportBeanDefinitionRegistrar接口是也是spring的扩展点之一,ImportBeanDefinition......