2009-01-31 13 views
5

Supongamos que por algún motivo perverso desea mostrar el contenido de bytes sin formato de un UTF8String.Delphi 2009 caprichos de RawByteString

var 
    utf8Str : UTF8String; 
begin  
    utf8Str := '€ąćęłńóśźż'; 
end; 

(1) Esto no hace, se muestra la forma legible:

memo1.Lines.Add(RawByteString(utf8Str)); 
// output: '€ąćęłńóśźż' 

(2) Esto, sin embargo, no "trabajo" - cuenta la concatenación:

memo1.Lines.Add('x' + RawByteString(utf8Str)); 
// output: 'x€ąćęłńóśźż' 

Entiendo (1), aunque la coerción forzada del compilador a UnicodeString parece evitar la visualización de una var RawByteString como es. Sin embargo, ¿por qué cambia el comportamiento en (2)?

(3) extraño aún - vamos a revertir la concatenación:

memo1.Lines.Add(RawByteString(utf8Str) + 'x'); 
// output: '€ąćęłńóśźżx' 

He estado leyendo sobre los tipos de cadenas novedosos en Delphi y creía comprender cómo funcionan, pero esto es un rompecabezas .

Respuesta

9

RawByteString solo existe para minimizar el número de sobrecargas requeridas para las funciones que funcionan con varios sabores de AnsiString s con diferentes afinidades de página de códigos.

En general, no declare las variables del tipo RawByteString. No encasille valores a ese tipo. No hagas concatenaciones en variables de ese tipo. Sobre las únicas cosas que se pueden hacer son:

  • Declarar un parámetro de este tipo (la intención original)
  • Index Server en un parámetro tal
  • Buscando en un parámetro tal
  • operaciones inteligentes que comprueban la página de códigos real de la cadena, utilizando la función StringCodePage.

Por ejemplo, notará que la función StringCodePage usa RawByteString como su tipo de argumento. De esta forma, funcionará con cualquier AnsiString, en lugar de hacer una traducción de página de códigos antes de pasarla como argumento.

Para su caso, cosas como las concatenaciones son en gran parte indefinidas. El comportamiento cambió entre RTM y Actualización 2, pero cuando las funciones de concatenación de cadenas RTL reciben múltiples cadenas con diferentes páginas de códigos, no hay una manera fácil de descubrir qué página de códigos debe usarse para la cadena final. Esa es solo una de las razones por las que no debes concatenarlas como lo haces aquí.

+0

Thans, Barry, eso tiene sentido.La concatenación fue solo un experimento de "qué pasaría si presiono este botón", nada de valor práctico. Aunque es extraño ver a Delphi introducir un comportamiento indefinido como este, nunca antes había muchos. –

1

No puede agregar una cadena a un TMemo "tal cual". Siempre hay que así algún tipo de conversión a Unicode, porque eso es todo TMemo conoce en Delphi 2009.

Si quieres pretender que su UTF8String utiliza el código de la página 1252, haga lo siguiente:

var 
    utf8Str : UTF8String; 
    Raw: RawByteString; 
begin 
    utf8Str := '€ąćęłńóśźż'; 
    Raw := utf8Str; 
    SetCodePage(Raw, 1252, False); 
    Memo.Lines.Add(Raw); 
end; 

Para más detalles, ver mi artículo Using RawByteString Effectively

+0

UTF-8 es una codificación de 8 bits. Requiere codeunits $ 00- $ FF para ser procesados ​​tal como están. Sin embargo, codepage 1252 mapas codeunits $ 80- $ 9F a diferentes valores cuando se convierte a UTF-16. En su lugar, debe usar la página de códigos 28591 (ISO-8859-1). –

Cuestiones relacionadas