No momento, estou investigando como a decodificação SBCS/DBCS funciona no JDK e me deparei com um pedaço de código estranho na IBM930
implementação do conjunto de caracteres (embora não seja o único).
Em primeiro lugar, pelo que entendi, os implementadores do JDK usam arquivos de mapeamento para gerar a maioria das classes de conjuntos de caracteres. Por exemplo:
IBM930.map
IBM930.nr non-roundtrip bytes override
IBM930.c2b non-roundtrip codepoints override
são os arquivos que o utilitário DBCS interpreta para gerar IBM930.java
.
Se olharmos para IBM930.nr
, veremos:
25 000a
O que significa que byte 0x25
deve mapear para \u000a
.
Se olharmos agora para IBM930.map
, veremos:
...
24 0084
25 000A <---
26 0017
...
Portanto, a substituição sem ida e volta já foi especificada no arquivo .map principal.
Se abrirmos IBM930.java
, podemos ver na parte inferior:
static class EncodeHolder {
static final char[] c2b = new char[0x7400];
static final char[] c2bIndex = new char[0x100];
static {
String b2cNR = "\u0025\n";
String c2bNR = ...
DoubleByte.Encoder.initC2B(DecodeHolder.b2cStr, DecodeHolder.b2cSBStr,
b2cNR, c2bNR,
0x40, 0xfe,
c2b, c2bIndex);
}
}
Especificamente estou apontando para String b2cNR = "\u0025\n"
.
Considerando que o arquivo .map principal já contém substituições de NR, por que o processo de geração gera um valor não nulo b2cNR
?
Será que é porque nem todos os arquivos .map são ajustados para incluir entradas .nr?
Ou estou ignorando um comportamento muito específico do initC2B
método?
Sim.
Não, na verdade não. Certamente não é assim que esses dados são usados.
O código-fonte da
sun.nio.cs.DoubleByte
classe relevante pode ser encontrado aqui: https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/sun/nio/cs/DoubleByte.java . Se você rastrear o queDoubleByte.Encoder.initCB()
acontece com os dados provenientes desse arquivo viab2cNR
, verá que ele não é usado para definir uma decodificação de0x25
para\u000a
. Em vez disso, ele é usado para garantir que a decodificação mapeada de0x25
para\u000a
(do.map
arquivo) não seja usada para definir também uma codificação de\u000a
volta para0x25
. E se não houvesse tal decodificação mapeada, ob2cNR
item e a.nr
entrada correspondente não teriam efeito.Os dados NR não são bem caracterizados como substituições. Pelo menos, não substituições de mapeamento. Em vez disso, eles sinalizam mapeamentos que são unidirecionais na direção bytes-caractere (decodificação). Você pode pensar, então, que repetir o mapeamento completo em vez de apenas fornecer os bytes seria redundante, e talvez você esteja certo, mas fornecer o mapeamento completo fornece uma verificação de consistência e talvez também seja conveniente no caso de haver um caractere diferente codificado para esses bytes.
Isso ocorre porque você entendeu mal o significado das entradas .nr. Espera-se que o arquivo .map forneça todas as correspondências de caracteres bytes <-->. As entradas .nr sinalizam alguns desses mapeamentos como unidirecionais.