4.1.5 • Published 6 months ago

@lml_taf/taf-stream v4.1.5

Weekly downloads
-
License
UNLICENSED
Repository
-
Last release
6 months ago

00 - 安装

taf-stream模块发布在公司内部NPM镜像,NPM镜像参数设置的方法请参考KM文档 内部 Node.JS NPM 镜像使用方法

$ tnpm install @tencent/taf-stream

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

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

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

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

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

该Jce文件一般由后台开发制定,前台开发需向后台开发索求经评审确认的jce文件,然后经工具转换成适用于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.jce”后,可以使用如下的命令生成不同的文件:

$ jce2node Protocol.jce

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

$ jce2node Protocol.jce --client

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

$ jce2node Protocol.jce --server

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

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

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

//第一步,引入JCE/WUP编解码库
var Taf = require("@tencent/taf-stream");

//第二步,客户端按照服务端要求,对输入参数进行编码
var ost = new Taf.JceOutputStream();
ost.writeUInt32(0, 155069599);		//写入“用户号码”;在服务端“0”代表“用户号码”。
ost.writeString(1, "KevinTian");	//写入“用户昵称”;在服务端“1”代表“用户昵称”。
ost.writeUInt32(2, 1002121);		//写入“商品编号”;在服务端“2”代表“商品编号”。
ost.writeUInt32(3, 10);				//写入“商品数量”;在服务端“3”代表“商品数量”。

//第三步,客户端将打包后的二进制Buffer发送给服务端
send(ost.getBinBuffer().toNodeBuffer())
to
server

//第四步,服务端从客户端接收完整的请求二进制Buffer
recv(
var requestBuffer = new Buffer()
)
from
client

//第五步,将该请求进行解码反序列化
var ist = new Taf.JceInputStream(new Taf.BinBuffer(requestBuffer));

var uin = ist.readUInt32(0, true);	//根据编号“0”读取“用户号码”。
var name = ist.readString(1, true);	//根据编号“1”读取“用户昵称”。
var gid = ist.readUInt32(2, true);	//根据编号“2”读取“商品编号”。
var num = ist.readUInt32(3, true);	//根据编号“3”读取“商品数量”。

//第六步,根据相关传入参数进行相应的逻辑操作
console.log("name:", name);
console.log("num :", num);
......

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

//第一步,引入JCE/WUP编解码库
var Taf = require("@tencent/taf-stream");

//第二步,客户端按照服务端要求,对输入参数进行编码
var wup_encode = new Taf.Wup();
wup_encode.writeUInt32("uin",  155069599);		//服务端接口函数“用户号码”的变量名称为“uin”。
wup_encode.writeString("name", "KevinTian");	//服务端接口函数“用户昵称”的变量名称为“name”。
wup_encode.writeUInt32("gid",  1002121);		//服务端接口函数“商品编号”的变量名称为“gid”。
wup_encode.writeUInt32("num",  10);				//服务端接口函数“商品数量”的变量名称为“uum”。

var BinBuffer = wup_encode.encode(true);

//第三步,客户端将打包后的二进制Buffer发送给服务端
send ( BinBuffer.toNodeBuffer() ) to server

//第四步,服务端从客户端接收完整的请求二进制Buffer
recv ( var requestBuffer = new Buffer() ) from client

//第五步,将该请求进行解码反序列化
var wup_decode = new Taf.Wup();
wup_decode.decode(new Taf.BinBuffer(requestBuffer));

var uin  = wup_decode.readUInt32("uin");		//服务端根据变量名“uin”读取“用户号码”。
var name = wup_decode.readString("name");		//服务端根据变量名“name”读取“用户昵称”。
var num  = wup_decode.readUInt32("num");		//服务端根据变量名“gid”读取“商品编号”。
var gid  = wup_decode.readUInt32("gid");		//服务端根据变量名“num”读取“商品数量”。

//第六步,根据相关传入参数进行相应的逻辑操作
console.log("name:", name);
console.log("num :", num);
......

02 - taf-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(在TAF框架中需要使用jce2node根据Jce文件来生成Javascript中的类)
二进制Buffervector<char>(在NodeJs中使用taf-stream.BinBuffer类型来模拟)
数组vector<DataType>(在NodeJs中使用taf-stream.List(vproto)类型来模拟)
词典map<KeyType, DataType>(在NodeJs中使用taf-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次方的整数。

当需要表示绝对值大于等于2的53次方的整数时,可以在读写int64类型数据的函数参数中,将bString参数设置为true,用字符串来表示超过精度范围的整数,详见后面writeInt64与readInt64函数的描述。

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

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

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

03 - 基本类型使用方法

//必须引入taf-stream模块
var Taf = require("@tencent/taf-stream");

//使用Taf.JceOutputStream对数据进行序列化
var os = new Taf.JceOutputStream();

os.writeBoolean(0, false);
os.writeInt8(1, 10);
os.writeInt16(2, 32767);
os.writeInt32(3, 0x7FFFFFFE);
os.writeInt64(4, 8589934591);
os.writeUInt8(5, 200);
os.writeUInt16(6, 65535);
os.writeUInt32(7, 0xFFFFFFEE);
os.writeString(8, "我的测试程序");

//使用Taf.JceInputStream对数据进行反序列化
var is = new Taf.JceInputStream(os.getBinBuffer());

var tp0 = is.readBoolean(0, true, false);
console.log("BOOLEAN:", tp0);

var tp1 = is.readInt8(1, true, 0);
console.log("INT8:", tp1);

var tp2 = is.readInt16(2, true, 0);
console.log("INT16:", tp2);

var tp3 = is.readInt32(3, true, 0);
console.log("INT32:", tp3);

var tp4 = is.readInt64(4, true, 0);
console.log("INT64:", tp4);

var tp5 = is.readUInt8(5, true, 0);
console.log("UINT8:", tp5);

var tp6 = is.readUInt16(6, true, 0);
console.log("UINT16:", tp6);

var tp7 = is.readUInt32(7, true, 0);
console.log("UINT32:", tp7);

var tp8 = is.readString(8, true, "");
console.log("STRING:", tp8);

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

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

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

#include <string>
#include <vector>

std::vector<std::string> vec;
vec.push_back("qzone");
vec.push_back("wechat");

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

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

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

var Taf = require("@tencent/taf-stream");

var abc = new Taf.List(Taf.String);
abc.push("qzone");
abc.push("wechat");

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

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

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

数据类型描述
布尔值taf-stream.Boolean
整型taf-stream.Int8, taf-stream.Int16, taf-stream.32, taf-stream.64, taf-stream.UInt8, taf-stream.UInt16, taf-stream.UInt32
数值taf-stream.Float, taf-stream.Double
字符串taf-stream.String
枚举值taf-stream.Enum
数组taf-stream.List
字典taf-stream.Map
二进制Buffertaf-stream.BinBuffer

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

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

var Taf = require("@tencent/taf-stream");

//c++语法:std::vector<int>
var abc = new Taf.List(Taf.Int32)
abc.push(10000);
abc.push(10001);

//c++语法:std::vector<std::vector<std::string> >
var abc = new Taf.List(Taf.List(Taf.String));
var ta = new Taf.List(Taf.String);
ta.push("ta1");
ta.push("ta2");
var tb = new Taf.List(Taf.String);
tb.push("tb1");
tb.push("tb2");
abc.push(ta);
abc.push(tb);

//c++语法:std::map<std::string, std::string>
var abc = new Taf.Map(Taf.String, Taf.String);
abc.insert("key1", "value1");
abc.insert("key2", "value2");

//c++语法:std::map<std::string, std::vector<string> >
var abc = new Taf.Map(Taf.String, Taf.List(Taf.String));
var ta = new Taf.List(Taf.String);
ta.push("ta1");
ta.push("ta2");
var tb = new Taf.List(Taf.String);
tb.push("tb1");
tb.push("tb2");
abc.insert("key_a", ta);
abc.insert("key_b", tb);

//c++语法:std::vector<char>
var abc = new Taf.BinBuffer();
abc.writeInt32(10000);
abc.writeInt32(10001);

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

module Ext
{
    struct ExtInfo  {
        0 optional string sUserName;
        1 optional map<string, vector<byte> > data;
        2 optional map<string, map<string, vector<byte> > > cons;
    };
};

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

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

var TafStream = require("@tencent/taf-stream");

var Ext = Ext || {};
module.exports.Ext = Ext;

Ext.ExtInfo = function () {
  this.sUserName = "";
  this.data = new TafStream.Map(TafStream.String, TafStream.BinBuffer);
  this.cons = new TafStream.Map(TafStream.String, TafStream.Map(TafStream.String, TafStream.BinBuffer));
};
Ext.ExtInfo._write = function (os, tag, value) {
  os.writeStruct(tag, value);
}
Ext.ExtInfo._read = function (is, tag, def) {
  return is.readStruct(tag, true, def);
}
Ext.ExtInfo._readFrom = function (is) {
  var tmp = new Ext.ExtInfo();
  tmp.sUserName = is.readString(0, false, "");
  tmp.data = is.readMap(1, false, TafStream.Map(TafStream.String, TafStream.BinBuffer));
  tmp.cons = is.readMap(2, false, TafStream.Map(TafStream.String, TafStream.Map(TafStream.String, TafStream.BinBuffer)));
  return tmp;
};
Ext.ExtInfo.prototype._writeTo = function (os) {
  os.writeString(0, this.sUserName);
  os.writeMap(1, this.data);
  os.writeMap(2, this.cons);
};
Ext.ExtInfo.prototype._equal = function (anItem) {
  return anItem.sUserName === this.sUserName
    && anItem.data === this.data
    && anItem.cons === this.cons;
}
Ext.ExtInfo.prototype._genKey = function () {
  if (!this._proto_struct_name_) {
    this._proto_struct_name_ = 'STRUCT' + Math.random();
  }
  return this._proto_struct_name_;
}
Ext.ExtInfo.prototype.toBinBuffer = function () {
  var os = new TafStream.JceOutputStream();
  this._writeTo(os);
  return os.getBinBuffer();
}
Ext.ExtInfo.create = function (is) {
  return Ext.ExtInfo._readFrom(is);
}

对“module Ext”的说明

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

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

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

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

方法限制描述
_write开发者不可用静态函数。当结构体用作类型原型时使用。
_read开发者不可用静态函数。当结构体用作类型原型时使用。
_readFrom开发者不可用静态函数。从数据流中读取结构体的数据成员值,并生成一个权限的结构体示例返回。
_writeTo开发者不可用成员函数。将当前结构体的数据成员写入指定的数据流中。
_equal开发者不可用成员函数。将当前结构体用作字典类型Key值时的比较函数。
_genKey开发者不可用成员函数。将当前结构体用作字典类型Key值时,内部使用该函数获得当前结构体的别名。
toBinBuffer开发者可用成员函数。将当前结构体序列化成二进制Buffer,返回值类型为require("@tencent/taf-stream").BinBuffer。
create开发者可用成员函数。从数据流中返回一个全新的结构体。

结构体的使用示例

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

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

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

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

module TRom
{
    struct Param  {
        0 optional string sUserName;
        1 optional int iId;
    };

	interface process {
		int getUserLevel(Param userInfo, out int iLevel);
	};
};}

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

var Taf = require("@tencent/taf-rpc").client;
var TRom = require("./ProtocolJce.js").TRom;

var prx = Taf.stringToProxy(TRom.NodeJsCommProxy, "TRom.NodeJsTestServer.NodeJsCommObj@tcp -h 10.12.22.13 -p 8080  -t 60000");

var usr = new TRom.Param();
usr.sUserName = "KevinTian";
usr.iId = 10000;

prx.getUserLevel(usr).then(function (result) {
  console.log("success:", result);
}, function (result) {
  console.log("error:", result);
}).done();

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

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

//客户端安装如下方法进行打包,然后将打包后的二进制数据流发送到服务端
var Taf  = require("@tencent/taf-stream");
var TRom = require("./ProtocolJce.js").TRom;

var usr  = new TRom.Param();
usr.sUserName = "KevinTian";
usr.iId       = 10000;

var os = new Taf.JceOutputStream();
os.writeStruct(1, usr);

//打包并得到发送的二进制数据流
var toSendBuffer = os.getBinBuffer().toNodeBuffer();

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

var Taf = require("@tencent/taf-stream");
var TRom = require("./ProtocolJce.js").TRom;

var is = new Taf.JceInputStream(new Taf.BinBuffer(toSendBuffer));
var usr = is.readStruct(1, true, TRom.Param);

console.log("TRom.Param.sUserName:", usr.sUserName);
console.log("TRom.Param.iId:", usr.iId);

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

//客户端根据约定的名字,将结构体放入Wup中
var Taf = require("@tencent/taf-stream");
var TRom = require("./ProtocolJce.js").TRom;

var usr = new TRom.Param();
usr.sUserName = "KevinTian";
usr.iId = 10000;

var wup_encode = new Taf.Wup();
wup_encode.writeStruct("userInfo", usr);

//打包并得到发送的二进制数据流
var toSendBuffer = wup_encode.encode(true).toNodeBuffer();

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

var Taf = require("@tencent/taf-stream");
var TRom = require("./ProtocolJce.js").TRom;

var wup_decode = new Taf.Wup();
wup_decode.decode(new Taf.BinBuffer(toSendBuffer));

var usr = wup_decode.readStruct("userInfo", TRom.Param);

console.log("TRom.Param.sUserName:", usr.sUserName);
console.log("TRom.Param.iId:", usr.iId);

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

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

[taf - stream].List = function (proto, bValue) {
  this.proto = proto;
  this.value = new Array();
  this.push = function (value) {
    this.value.push(value);
  }
......
}

构造函数中,proto为List中存储的数据类型;bValue用来设置List中存储的数据是否需要做格式转换,例如将非utf8编码格式的字符串用buffer来表示,long类型用字符串来表示。

bValue取值为0时,表示不转换,bValue取值为1时,表示转换,默认为0。例如:

new TafStream.List(TafStream.String, 1); // 字符串会使用buffer来表示
new TafStream.List(TafStram.Int64, 1);   // long字段将用字符串来表示,防止精度丢失

taf-stream.List 对象属性

属性描述
valueJs中的Array数据类型。Taf.List实际是基于该Array进行的上层封装。
length返回数组中元素的数目。

taf-stream.List 对象方法

方法描述
at返回数组中指定位置的元素。
push向数组的末尾添加一个元素。
forEach当前数组的遍历方法,具体使用方法请参考后面的示例。
toObject将List实例转化成基本的数据对象,具体使用方法请参考后面的示例。
readFromObject将传入的数组处理后push到List实例中,具体使用方法请参考后面的示例。

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

taf-stream.List的声明示例

var Taf = require("@tencent/taf-stream");

//例子1:声明vector<int32>
var va = new Taf.List(Taf.Int32);

//例子2:声明vector<string>
var vb = new Taf.List(Taf.String);

//例子3:声明vector<map<uint32, string> >
var vc = new Taf.List(Taf.Map(Taf.UInt32, Taf.String));

//例子4:声明vector<struct>,假设结构体名称为TRom.Param
var vd = new Taf.Vector(TRom.Param);

taf-stream.List的操作示例

var Taf = require("@tencent/taf-stream");

var ve = new Taf.List(Taf.String);

//向数组中添加元素
ve.push("TENCENT-MIG");
ve.push("TENCENT-SNG");
ve.push("TENCENT-IEG");
ve.push("TENCENT-TEG");

//获取数组的长度
console.log("Length:", ve.length);

//获取指定位置的元素
console.log("Array[1]:", ve.at(1));

//遍历方法1:
ve.forEach(function (value, index, oArray) {
  console.log("Array[" + index + "]:", value);
});

// 遍历方法2:
for (var index = 0, len = ve.length; index < len; index++) {
  console.log("Array[" + index + "]:", ve.at(index));
}

// toObject方法和readFromObject方法的详细例子可以参照sample/list路径下的test-list-c3.js文件
var user1 = new TRom.User_t();
user1.id = 1;
user1.name = 'x1';
user1.score = 1;

var user2 = new TRom.User_t();
user2.id = 2;
user2.name = 'x2';
user2.score = 2;

var user3 = new TRom.User_t();
user3.id = 3;
user3.name = 'x3';
user3.score = 3;

var userList1 = new Taf.List(TRom.User_t);

console.log('user1: ', user1);
console.log('user2: ', user2);

userList1.push(user1);
userList1.push(user2);

//toObject方法
console.log('userList1: ', userList1.toObject());

var userList2 = new Taf.List(TRom.User_t);
//readFromObject方法
userList2.readFromObject([user1, user2, user3]);
console.log('userList2: ', userList2.toObject());

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

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

[taf - stream].Map = function (kproto, vproto, bKey, bValue) {
  var Map = function () {
    this._kproto = kproto;
    this._vproto = vproto;
    this.value = new Object();
    this.put = function (key, value) {
      this.insert(key, value);
    }
  ......
  }

  return new Map();
}

构造函数中,kproto的数据类型,vproto为value的数据类型;bKey用来key中的数据是否需要做格式转换, bValue用来设置value中的数据是否需要做格式转换,例如将非utf8编码格式的字符串用buffer来表示,long类型用字符串来表示。

bKey和bValue取值为0时,表示不转换,取值为1时,表示转换,默认为0。例如:

new TafStream.Map(TafStream.Int64, TafStream.String, 1, 1); //Int64类型会用字符串表示, 字符串会使用buffer来表示

taf-stream.Map 对象属性

属性描述
valueJs中的Object数据类型。taf-stream.Map实际是基于该Object进行的上层封装。

taf-stream.Map 方法属性

方法描述
insert向字典中添加一个元素。
set同insert。
put同insert。
remove根据指定的key,从字典中删除对应的数值。
clear清空当前字典。
has根据指定的key,判断字典中是否包含对应的数值。
size返回当前字典中元素的数目。
forEach当前数组的遍历方法,具体使用方法请参考后面的示例。
toObject将Map实例转化成基本的数据对象,具体使用方法请参考后面的示例。
readFromObject将传入的对象处理后insert到Map实例中,具体使用方法请参考后面的示例。

taf-stream.Map的声明示例

var Taf = require("@tencent/taf-stream");

//例子1:声明map<int32, int32>
var ma = new Taf.Map(Taf.Int32, Taf.Int32);

//例子2:声明map<uint32, string>
var mb = new Taf.Map(Taf.Int32, Taf.String);

//例子3:声明map<string, string>的方法
var mc = new Taf.Map(Taf.String, Taf.String);

//例子4:声明map<string, vector<int32> >
var md = new Taf.Map(Taf.String, Taf.List(Taf.Int32));

//例子5:声明map<string, map<int32, vector<string> > >
var me = new Taf.Map(Taf.String, Taf.Map(Taf.Int32, Taf.List(Taf.String)));

//例子6:声明map<string, struct>的方法,假设结构体名称为TRom.Param
var mf = new Taf.map(Taf.String, TRom.Param);

taf-stream.Map的操作示例

var Taf = require("@tencent/taf-stream");

var mc = new Taf.Map(Taf.String, Taf.String);

//向字典中添加元素
mc.insert("KEY-00", "TENCENT-MIG");
mc.insert("KEY-01", "TENCENT-IEG");
mc.insert("KEY-02", "TENCENT-TEG");
mc.insert("KEY-03", "TENCENT-SNG");

//获取字典元素大小
console.log("SIZE:", mc.size());

//判断字典中是否有指定的值
console.log("Has:", mc.has("KEY-04"));

//字典遍历
mc.forEach(function (key, value) {
  console.log("KEY:", key);
  console.log("VALUE:", value);
});

// toObject方法和readFromObject方法的详细例子可以参照sample/map路径下的test-map-c5.js文件
var user1 = new TRom.User_t();
user1.id = 1;
user1.name = 'x1';
user1.score = 1;

var user2 = new TRom.User_t();
user2.id = 2;
user2.name = 'x2';
user2.score = 2;

var user3 = new TRom.User_t();
user3.id = 3;
user3.name = 'x3';
user3.score = 3;

var userMap1 = new Taf.Map(Taf.String, TRom.User_t);

userMap1.insert('user1', user1);
userMap1.insert('user2', user2);

//toObject方法
console.log('userMap1: ', userMap1.toObject());

var userMap2 = new Taf.Map(Taf.String, TRom.User_t);
//readFromObject方法
userMap2.readFromObject({
  'user1': user1,
  'user2': user2,
  'user3': user3
});
console.log('userMap2: ', userMap2.toObject());

支持MultiMap类型

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

其操作实例如下:

//构造Map类型
var msg = new Taf.Map(Test.StatMicMsgHead, Test.StatMicMsgBody);
msg.put(StatMicMsgHead1, StatMicMsgBody1);
msg.put(StatMicMsgHead2, StatMicMsgBody2);

//JCE编码
var os = new Taf.JceOutputStream();
os.writeMap(1, msg);

//JCE解码
var data = os.getBinBuffer().toNodeBuffer();

var is = new Taf.JceInputStream(new Taf.BinBuffer(data));
var ta = is.readMap(1, true, Taf.Map(Test.StatMicMsgHead, Test.StatMicMsgBody));

//遍历Map结果集
ta.forEach(function (key, value) {
  console.log("KEY:", key.masterName, "VALUE.totalRspTime", value.totalRspTime);
});

//根据值去获取
var tb = ta.get(StatMicMsgHead2);
if (tb == undefined) {
  console.log("not found by name : StatMicMsgHead2");
} else {
  console.log(tb.totalRspTime);
}

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

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

[taf - stream].BinBuffer = function (buffer) {
  this._buffer = (buffer != undefined && buffer instanceof Buffer) ? buffer : null;
  this._length = (buffer != undefined && buffer instanceof Buffer) ? buffer.length : 0;
  this._capacity = this._length;
  this._position = 0;
}

taf-stream.BinBuffer 对象属性

属性描述
length获取该二进制Buffer的数据长度
capacity获取该二进制Buffer在不重新分配内存的情况下,可容纳数据的最大长度
position获取或者设置当前二进制Buffer的访问指针

length和capacity的区别:

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

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

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

taf-stream.BinBuffer 方法属性

toNodeBuffer

函数定义;taf-stream.BinBuffer.toNodeBuffer()

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

输入参数:无

返回数据:NodeJS.Buffer类型

print

函数定义:taf-stream.BinBuffer.print()

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

writeNodeBuffer

函数定义:taf-stream.BinBuffer.writeNodeBuffer(srcBuffer, offset, byteLength)

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

输入参数:

参数数据类型描述
srcBufferNodeJS.Buffer原始的Buffer数据
offsetUInt32表示拷贝srcBuffer的起始位置
byteLengthUInt32表示从offset开始,从srcBuffer中拷贝的数据量

函数说明:

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

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

writeBinBuffer

函数定义:taf-stream.BinBuffer.writeBinBuffer(value)

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

输入参数:

参数数据类型描述
valuetaf-stream.BinBuffer表示二进制Buffer

函数说明:

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

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

writeInt8

函数定义:taf-stream.BinBuffer.writeInt8(value)

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

输入参数:

参数数据类型描述
valueInt88位的整型数据

函数说明:

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

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

writeInt16

函数定义:taf-stream.BinBuffer.writeInt16(value)

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

输入参数:

参数数据类型描述
valueInt1616位的整型数据

函数说明:

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

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

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

writeInt32

函数定义:taf-stream.BinBuffer.writeInt32(value)

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

输入参数:

参数数据类型描述
valueInt3232位的整型数据

函数说明:

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

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

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

writeInt64

函数定义:taf-stream.BinBuffer.writeInt64(value, bString)

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

输入参数:

参数数据类型描述
valueInt6464位的整型数据
bStringBoolean是否以字符串来表示数字写入

函数说明:

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

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

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

4写入绝对值大于2^53-1的数字时,需要将bString设为true并使用字符串表示数字,方可保持精度

writeUInt8

函数定义:taf-stream.BinBuffer.writeUInt8(value)

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

输入参数:

参数数据类型描述
valueUInt88位的整型数据

函数说明:

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

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

writeUInt16

函数定义:taf-stream.BinBuffer.writeUInt16(value)

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

输入参数:

参数数据类型描述
valueUInt1616位的整型数据

函数说明:

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

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

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

writeUInt32

函数定义:taf-stream.BinBuffer.writeUInt32(value)

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

输入参数:

参数数据类型描述
valueUInt3232位的整型数据

函数说明:

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

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

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

writeFloat

函数定义:taf-stream.BinBuffer.writeFloat(value)

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

输入参数:

参数数据类型描述
valueFloat32位的单精度浮点数

函数说明:

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

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

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

writeDouble

函数定义:taf-stream.BinBuffer.writeDouble(value)

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

输入参数:

参数数据类型描述
valueDouble64位的双精度浮点数

函数说明:

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

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

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

writeString

函数定义:taf-stream.BinBuffer.writeString(value)

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

输入参数:

参数数据类型描述
valueStringUTF8编码的字符串
ByteLengthInt字符串的字节长度
bRawBoolean是否写入二进制数据

函数说明:

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

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

3bRaw为true时,代表value为一个buffer,以写入非UTF8编码的字符串

readInt8

函数定义:taf-stream.BinBuffer.readInt8()

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

输入参数:无

函数说明:

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

readInt16

函数定义:taf-stream.BinBuffer.readInt16()

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

输入参数:无

函数说明:

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

readInt32

函数定义:taf-stream.BinBuffer.readInt32()

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

输入参数:无

函数说明:

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

readInt64

函数定义:taf-stream.BinBuffer.readInt64(bString)

参数数据类型描述
bStringBoolean是否以字符串来表示数字读取

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

输入参数:无

函数说明:

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

readUInt8

函数定义:taf-stream.BinBuffer.readUInt8()

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

输入参数:无

函数说明:

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

readUInt16

函数定义:taf-stream.BinBuffer.readUInt16()

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

输入参数:无

函数说明:

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

readUInt32

函数定义:taf-stream.BinBuffer.readUInt32()

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

输入参数:无

函数说明:

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

readFloat

函数定义:taf-stream.BinBuffer.readFloat()

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

输入参数:无

函数说明:

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

readDouble

函数定义:taf-stream.BinBuffer.readDouble()

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

输入参数:无

函数说明:

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

readString

函数定义:taf-stream.BinBuffer.readString(byteLength)

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

输入参数:

参数数据类型描述
byteLengthUInt32字符串的字节长度
bRawBoolean是否读取二进制数据

函数说明:

1当前BinBuffer的 position = position(原Buffer的位置指针) + 字符串的字节长度 2后台对字符串的编码需要使用UTF8字符集 3bRaw为true时,可读取二进制数据,以读出非UTF8编码的数据

readBinBuffer

函数定义:taf-stream.BinBuffer.readBinBuffer(byteLength)

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

输入参数:

参数数据类型描述
byteLengthUInt32二进制Buffer的字节长度

函数说明:

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

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

构造函数

函数定义:taf-stream.JceOutputStram()

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

输入参数:无

使用示例:var os = new taf-stream.JceOutputStream()

getBinBuffer

函数定义:var buffer = taf-stream.JceOutputStream.getBinBuffer()

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

输入参数:无

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

writeBoolean

函数定义:taf-stream.JceOutputStream.writeBoolean(tag, value)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valueBoolean表示该变量的值,取值范围{false, true}

返回数据:void

writeInt8

函数定义:taf-stream.JceOutputStream.writeInt8(tag, value)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valueint8(Number)表示该变量的值,取值范围-128, 127

返回数据:void

writeInt16

函数定义:taf-stream.JceOutputStream.writeInt16(tag, value)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valueint16(Number)表示该变量的值,取值范围-32768, 32767

返回数据:void

writeInt32

函数定义:taf-stream.JceOutputStream.writeInt32(tag, value)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valueint32(Number)表示该变量的值,取值范围-2147483648, 2147483647

返回数据:void

writeInt64

函数定义:taf-stream.JceOutputStream.writeInt64(tag, value, bString)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valueint64(Number)表示该变量的值,取值范围-9223372036854775808, 9223372036854775807
bStringBoolean是否以字符串来表示数字写入

返回数据:void

函数说明: 1写入绝对值大于2^53-1的数字时,需要将bString设为true并使用字符串表示数字,方可保持精度

writeUInt8

函数定义:taf-stream.JceOutputStream.writeUInt8(tag, value)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valueUInt8(Number)表示该变量的值,取值范围0, 255

返回数据:void

writeUInt16

函数定义:taf-stream.JceOutputStream.writeUInt16(tag, value)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valueUInt16(Number)表示该变量的值,取值范围0, 65535

返回数据:void

writeUInt32

函数定义:taf-stream.JceOutputStream.writeUInt32(tag, value)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valueUInt32(Number)表示该变量的值,取值范围0, 4294967295

返回数据:void

writeFloat

函数定义:taf-stream.JceOutputStream.writeFloat(tag, value)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valueFloat(Number)单精度浮点数,因为有精度损失问题,不推荐使用该类型

返回数据:void

writeDouble

函数定义:taf-stream.JceOutputStream.writeDouble(tag, value)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valueDouble(Number)双精度浮点数,因为有精度损失问题,不推荐使用该类型

返回数据:void

writeString

函数定义:taf-stream.JceOutputStream.writeString(tag, value)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valueString表示该变量的值,字符串编码字符集为UTF8
bRawBoolean是否写入二进制数据

返回数据:void

函数说明:

1 bRaw为true时,代表value为一个buffer,以写入非UTF8编码的字符串

writeStruct

函数定义:writeStruct(tag, value)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
value自定义结构体结构体必须是使用jce2node转换而成的,否则可能会因缺少辅助函数而导致编解码失败

返回数据:void

writeBytes

函数定义:taf-stream.JceOutputStream.writeBytes(tag, value)

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

输入参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valuetaf-stream.BinBufferBinBuffer是对NodeJs中的Buffer类的封装,同时集成了编解码需要用到的辅助函数

返回数据:void

writeList

函数定义:taf-stream.JceOutputStream.writeList(tag, value)

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

函数参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valuetaf-stream.List(T)该变量的类型原型

返回数据:void

writeMap

函数定义:taf-stream.JceOutputStream.writeMap(tag, value)

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

函数参数:

参数数据类型描述
tagUInt8表示该变量的数字标识,取值范围0, 255
valuetaf-stream.Map(T, V)该变量的类型原型

返回数据:void

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

构造函数

函数定义:taf-stream.JceInputStream(binBuffer)

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

输入参数:

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

使用示例:var is = new taf-stream.JceInputStream(new taf-stream.BinBuffer(Node.Buffer))

readBoolean

函数定义:var value = taf-stream.JceInputStream.readBoolean(tag, require, default)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
defaultBoolean表示读取变量不成功时的返回值,取值范围{false, true}

对require的说明:

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

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

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

readInt8

函数定义:taf-stream.JceInputStream.readInt8(tag, require, default)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
defaultInt8表示读取变量不成功时的返回值,取值范围-128, 127

对require的说明:

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

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

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

readInt16

函数定义:taf-stream.JceInputStream.readInt16(tag, require, default)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
defaultInt16表示读取变量不成功时的返回值,取值范围-32768, 32767

对require的说明:

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

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

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

readInt32

函数定义:taf-stream.JceInputStream.readInt32(tag, require, default)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
defaultInt32表示读取变量不成功时的返回值,取值范围-2147483648, 2147483647

对require的说明:

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

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

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

readInt64

函数定义:taf-stream.JceInputStream.readInt64(tag, require, default, bString)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
defaultInt64表示读取变量不成功时的返回值,取值范围-9223372036854775808, 9223372036854775807
bStringBoolean是否以字符串来读取数字

函数说明:

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

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

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

读取绝对值大于2^53-1的数字时,需要将bString设为true,方可保持精度

readUInt8

函数定义:taf-stream.JceInputStream.readUInt8(tag, require, default)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
defaultUInt8表示读取变量不成功时的返回值,取值范围0, 255

对require的说明:

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

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

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

readUInt16

函数定义:taf-stream.JceInputStream.readUInt16(tag, require, default)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
defaultUInt8表示读取变量不成功时的返回值,取值范围0, 65535

对require的说明:

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

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

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

readUInt32

函数定义:taf-stream.JceInputStream.readUInt32(tag, require, default)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
defaultUInt8表示读取变量不成功时的返回值,取值范围0, 4294967295

对require的说明:

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

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

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

readFloat

函数定义:taf-stream.JceInputStream.readFloat(tag, require, default)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
defaultFloat表示读取变量不成功时的返回值

对require的说明:

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

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

返回数据:Float(Number)

readDouble

函数定义:taf-stream.JceInputStream.readFloat(tag, require, default)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
defaultDouble表示读取变量不成功时的返回值

对require的说明:

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

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

返回数据:Double(Number)

readString

函数定义:taf-stream.JceInputStream.readString(tag, require, default)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
defaultString表示读取变量不成功时的返回值
bRawBoolean是否读取二进制数据

对require的说明:

require === true   时, 如果当前变量不在数据流中,系统将抛出一个读取数据不存在的异常; 当 require === false 时,如果当前变量不在数据流中,系统将返回变量的默认值default; 当bRaw为true时,读出二进制数据,以读取非UTF8编码的数据;

返回数据:String(UTF8编码)

readStruct

函数定义:taf-stream.JceInputStream.readStruct(tag, require, TYPE_T)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
TYPE_T自定义结构体的类型原型表示该变量的类型原型

对require的说明:

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

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

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

readBytes

函数定义:taf-stream.JceInputStream.readBytes(tag, require, TYPE_T)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
TYPE_Ttaf-stream.BinBuffer表示该变量的类型原型

对require的说明:

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

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

返回数据:taf-stream.BinBuffer

readList

函数定义:taf-stream.JceInputStream.readList(tag, require, TYPE_T)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
TYPE_Ttaf-stream.List表示该变量的类型原型

对require的说明:

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

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

返回数据:taf-stream.List(T)

readMap

函数定义:taf-stream.JceInputStream.readMap(tag, require, TYPE_T)

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

输入参数:

参数数据类型描述
tagUInt8表示欲读取变量的数字标识,取值范围0, 255
requireBoolean表示当前变量是否为必须值,取值范围{false, true}
TYPE_Ttaf-stream.Map(T, V)表示该变量的类型原型

对require的说明:

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

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

返回数据:taf-stream.Map(T, V)