@tars/stream

00 - 安装

$ npm install @tars/stream

01 - stream 模块基本介绍和使用方法

stream 模块用作 Tars(tars/TUP)基础协议编解码库,使用该模块可以基于 tars 协议描述格式对数据流进行编解码,并能够与目前使用 tars 协议的 TARS 服务端以及终端进行无障碍通信。

tars 编解码模块工作流方式一般有如下三种:

第一种,以 tars 文件作为调用方和服务方的通信桥梁(双方约定最终协议以 tars 文件为准)。

该 tars 文件也就是我们常说的以".tars"结尾的协议描述文件。

该 tars 文件一般由后台开发制定,前台开发需向后台开发索求经评审确认的 tars 文件,然后经工具转换成适用于 NodeJS 的编解码源代码文件。

module TRom
{
    struct User_t
    {
        0 optional int id = 0;
        1 optional float score = 0;
        2 optional string name = "";
    };

    struct Result_t
    {
        0 optional int id = 0;
    };

    interface NodeJsComm
    {
        int test();

        int getall(User_t stUser, out Result_t stResult);

        int getUsrName(string sUsrName, out string sValue1, out string sValue2);

        int secRequest(vector<byte> binRequest, out vector<byte> binResponse);
    };
};

比如,我们将如上内容保存为“Protocol.tars”后,可以使用如下的命令生成不同的文件:

$ tars2node Protocol.tars

上述命令将忽略 interface 描述段,只转换文件中定义的“常量”、“枚举值”、“结构体”等数据类型,供开发者当不使用 Tars 框架作为调用工具时的编解码库文件。生成的文件名称为“Protocol.js”。

$ tars2node Protocol.tars --client

上述命令不仅转换文件中定义的“常量”、“枚举值”、“结构体”等数据类型,同时将 interface 的描述段翻译成 RPC 调用框架。生成的文件名称为“ProtocolProxy.js”,该文件供调用方使用。开发者引入该文件之后,可以直接调用服务端的服务。具体的使用方法请参考“npm install rpc”模块的说明文档。

$ tars2node Protocol.tars --server

上述命令不仅转换文件中定义的“常量”、“枚举值”、“结构体”等数据类型,同时将 interface 的描述段翻译成服务端的接口文件。生成的文件名称为“Protocol.js”以及“ProtocolImp.js”,开发者不要改动“Protocol.js”,只需要继续完善“ProtocolImp.js”,实现文件中具体的函数,即可作为 Tars 服务端提供服务。具体的使用方法请参考“npm install rpc”模块的说明文档。

第二种,没有协议描述文件,需要我们自己手工书写编解码代码时。

比如服务后台提供购买某件商品的功能,它需要“用户号码”、“用户昵称”、“商品编号”、“商品数量”等四个参数。 后台对这四个参数的编号(也就是 tars 中所指的 tag)分别为 0、1、2、3。

第三种,服务端接受 TUP 协议格式的数据。

02 - stream 支持的数据类型以及使用方法

基本数据类型

数据类型
对应 C++语言的数据类型

布尔值

bool

整型

char(int8)、short(int16)、int(int32)、long long(int64)

整型

unsigned char(uint8)、unsigned short(uint16)、unsigned int(uint32)

数值

float(32 位)、double(64 位)

字符串

std::string

复杂数据类型

数据类型
对应 C++语言的数据类型

结构体

struct(在 Tars 框架中需要使用 tars2node 根据 tars 文件来生成 Javascript 中的类)

二进制 Buffer

vector<char>(在 NodeJs 中使用[stream].BinBuffer 类型来模拟)

数组

vector<DataType>(在 NodeJs 中使用[stream].List(vproto)类型来模拟)

词典

map<KeyType, DataType>(在 NodeJs 中使用[stream].Map(kproto, vproto)类型来模拟)

关于 NodeJs 中数据类型的特别说明

[1]: “复杂数据类型”与“基本数据类型”,或者“复杂数据类型”与“复杂数据类型”组合使用可以组成其他高级数据类型。

[2]: 虽然 NodeJS 中支持 Float 和 Double 数据类型,但我们不推荐使用,因为在序列化和反序列化之后,数值存在精度损失,某些情况下会对业务逻辑造成伤害。

[3]: 我们这里实现的 64 位整形实际上是伪 64 位,在 NodeJs 中它的原形仍然是 Number。

我们都知道 Js 中的 Number 类型采用 IEEE754 双精度浮点数标准来表示。IEEE754 规定有效数字第一位默认为 1,再加上后面的 52 位来表示数值。

也就是说 IEEE754 提供的有效数字的精度为 53 个二进制位,这就意味着 NodeJs 的 Number 数值或者说我们实现的 Int64 数据类型只能精确表示绝对值小于 2 的 53 次方的整数。

[4]: 在 Javascript 中 String 类型是 Unicode 编码,在 tars 编解码时我们将其转换成了 UTF8 编码格式;

后台服务程序接受到的字符串是 UTF8 编码,如果需要按照 GBK 编码的方式处理字符串,需要后台程序先做下转码(UTF8->GBK);

后台服务程序如果使用的是 GBK,发送字符串之前,需要将其转成 UTF8 编码。

03 - 基本类型使用方法

04 - 复杂类型前传 - 用于表示复杂类型的类型原

首先,我们理解下什么是 类型原型

在 C++中,我们可以按如下方法声明一个字符串的容器向量:

其中 std::vectorstd::string,std::vector 表示容器类型,而 std::string 则表示该容器所容纳的 类型原型

那我们如何在 NodeJs 中表示该类型?并能使之与 tars 的编解码库无缝的融合?

为了解决这个问题,我们使用如下的方法对 std::vector 进行模拟,以达到上述 C++代码所能完成的功能:

其中 Tars.List(Tars.String),Tars.List 表示数组类型,而 Tars.String 则用来表示该容器所容纳的 类型原型

至此,我们明白类型原型主要是用来与复杂数据类型组合,表示更加复杂的数据类型。

目前的版本中,我们支持如下的类型原型定义:

数据类型
描述

布尔值

[stream].Boolean

整型

[stream].Int8, [stream].Int16, [stream].32, [stream].64, [stream].UInt8, [stream].UInt16, [stream].UInt32

数值

[stream].Float, [stream].Double

字符串

[stream].String

枚举值

[stream].Enum

数组

[stream].List

字典

[stream].Map

二进制 Buffer

[stream].BinBuffer

为了大家更加清晰的理解该概念,我们提前描述一部分复杂类型的在 NodeJs 中的表示方法。

数据类型的详细使用方法,请参考后续的详细说明。

05 - 复杂类型 - struct(结构体)的使用方法说明

将上述内容保存为文件“Demo.tars”,然后使用命令“tars2node Demo.tars”生成编解码文件“Demo.js”。

“Demo.js”内容如下所示:

对“module Ext”的说明

Ext 在 C++中就是命名空间,在 Javascript 中我们将它翻译成一个 Object,该命名空间下所有的“常量”、“枚举值”、“结构体”、“函数”都挂接在该 Object 之下。

tars 文件中描述的结构体的表示方法

首先,结构体翻译成一个 Object。翻译程序根据数据类型以及 tars 文件中定义的默认值,生成数据成员。除 tars 中定义的数据成员之外,根据编解码的需要,翻译程序为结构体添加了若干辅助函数。这些函数如_writeTo,在需要将结构体序列化成数据流的地方,被编解码库调用,该函数逐个将数据成员写入数据流中。

翻译程序默认添加的辅助函数

方法
限制
描述

_write

开发者不可用

静态函数。当结构体用作类型原型时使用。

_read

开发者不可用

静态函数。当结构体用作类型原型时使用。

_readFrom

开发者不可用

静态函数。从数据流中读取结构体的数据成员值,并生成一个权限的结构体示例返回。

_writeTo

开发者不可用

成员函数。将当前结构体的数据成员写入指定的数据流中。

_equal

开发者不可用

成员函数。将当前结构体用作字典类型 Key 值时的比较函数。

_genKey

开发者不可用

成员函数。将当前结构体用作字典类型 Key 值时,内部使用该函数获得当前结构体的别名。

toBinBuffer

开发者可用

成员函数。将当前结构体序列化成二进制 Buffer,返回值类型为 require("@tars/stream").BinBuffer。

create

开发者可用

成员函数。从数据流中返回一个全新的结构体。

结构体的使用示例

我们演示结构体在三个典型场景的使用方法:

第一种场景: 当结构体用作 RPC 函数的参数时。

由于 rpc 框架会自动对参数进行序列化,所以我们无需关心编解码,只需要按照普通的类一样,先 new 后赋值,然后传入参数直接调用 RPC 函数即可。

假如服务端有个 RPC 如下定义:

安装上述方法生成 tars 编解码文件(生成文件名称为:Protocol.js)之后,按如下方法调用对端服务:

第二种场景: 对端非标准 rpc 框架,接受序列化的数据流作为参数。

在这种场景下需要我们自己对结构体进行序列化。还是以上面的 tars 文件作为例子,一般的方法如下:

客户端将 toSendBuffer 发送给服务端,并且服务端接受完毕之后按如下方法进行解码:

第三种场景: 对方服务要求数据流使用 Tup 协议,并且已经约定好了各个变量的名字。我们可以按如下的方法进行编解码:

客户端将 toSendBuffer 发送给服务端,并且服务端接受完毕之后按如下方法进行解码:

06 - 复杂类型 - vector(数组)的使用方法说明

由于 Javascript 原生的 Array 不支持 tars 中的一些特殊化操作,所以我们对它进行了一次封装。开发者可按下述的代码理解:

[stream].List 对象属性

属性
描述

value

Js 中的 Array 数据类型。Tars.List 实际是基于该 Array 进行的上层封装。

length

返回数组中元素的数目。

[stream].List 对象方法

方法
描述

at

返回数组中指定位置的元素。

push

向数组的末尾添加一个元素。

forEach

当前数组的遍历方法,具体使用方法请参考后面的示例。

toObject

将 List 实例转化成基本的数据对象,具体使用方法请参考后面的示例。

readFromObject

将传入的数组处理后 push 到 List 实例中,具体使用方法请参考后面的示例。

proto 是 Vector 的类型原型(类型原型决定了在对 Vector 编解码时采用的方法,所以声明 Vector 的时候必须传入正确的类型原型)。

[stream].List 的声明示例

[stream].List 的操作示例

07 - 复杂类型 - map(字典)的使用方法说明

由于 Javascript 原生的 Object 不支持 tars 中的一些特殊化操作,所以我们对它进行了一次封装。开发者可按下述的代码理解:

[stream].Map 对象属性

属性
描述

value

Js 中的 Object 数据类型。[stream].Map 实际是基于该 Object 进行的上层封装。

[stream].Map 方法属性

方法
描述

insert

向字典中添加一个元素。

set

同 insert。

put

同 insert。

remove

根据指定的 key,从字典中删除对应的数值。

clear

清空当前字典。

has

根据指定的 key,判断字典中是否包含对应的数值。

size

返回当前字典中元素的数目。

forEach

当前数组的遍历方法,具体使用方法请参考后面的示例。

toObject

将 Map 实例转化成基本的数据对象,具体使用方法请参考后面的示例。

readFromObject

将传入的对象处理后 insert 到 Map 实例中,具体使用方法请参考后面的示例。

[stream].Map 的声明示例

[stream].Map 的操作示例

支持 MultiMap 类型

支持 MultiMap 类型,此类型允许以一个结构体作为 Map 的 key。javascript 原生对象没有办法表示此数据类型,因此此类型没有实现普通 Map 支持的 toObject 和 readFromObject 方法。

其操作实例如下:

08 - 复杂类型 - 二进制 Buffer 的使用方法说明

在浏览器中我们可以使用“DataView”和“ArrayBuffer”来存储和操作二进制数据。NodeJS 为了提升性能,自身提供了一个 Buffer 类。为了方便 Tars 的编解码,我们对 Buffer 类进行了一层封装。开发者可按下述的代码理解:

[stream].BinBuffer 对象属性

属性
描述

length

获取该二进制 Buffer 的数据长度

capacity

获取该二进制 Buffer 在不重新分配内存的情况下,可容纳数据的最大长度

position

获取或者设置当前二进制 Buffer 的访问指针

length 和 capacity 的区别:

假如我们向 BinBuffer 中写入一个 Int32 类型的数据。写成功之后,length 和 capacity 的区别:

由于 BinBuffer 类在第一次分配时使用默认的 512 长度来申请内存,此时 capacity 的值为 512

length 表示当前 Buffer 中存在真实数据的大小,此时 length 的值为 4

[stream].BinBuffer 方法属性

toNodeBuffer

函数定义;[stream].BinBuffer.toNodeBuffer()

函数作用:返回当前二进制 Buffer 的数据,该值为深拷贝的类型为 NodeJS.Buffer 的数据

输入参数:无

返回数据:NodeJS.Buffer 类型

print

函数定义:[stream].BinBuffer.print()

函数作用:以每行 16 个字节,并 16 进制的方式打印当前的 Buffer

writeNodeBuffer

函数定义:[stream].BinBuffer.writeNodeBuffer(srcBuffer, offset, byteLength)

函数作用:向二进制 Buffer 中写入 NodeJS.Buffer 类数据

输入参数:

参数
数据类型
描述

srcBuffer

NodeJS.Buffer

原始的 Buffer 数据

offset

UInt32

表示拷贝 srcBuffer 的起始位置

byteLength

UInt32

表示从 offset 开始,从 srcBuffer 中拷贝的数据量

函数说明:

[1]当前 BinBuffer 的 length = length(原Buffer数据长度) + byteLength

[2]当前 BinBuffer 的 position = position(原Buffer的位置指针) + byteLength

writeBinBuffer

函数定义:[stream].BinBuffer.writeBinBuffer(value)

函数作用:向二进制 Buffer 中写入[stream].BinBuffer 类数据

输入参数:

参数
数据类型
描述

value

[stream].BinBuffer

表示二进制 Buffer

函数说明:

[1]当前 BinBuffer 的 length = length(原Buffer数据长度) + value.length

[2]当前 BinBuffer 的 position = position(原Buffer的位置指针) + value.length

writeInt8

函数定义:[stream].BinBuffer.writeInt8(value)

函数作用:向二进制 Buffer 中写入 Int8 类数据

输入参数:

参数
数据类型
描述

value

Int8

8 位的整型数据

函数说明:

[1]当前 BinBuffer 的 length = length(原Buffer数据长度) + 1

[2]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 1

writeInt16

函数定义:[stream].BinBuffer.writeInt16(value)

函数作用:向二进制 Buffer 中写入 Int16 类数据

输入参数:

参数
数据类型
描述

value

Int16

16 位的整型数据

函数说明:

[1]当前 BinBuffer 的 length = length(原Buffer数据长度) + 2

[2]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 2

[3]数据存储采用网络字节序

writeInt32

函数定义:[stream].BinBuffer.writeInt32(value)

函数作用:向二进制 Buffer 中写入 Int32 类数据

输入参数:

参数
数据类型
描述

value

Int32

32 位的整型数据

函数说明:

[1]当前 BinBuffer 的 length = length(原Buffer数据长度) + 4

[2]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 4

[3]数据存储采用网络字节序

writeInt64

函数定义:[stream].BinBuffer.writeInt64(value)

函数作用:向二进制 Buffer 中写入 Int64 类数据

输入参数:

参数
数据类型
描述

value

Int64

64 位的整型数据

函数说明:

[1]当前 BinBuffer 的 length = length(原Buffer数据长度) + 8

[2]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 8

[3]数据存储采用网络字节序

writeUInt8

函数定义:[stream].BinBuffer.writeUInt8(value)

函数作用:向二进制 Buffer 中写入 UInt8 类数据

输入参数:

参数
数据类型
描述

value

UInt8

8 位的整型数据

函数说明:

[1]当前 BinBuffer 的 length = length(原Buffer数据长度) + 1

[2]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 1

writeUInt16

函数定义:[stream].BinBuffer.writeUInt16(value)

函数作用:向二进制 Buffer 中写入 UInt16 类数据

输入参数:

参数
数据类型
描述

value

UInt16

16 位的整型数据

函数说明:

[1]当前 BinBuffer 的 length = length(原Buffer数据长度) + 2

[2]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 2

[3]数据存储采用网络字节序

writeUInt32

函数定义:[stream].BinBuffer.writeUInt32(value)

函数作用:向二进制 Buffer 中写入 UInt32 类数据

输入参数:

参数
数据类型
描述

value

UInt32

32 位的整型数据

函数说明:

[1]当前 BinBuffer 的 length = length(原Buffer数据长度) + 4

[2]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 4

[3]数据存储采用网络字节序

writeFloat

函数定义:[stream].BinBuffer.writeFloat(value)

函数作用:向二进制 Buffer 中写入 Float(32 位,单精度浮点数)类数据

输入参数:

参数
数据类型
描述

value

Float

32 位的单精度浮点数

函数说明:

[1]当前 BinBuffer 的 length = length(原Buffer数据长度) + 4

[2]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 4

[3]数据存储采用网络字节序

writeDouble

函数定义:[stream].BinBuffer.writeDouble(value)

函数作用:向二进制 Buffer 中写入 Double(64 位,双精度浮点数)类数据

输入参数:

参数
数据类型
描述

value

Double

64 位的双精度浮点数

函数说明:

[1]当前 BinBuffer 的 length = length(原Buffer数据长度) + 8

[2]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 8

[3]数据存储采用网络字节序

writeString

函数定义:[stream].BinBuffer.writeString(value)

函数作用:向二进制 Buffer 中写入 String(UTF8 编码)类数据

输入参数:

参数
数据类型
描述

value

String

UTF8 编码的字符串

函数说明:

[1]当前 BinBuffer 的 length = length(原Buffer数据长度) + 字符串的字节长度

[2]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 字符串的字节长度

readInt8

函数定义:[stream].BinBuffer.readInt8()

函数作用:从二进制 Buffer 中,根据当前数据指针读取一个 Int8 类型的变量

输入参数:无

函数说明:

[1]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 1

readInt16

函数定义:[stream].BinBuffer.readInt16()

函数作用:从二进制 Buffer 中,根据当前数据指针读取一个 Int16 类型的变量

输入参数:无

函数说明:

[1]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 2

readInt32

函数定义:[stream].BinBuffer.readInt32()

函数作用:从二进制 Buffer 中,根据当前数据指针读取一个 Int32 类型的变量

输入参数:无

函数说明:

[1]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 4

readInt64

函数定义:[stream].BinBuffer.readInt64()

函数作用:从二进制 Buffer 中,根据当前数据指针读取一个 Int64 类型的变量

输入参数:无

函数说明:

[1]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 8

readUInt8

函数定义:[stream].BinBuffer.readUInt8()

函数作用:从二进制 Buffer 中,根据当前数据指针读取一个 UInt8 类型的变量

输入参数:无

函数说明:

[1]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 1

readUInt16

函数定义:[stream].BinBuffer.readUInt16()

函数作用:从二进制 Buffer 中,根据当前数据指针读取一个 UInt16 类型的变量

输入参数:无

函数说明:

[1]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 2

readUInt32

函数定义:[stream].BinBuffer.readUInt32()

函数作用:从二进制 Buffer 中,根据当前数据指针读取一个 UInt32 类型的变量

输入参数:无

函数说明:

[1]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 4

readFloat

函数定义:[stream].BinBuffer.readFloat()

函数作用:从二进制 Buffer 中,根据当前数据指针读取一个 Float(32 位的单精度浮点数)类型的变量

输入参数:无

函数说明:

[1]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 4

readDouble

函数定义:[stream].BinBuffer.readDouble()

函数作用:从二进制 Buffer 中,根据当前数据指针读取一个 Double(64 位的双精度浮点数)类型的变量

输入参数:无

函数说明:

[1]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 8

readString

函数定义:[stream].BinBuffer.readString(byteLength)

函数作用:从二进制 Buffer 中,根据当前数据指针读取一个 String(UTF8 编码)类型的变量

输入参数:

参数
数据类型
描述

byteLength

UInt32

字符串的字节长度

函数说明:

[1]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 字符串的字节长度

[2]后台对字符串的编码需要使用 UTF8 字符集

readBinBuffer

函数定义:[stream].BinBuffer.readBinBuffer(byteLength)

函数作用:从二进制 Buffer 中,根据当前数据指针读取一个[stream].BinBuffer 类型的变量

输入参数:

参数
数据类型
描述

byteLength

UInt32

二进制 Buffer 的字节长度

函数说明:

[1]当前 BinBuffer 的 position = position(原Buffer的位置指针) + 二进制Buffer的字节长度

09 - 编码工具 - OutputStream 的使用方法说明

构造函数

函数定义:[stream].OutputStram()

函数作用:声明一个输出流对象

输入参数:无

使用示例:var os = new [stream].OutputStream()

getBinBuffer

函数定义:var buffer = [stream].OutputStream.getBinBuffer()

函数作用:调用该函数获得打包后的二进制数据流

输入参数:无

返回数据:返回打包后的二进制数据流,该返回值类型为[stream].BinBuffer

writeBoolean

函数定义:[stream].OutputStream.writeBoolean(tag, value)

函数作用:向数据流中写一个 Boolean 类型的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

Boolean

表示该变量的值,取值范围{false, true}

返回数据:void

writeInt8

函数定义:[stream].OutputStream.writeInt8(tag, value)

函数作用:向数据流中写一个 int8 类型的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

int8(Number)

表示该变量的值,取值范围[-128, 127]

返回数据:void

writeInt16

函数定义:[stream].OutputStream.writeInt16(tag, value)

函数作用:向数据流中写一个 Int16 类型的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

int16(Number)

表示该变量的值,取值范围[-32768, 32767]

返回数据:void

writeInt32

函数定义:[stream].OutputStream.writeInt32(tag, value)

函数作用:向数据流中写一个 Int32 类型的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

int32(Number)

表示该变量的值,取值范围[-2147483648, 2147483647]

返回数据:void

writeInt64

函数定义:[stream].OutputStream.writeInt64(tag, value)

函数作用:向数据流中写一个 Int64 类型的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

int64(Number)

表示该变量的值,取值范围[-9223372036854775808, 9223372036854775807]

返回数据:void

writeUInt8

函数定义:[stream].OutputStream.writeUInt8(tag, value)

函数作用:向数据流中写一个 UInt8 类型的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

UInt8(Number)

表示该变量的值,取值范围[0, 255]

返回数据:void

writeUInt16

函数定义:[stream].OutputStream.writeUInt16(tag, value)

函数作用:向数据流中写一个 UInt16 类型的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

UInt16(Number)

表示该变量的值,取值范围[0, 65535]

返回数据:void

writeUInt32

函数定义:[stream].OutputStream.writeUInt32(tag, value)

函数作用:向数据流中写一个 UInt32 类型的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

UInt32(Number)

表示该变量的值,取值范围[0, 4294967295]

返回数据:void

writeFloat

函数定义:[stream].OutputStream.writeFloat(tag, value)

函数作用:向数据流中写一个 float(32 位)类型的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

Float(Number)

单精度浮点数,因为有精度损失问题,不推荐使用该类型

返回数据:void

writeDouble

函数定义:[stream].OutputStream.writeDouble(tag, value)

函数作用:向数据流中写一个 double(64 位)类型的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

Double(Number)

双精度浮点数,因为有精度损失问题,不推荐使用该类型

返回数据:void

writeString

函数定义:[stream].OutputStream.writeString(tag, value)

函数作用:向数据流中写一个 String 类型的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

String

表示该变量的值,字符串编码字符集为 UTF8

返回数据:void

writeStruct

函数定义:writeStruct(tag, value)

函数作用:向数据流中写一个自定义结构体的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

自定义结构体

结构体必须是使用 tars2node 转换而成的,否则可能会因缺少辅助函数而导致编解码失败

返回数据:void

writeBytes

函数定义:[stream].OutputStream.writeBytes(tag, value)

函数作用:向数据流中写一个类型为 char * 或者 vector<char> 的变量

输入参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

[stream].BinBuffer

BinBuffer 是对 NodeJs 中的 Buffer 类的封装,同时集成了编解码需要用到的辅助函数

返回数据:void

writeList

函数定义:[stream].OutputStream.writeList(tag, value)

函数作用:向数据流中写一个类型为 vector<T>(T 不可为 byte)的变量

函数参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

[stream].List(T)

该变量的类型原型

返回数据:void

writeMap

函数定义:[stream].OutputStream.writeMap(tag, value)

函数作用:向数据流中写一个类型为 map<T, V> 类型的字段。

函数参数:

参数
数据类型
描述

tag

UInt8

表示该变量的数字标识,取值范围[0, 255]

value

[stream].Map(T, V)

该变量的类型原型

返回数据:void

10 - 解码工具 - InputStream 的使用方法说明

构造函数

函数定义:[stream].InputStream(binBuffer)

函数作用:声明一个输入流对象

输入参数:

binBuffer 欲解码的二进制数据流,该值类型必须为[stream].BinBuffer,而不能是 NodeJs 中实现的 Buffer 类。

使用示例:var is = new [stream].InputStream(new [stream].BinBuffer(Node.Buffer))

readBoolean

函数定义:var value = [stream].InputStream.readBoolean(tag, require, default)

函数作用:从数据流读取一个 Boolean 类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

default

Boolean

表示读取变量不成功时的返回值,取值范围{false, true}

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回变量的默认值 default;

返回数据:Boolean,取值范围{false, true}

readInt8

函数定义:[stream].InputStream.readInt8(tag, require, default)

函数作用:从数据流读取一个 Int8 类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

default

Int8

表示读取变量不成功时的返回值,取值范围[-128, 127]

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回变量的默认值 default;

返回数据:Int8,取值范围[-128, 127]

readInt16

函数定义:[stream].InputStream.readInt16(tag, require, default)

函数作用:从数据流读取一个 Int16 类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

default

Int16

表示读取变量不成功时的返回值,取值范围[-32768, 32767]

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回变量的默认值 default;

返回数据:Int16,取值范围[-32768, 32767]

readInt32

函数定义:[stream].InputStream.readInt32(tag, require, default)

函数作用:从数据流读取一个 Int32 类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

default

Int32

表示读取变量不成功时的返回值,取值范围[-2147483648, 2147483647]

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回变量的默认值 default;

返回数据:Int32,取值范围[-2147483648, 2147483647]

readInt64

函数定义:[stream].InputStream.readInt64(tag, require, default)

函数作用:从数据流读取一个 Int64 类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

default

Int64

表示读取变量不成功时的返回值,取值范围[-9223372036854775808, 9223372036854775807]

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回变量的默认值 default;

返回数据:Int64(Number),取值范围[-9223372036854775808, 9223372036854775807]

readUInt8

函数定义:[stream].InputStream.readUInt8(tag, require, default)

函数作用:从数据流读取一个 UInt8 类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

default

UInt8

表示读取变量不成功时的返回值,取值范围[0, 255]

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回变量的默认值 default;

返回数据:UInt8(Number),取值范围[0, 255]

readUInt16

函数定义:[stream].InputStream.readUInt16(tag, require, default)

函数作用:从数据流读取一个 UInt16 类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

default

UInt8

表示读取变量不成功时的返回值,取值范围[0, 65535]

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回变量的默认值 default;

返回数据:UInt16(Number),取值范围[0, 65535]

readUInt32

函数定义:[stream].InputStream.readUInt32(tag, require, default)

函数作用:从数据流读取一个 UInt32 类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

default

UInt8

表示读取变量不成功时的返回值,取值范围[0, 4294967295]

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回变量的默认值 default;

返回数据:UInt32(Number),取值范围[0, 4294967295]

readFloat

函数定义:[stream].InputStream.readFloat(tag, require, default)

函数作用:从数据流读取一个 Float(32 位,单精度浮点数)类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

default

Float

表示读取变量不成功时的返回值

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回变量的默认值 default;

返回数据:Float(Number)

readDouble

函数定义:[stream].InputStream.readFloat(tag, require, default)

函数作用:从数据流读取一个 Double(64 位,双精度浮点数)类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

default

Double

表示读取变量不成功时的返回值

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回变量的默认值 default;

返回数据:Double(Number)

readString

函数定义:[stream].InputStream.readString(tag, require, default)

函数作用:从数据流读取一个 String(UTF8 编码)类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

default

String

表示读取变量不成功时的返回值

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回变量的默认值 default;

返回数据:String(UTF8 编码)

readStruct

函数定义:[stream].InputStream.readStruct(tag, require, TYPE_T)

函数作用:从数据流读取一个自定义结构体类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

TYPE_T

自定义结构体的类型原型

表示该变量的类型原型

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回一个空的结构体的实例;

返回数据:自定义结构体的实例

readBytes

函数定义:[stream].InputStream.readBytes(tag, require, TYPE_T)

函数作用:从数据流读取一个 [stream].BinBuffer 类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

TYPE_T

[stream].BinBuffer

表示该变量的类型原型

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回一个空的[stream].BinBuffer 的实例;

返回数据:[stream].BinBuffer

readList

函数定义:[stream].InputStream.readList(tag, require, TYPE_T)

函数作用:从数据流读取一个 [stream].List<T> 类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

TYPE_T

[stream].List

表示该变量的类型原型

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回一个空的[stream].List(T)的实例;

返回数据:[stream].List(T)

readMap

函数定义:[stream].InputStream.readMap(tag, require, TYPE_T)

函数作用:从数据流读取一个 [stream].Map<T, V> 类型的数值

输入参数:

参数
数据类型
描述

tag

UInt8

表示欲读取变量的数字标识,取值范围[0, 255]

require

Boolean

表示当前变量是否为必须值,取值范围{false, true}

TYPE_T

[stream].Map(T, V)

表示该变量的类型原型

对 require 的说明:

require === true 时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常;

require === false 时,如果当前变量不在数据流中,系统将返回一个空的[stream].Map(T, V)的实例;

返回数据:[stream].Map(T, V)

Last updated

Was this helpful?