npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@lml_taf/taf-stream

v4.1.5

Published

A library for TAF Encode/Decode(JCE WUP)

Downloads

8

Readme

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中的类)| | 二进制Buffer | vector<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::vectorstd::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 | | 二进制Buffer | [taf-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 对象属性

| 属性 | 描述 | | ------------- | ------------- | | value | Js中的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 对象属性

| 属性 | 描述 | | ------------- | ------------- | | value | Js中的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类数据

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | srcBuffer | NodeJS.Buffer | 原始的Buffer数据 | | offset | UInt32 | 表示拷贝srcBuffer的起始位置 | | byteLength | UInt32 | 表示从offset开始,从srcBuffer中拷贝的数据量 |

函数说明:

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

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

writeBinBuffer

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | value | [taf-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类数据

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | value | Int8 | 8位的整型数据 |

函数说明:

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

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

writeInt16

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | value | Int16 | 16位的整型数据 |

函数说明:

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

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

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

writeInt32

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | value | Int32 | 32位的整型数据 |

函数说明:

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

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

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

writeInt64

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | value | Int64 | 64位的整型数据 | | bString | Boolean | 是否以字符串来表示数字写入 |

函数说明:

[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类数据

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | value | UInt8 | 8位的整型数据 |

函数说明:

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

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

writeUInt16

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | value | UInt16 | 16位的整型数据 |

函数说明:

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

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

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

writeUInt32

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | value | UInt32 | 32位的整型数据 |

函数说明:

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

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

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

writeFloat

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | value | Float | 32位的单精度浮点数 |

函数说明:

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

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

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

writeDouble

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | value | Double | 64位的双精度浮点数 |

函数说明:

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

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

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

writeString

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | value | String | UTF8编码的字符串 | | ByteLength | Int | 字符串的字节长度 | | bRaw | Boolean | 是否写入二进制数据 |

函数说明:

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

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

[3]bRaw为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)

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | bString | Boolean | 是否以字符串来表示数字读取 |

函数作用:从二进制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编码)类型的变量

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | byteLength | UInt32 | 字符串的字节长度 | | bRaw | Boolean | 是否读取二进制数据 |

函数说明:

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

readBinBuffer

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | byteLength | UInt32 | 二进制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类型的变量

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示该变量的数字标识,取值范围[0, 255] | | value | Boolean | 表示该变量的值,取值范围{false, true} |

返回数据:void

writeInt8

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示该变量的数字标识,取值范围[0, 255] | | value | int8(Number) | 表示该变量的值,取值范围[-128, 127] |

返回数据:void

writeInt16

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示该变量的数字标识,取值范围[0, 255] | | value | int16(Number) | 表示该变量的值,取值范围[-32768, 32767] |

返回数据:void

writeInt32

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示该变量的数字标识,取值范围[0, 255] | | value | int32(Number) | 表示该变量的值,取值范围[-2147483648, 2147483647] |

返回数据:void

writeInt64

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示该变量的数字标识,取值范围[0, 255] | | value | int64(Number) | 表示该变量的值,取值范围[-9223372036854775808, 9223372036854775807] | | bString | Boolean | 是否以字符串来表示数字写入 |

返回数据:void

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

writeUInt8

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示该变量的数字标识,取值范围[0, 255] | | value | UInt8(Number) | 表示该变量的值,取值范围[0, 255] |

返回数据:void

writeUInt16

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示该变量的数字标识,取值范围[0, 255] | | value | UInt16(Number) | 表示该变量的值,取值范围[0, 65535] |

返回数据:void

writeUInt32

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示该变量的数字标识,取值范围[0, 255] | | value | UInt32(Number) | 表示该变量的值,取值范围[0, 4294967295] |

返回数据:void

writeFloat

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

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

输入参数:

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

返回数据:void

writeDouble

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

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

输入参数:

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

返回数据:void

writeString

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示该变量的数字标识,取值范围[0, 255] | | value | String | 表示该变量的值,字符串编码字符集为UTF8 | | bRaw | Boolean | 是否写入二进制数据 |

返回数据:void

函数说明:

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

writeStruct

函数定义:writeStruct(tag, value)

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

输入参数:

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

返回数据:void

writeBytes

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

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

输入参数:

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

返回数据:void

writeList

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

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

函数参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示该变量的数字标识,取值范围[0, 255] | | value | [taf-stream].List(T) | 该变量的类型原型 |

返回数据:void

writeMap

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

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

函数参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示该变量的数字标识,取值范围[0, 255] | | value | [taf-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类型的数值

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示欲读取变量的数字标识,取值范围[0, 255] | | require | Boolean | 表示当前变量是否为必须值,取值范围{false, true} | | default | Boolean | 表示读取变量不成功时的返回值,取值范围{false, true} |

对require的说明:

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

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

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

readInt8

函数定义:[taf-stream].JceInputStream.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

函数定义:[taf-stream].JceInputStream.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

函数定义:[taf-stream].JceInputStream.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

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示欲读取变量的数字标识,取值范围[0, 255] | | require | Boolean | 表示当前变量是否为必须值,取值范围{false, true} | | default | Int64 | 表示读取变量不成功时的返回值,取值范围[-9223372036854775808, 9223372036854775807] | | bString | Boolean | 是否以字符串来读取数字 |

函数说明:

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

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

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

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

readUInt8

函数定义:[taf-stream].JceInputStream.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

函数定义:[taf-stream].JceInputStream.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

函数定义:[taf-stream].JceInputStream.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

函数定义:[taf-stream].JceInputStream.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

函数定义:[taf-stream].JceInputStream.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

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示欲读取变量的数字标识,取值范围[0, 255] | | require | Boolean | 表示当前变量是否为必须值,取值范围{false, true} | | default | String | 表示读取变量不成功时的返回值 | | bRaw | Boolean | 是否读取二进制数据 |

对require的说明:

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

返回数据:String(UTF8编码)

readStruct

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

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

输入参数:

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

对require的说明:

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

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

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

readBytes

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

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

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示欲读取变量的数字标识,取值范围[0, 255] | | require | Boolean | 表示当前变量是否为必须值,取值范围{false, true} | | TYPE_T | [taf-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> 类型的数值

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示欲读取变量的数字标识,取值范围[0, 255] | | require | Boolean | 表示当前变量是否为必须值,取值范围{false, true} | | TYPE_T | [taf-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> 类型的数值

输入参数:

| 参数 | 数据类型 | 描述 | | ------------- | ------------- | ------------- | | tag | UInt8 | 表示欲读取变量的数字标识,取值范围[0, 255] | | require | Boolean | 表示当前变量是否为必须值,取值范围{false, true} | | TYPE_T | [taf-stream].Map(T, V) | 表示该变量的类型原型 |

对require的说明:

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

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

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