在JavaScript (Node)中,我编写了一个模块,该模块接受字段列表及其类型,并返回具有pack
和unpack
方法的对象。下面是打包和解包IPv4的代码:
var ipv4 = proto.add('struct', {
name: 'IPV4',
fields: {
version: 'int:4',
ihl: 'int:4',
dscp: 'int:6',
ecn: 'int:2',
length: 'int:16',
id: 'int:16',
flags: 'int:3',
offset: 'int:13',
ttl: 'int:8',
protocol: 'int:8',
checksum: 'int:16',
src: 'IPV4_ADDR',
dst: 'IPV4_ADDR',
// TODO: IPv4 OPTIONS
options: 'raw'
},
$length: 'length'
});
//then I can do
ipv4.pack({ version: 4, ... }); //=> buffer
//and
ipv4.unpack(buffer); //=> { ... }
由于JavaScript是动态的,我可以元程序(合理地)优化pack
和unpack
函数。据我所知,你不能在Go中动态创建函数,尽管使用reflect
包似乎可以实现。这值得追求吗?或者使用reflect
会不会太贵?
我希望避免为我希望解析的每个网络协议编写这样的代码。
如果可以接受半动态的解决方案,那么您可以从众多为速度而设计的Golang JSON替代包中获得灵感。他们的方法是标记一个结构体,然后运行一个工具(例如,作为make配置的一部分)为所需类型生成MarshalJSON
和UnmarshalJSON
方法。这显然比使用标签要快。
一些帮助你的例子:
- https://github.com/pquerna/ffjson
- https://github.com/benbjohnson/megajson