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

问题描述 投票:8回答:1

这段代码:

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,但语法是正确的?

encoding perl6
1个回答
7
投票

TL; DR:

  • 只有samcv或其他核心开发人员才能提供权威的答案。这是我对我看到的代码,注释和结果的理解。
  • 如果我的理解是正确的,那么需要整理一些文档和/或代码以使这个SO无法实现
  • 指定$replacement参数匹配不同的P6核心多方法而不是不这样做。我们称之为“替代者”代码路径。
  • “replacer”代码路径将$replacement$strict参数传递到nqp中的代码路径,然后将它们传递到处理替换的后端的代码路径中。
  • 在MoarVM后端,替换和严格参数传递给windows1252,windows1251和shiftjis编码的解码器,但不传递给其他编码。

Following the relevant code path

你的代码调用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参数,那么如果解码除windows或shiftjis编码之外的任何编码,$strict参数将最终被忽略(并且$strict = True假设)。

What happens with ascii and latin1 in particular

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通过使用“invalid ASCII”消息抛出异常来对无效值做出反应。

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

但是,如果你使用更大元素尺寸的Buf,那就不错了。结果仍然是¬,加上tofu。我可以看到,即使我不能C,所以我很清楚解释latin1的the MVM_string_latin1_decode function in MoarVM不会抛出异常。因此,当它遇到0-255范围之外的字符值时,它会将更高的字节变成豆腐。

Footnotes

1当然,JJ正在做的事情导致他们首先发布这个SO正在修复文档。我添加了这个脚注,以便其他后来的读者能够理解上下文,并意识到这个SO正在导致文档中的更改,并且可能导致代码的更改,这可能会因为完成的工作而导致这样的SO。

2如果指定编码的解码器没有对它做任何事情,那么如果有multis拒绝使用$replacement参数,那将是很好的。

3请参阅下面的timotimo ++的评论。

© www.soinside.com 2019 - 2024. All rights reserved.