Smalltalk的位语法

2020-10-08 09:15:53

当我在一个移动Smalltalk系统上工作时,我发现自己需要解码和编码许多复杂的电话数据包格式1,例如,传入的SMS Delivery消息,其中包含GSM 03.40格式的SMS-Delivery TPDU,该TPDU包含7位(!)。GSM 03.38-编码文本:

事实证明,要获得一部可以正常工作的手机,需要过多的这样的二进制格式。

我一开始手卷它们,但很快就变得太多了,所以我从Erlang那里大方地借用了一些东西,并为Smalltalk实现了BitSyntaxfor Smalltalk。(毕竟,我已经在为Smalltalk系统守护进程使用受Erlang影响的演员了!)。

我以前做过这件事,对于Sracket,还有很多其他类似的项目,比如JavaScript和OCaml。

BitSynTax包包括一个BitSyntaxCompiler类,该类解释BitSyntaxSpecification对象,生成合理高效的Smalltalk,用于解码和编码二进制结构,将字节映射到实例变量,然后再映射回来。

到编译代码的接口很简单。在为上述数据格式编译了BitSyntaxSpecification之后,我们可以直接分析示例消息:

例如,对于上述数据格式,我们将为SmsIncome类提供以下规范:

以及SmsAddress和SmsPdu的相应规范(此处出于空间原因省略),以及SmsPdu子类SmsPduDeliver的以下规范:

这些都不是平凡的例子;简单的例子很简单,而复杂的例子通常不需要手写代码就可以表达出来。EDSL是可扩展的,因此可以根据需要轻松添加更多的组合符和解析器类型。

电话分组格式在某些地方特别奇怪。七位文本编码?真的?对电话号码进行编码的多路。长度有时以八位字节表示,有时以半八位字节表示,有时以七位字节表示(!)。隐式填充。偶尔会将8位数据硬塞到消息的基于七位字节的部分中。比特字段到处都是。所有内容都是缩写,交叉引用到另一个文档。看着3gpp和gsm的规格让我回想起上一次我做电话的时候,大约20年前,…。*↩