带有替换的Blob.decode似乎不起作用

时间:2019-03-26 08:57:29

标签: encoding perl6

此代码:

my $þor-blob = Blob.new("þor".ords);
$þor-blob.decode( "ascii", :replacement("0"), :strict(False) ).say

失败:

Will not decode invalid ASCII (code point > 127 found)␤

还有一个:

my $euro = Blob.new("3€".ords);
$euro.decode( "latin1", :replacement("euro") ).say

似乎根本行不通,用¬代替€。

those methods are not tested是正确的,但是语法正确吗?

1 个答案:

答案 0 :(得分:7)

TL; DR

  • 只有samcv或其他核心开发人员才能提供权威的答案。这是我对所看到的代码,注释和结果的理解。

  • 如果我的理解是正确的,则需要整理一些文档和/或代码以呈现此SO主题。 1

  • 指定$replacement参数与不同的P6核心多重方法匹配。我们称它为“替换”代码路径。

  • “替换”代码路径将$replacement$strict参数传递到nqp中的代码路径,然后将其传递到后端中处理替换的代码路径。

  • p>
  • 在MoarVM后端,对于Windows1252,Windows1251和shiftjis编码,而不是其他编码 2

遵循相关的代码路径

您的代码调用this code in Buf.pm6

multi method decode(Blob:D: $encoding,
                    Str    :$replacement!,
                    Bool:D :$strict = False) {
    nqp::p6box_s(
      nqp::decoderepconf(
        self,
        Rakudo::Internals.NORMALIZE_ENCODING($encoding),
        $replacement.defined ?? $replacement !! nqp::null_s(),
        $strict ?? 0 !! 1))
}

nqp::decoderepconf函数直接映射到后端中的相应函数。

在MoarVM后端,它是MVM_string_decode_from_buf_config in ops.c

这反过来在同一文件中调用MVM_string_decode_config

从后一个函数的注释中,有几个关键句子大概可以解释替换和严格性参数的相关性:

  

MVM_string_decode不同,它不会通过没有正式映射的代码点。

     

目前只有Windows-1252和Windows-1251可以发挥作用。

对代码进行拼写并提交到回购中,表明后者的注释有些过时了,因为它似乎也应该对shiftjis有所帮助。

此外,要明确一点,如果在P6中指定了$replacement参数,则如果解码其他编码,则$strict参数将最终被忽略(并假设$strict = True)而不是Windows或shiftjis编码。 2

ascii和latin1会发生什么

MVM_string_decode_config的当前代码不会传递替换/严格参数给MVM_string_ascii_decodeMVM_string_latin1_decode函数。

因此,如果您使用编码“ ascii”,则blob只能包含0到127之间的值,而对于“ latin1”,该值必须介于0到255之间。

say "þor".ords; # (254 111 114)
say "3€".ords;  # (51 8364)

第一个字符串(作为Buf)无法解码,而是生成一条错误消息,因为254大于127,并且the ascii decoder code in MoarVM通过抛出带有“无效的ASCII”消息。

第二个将替换为¬。这是因为默认情况下,Buf是一个8位数组,因此大于255的值将被截断为其低字节,¬相同(在latin1和Unicode)。 3

但是,如果您使用元素大小较大的Buf也不会更好。结果仍然是¬tofu的组合。我什至看不到C,所以对我来说很清楚the MVM_string_latin1_decode function in MoarVM解码latin1不会引发异常。因此,大概是当遇到字符值超出0-255的范围时,它会将较高的字节转换为豆腐。

脚语

1 当然,JJ所做的正是使他们首先发布此SO的事情是修复了文档。我添加了此脚注,以便其他后来的读者理解该上下文并意识到此SO导致文档中的更改,并且可能导致代码更改,这可能由于完成的工作而使SO毫无意义。 >

2 如果指定编码的解码器不对其进行任何操作,如果有多个拒绝使用$replacement参数,那就太好了。

3 参见下面的timotimo ++评论。

相关问题