[QAMF] QAMF 的基本用法示例

QAMF 是 QDAC 项目中的一个新成员,用来支持 AMF 格式的解析。受限于作者手头的 AMF 资料的欠缺,可能有些实现并不一定 100% 正确,如果大家在使用过程中发现什么问题,请提供一个具体的详细测试用例,并请说明:

1、原始需要解析或生成的数据包;

2、重现问题的测试程序

3、问题的具体描述

再次感谢大家对 QDAC 项目的支持,现在说明一下 QAMF 的基本用法:

1、解析一个带有协议头部的 AMF 格式数据流:

这种格式的数据流,带有完整的 AMF 协议头部,而不是单纯的数据内容。QAMF 提供了以下几种方式来完成解析:

  • Parse/TryParse
    TryParse 会尝试解析内存中的协议数据,如果无法正确解析,则返回 False,解析成功,则返回 True。而 Parse 则在解析失败时抛出异常。请根据实际需要选择。
  • LoadFromStream/LoadFromFile
    直接从流或文件中解析 AMF 数据。如果解析失败,则抛出异常。

这种格式的数据流的格式,包含三个组成部分:

  • 文件头
    文件头包含版本号:两个字节,代表协议的版本 00 03 代表是 AMF3, 00 00 代表 AMF 0。但实际上这个版本标记意义不大。因为默认的存贮是以AMF 0 数据开始,然后根据需要临时切换到 AMF3 格式的。
  • 头部列表
    首先是一个 BE 编码的16位无符号整数,来标记头部的数量。一般常见的数据包这里都是0,如果不是0,则后面是具体的协议头部定义:
    (1)、一个 AMF0 字符串来记录头部名称
    (2)、一个AMF0 数据实体记录具体的头部内容
  • 消息数据列表
    首先是一个 BE 编码的16位无符号整数,来标记消息的数量,然后后面跟具体的 AMF 0 格式的数据内容。常见的格式封装在这里直接以 0x11 开始,转入 AMF 3 格式的对象,也有的是以 AMF0 数组开始,然后数组里面是 AMF 3 格式的对象列表。

2、解析没有头部标记的纯消息数据流

这种格式的数据流,用户必需明确知道它是 AMF 0 还是 AMF 3 格式的,否则就会解析失败。QAMF 提供了两个函数分别对应这个解析:

  • ParseAMF3Data/TryParseAMF3Data
    解析 AMF 3 格式的数据内容,至于加 Try 的区别,参考上面的描述;
  • ParseAMF0Data/TryParseAMF0Data
    解析 AMF 0 格式的数据内容。

注意一点,解析时,会在 TQAMF 对象的 Messages 里创建一个子结点,然后将解析的结点保存到相应的子结点下面。

3、编码 AMF 数据流

QAMF 目前的内测版本编码存在一些限制,如:对象只会编码为动态内联的对象(格式标记为11),而不会支持 DSK等外部类别对象的编码。将来随着对格式的进一步理解,会考虑添加支持;

而编码为 AMF 数据流的函数为 Encode。它会返回一个 TBytes 类型的字节数组,来保存编码后的结果。SaveToStream/SaveToFile 实际上调用了它保存到流或文件当中。

这里,要注意:TQAMF 的 Encode 编码会包含头部,如果要不包含头部的结果,直接调用相应消息结点的 Encode 就可以了。比如下面的代码是带有协议头部的:

var
  AMF:TQAMF;
  ABytes:TBytes;
begin
AMF:=TQAMF.Create;
try
  ....
  ABytes:=AMF.Encode;
finally
  FreeAndNil(AMF);
end;
end;

而下面的代码将只包含第一个消息的数据体,而没有任何头部内容。

var
  AMF:TQAMF;
  ABytes:TBytes;
begin
AMF:=TQAMF.Create;
try
  ....
  ABytes:=AMF.Messages[0].Encode;
finally
  FreeAndNil(AMF);
end;
end;

4、结点的增、删、查、改

好吧,这块简单说一下:

  • 调用 Add 增加子结点,然后用 AsXXX 设置子结点的值,用 KeyAsXXX 设置子结点的键值。
  • 调用 Delete 删除指定的子结点,调用 Clear 清除所有的子结点。
  • 查找的实现暂时没有处理,将来会支持 ItemByName/ItemByPath/ItemByRegEx 接口(和 QJson一样:) )。
  • 修改类型的话,直接设置结点的 DataType 属性,修改值的话,用 AsXXX ,修改键的话,用 KeyAsXXX。

因为是内测的版本,现在主要是完成解析和编码这块,至于其它的,再根据需要一步步完善,包括将来的 RTTI 支持。

好了,源码是最好的老师,有问题读源码和格式规范吧。希望大家用得愉快。

 

分享到: