可以解析二进制!在Rebol 2中捕获二进制文件!而不是字符串!(如Rebol 3)



考虑以下内容:

>> bin: to-binary {Rebol}
== #{5265626F6C}
>> parse/all bin [s: to end]
== true

我期望s已经捕获了二进制序列的头,并且类型为binary !在Rebol 3中是这样的:

>> type? s
== binary!
>> s == bin
== true

在Rebol 2中,似乎parse必须将数据转换为字符串(或至少将二进制"成像"为字符串)!在引擎盖下,不比较相等)

>> type? s
== string!
>> s == bin
== false

因为Rebol 2不是Unicode,二进制字节串和字符串基本上是等价的。但是对于Rebol 3的Unicode,我猜测如果你写:

,你可能会得到非常不同的行为:
parse/all to-string bin [s: to end]

因为它会开始将多个字节序列解释为字符串编码,如果您真正想要的是未解释的字节,这将不起作用。: - (

如果你想写的代码在Rebol 2或Rebol 3中都能很好地解析二进制!你会如何解决这个问题?(理想情况下让Rebol 2更像3)

事实上,Rebol 2实际上只是将数据"成像"为STRING!不要复制它,注意下面的

>> bin: to-binary {Rebol}
== #{5265626F6C}
>> parse bin [s: (clear s)] 
== true
>> s
== ""
>> bin
== #{}

这是因为Rebol 2有可用于将字符串数据混叠为二进制数据的例程,反之亦然:as - binary和as - string。与它们的TO-BINARY和TO-STRING变体不同,它们实际上并不复制数据。

这里有一个你(嗯,嗯,我)可以尝试的想法…创建一个兼容函数(我们称之为bin-pos):

bin-pos: func [pos [binary! string!]] [
    return either string? pos [
        ;; we must be using r2, image the parse position back to binary
        as-binary pos
    ] [
        ;; just a no-op in r3, binary parse input yields binary parse positions
        pos
    ]
]

所以在上面的例子中,对于Rebol 2,正确的事情发生了,如果你在任何地方使用s,你代替bin-pos s:

>> type? (bin-pos s)
== binary!
>> (bin-pos s) == bin
== true

对于使用COPY方言单词并生成新字符串的情况,同样的技术将起作用…但也许应该使用不同的包装器名称。bin-capture ?

您可以在规则中添加一个解析操作,以确保捕获的数据是binary!:

>> bin: to binary! {Rebol}
>> parse/all bin [s: to end (s: to binary! s)]
>> type? s
== binary!

出于文档目的,您可以将此转换封装在ensure-binary帮助器中。

请注意,如果我对你答案的最后一段理解正确的话,这基本上就是你在那里提出的建议。但是,我认为即使没有copy,您也可以使用这种方法。)

最新更新