Sign in Join
Wiki copytemporary

XML Decoders/es: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1+```text
2+ Category:CastellanoCategory:Español
3+```
4+
15## XML Decodificadores
26
37   A partir de la revisión de SVN 12582, el lector de XML es capaz de procesar los datos en cualquier codificación mediante el uso de descodificadores externos. Lo que sigue es una breve descripción de cómo funciona.
48
59### Decodificadores disponibles
610
711   En la actualidad, un decodificador que utiliza libiconv está disponible. Tiene dos implementaciones distintas. La primera, en la unidad**xmliconv.pas**, utiliza el paquete iconvenc existente y es compatible con Linux, FreeBSD y Darwin. La segunda, en la unidad **xmliconv_windows.pas**, es para Windows. Enlaza a la iconv.dll que debes distribuir con la aplicación.
812
913### Estructura del decodificador
1014
1115   La interacción con los decodificadores externos se hace mediante procedimiento sencillo. Escribir el decodificador es esencialmente escribir la implementación de los tres procedimientos siguientes:
1216
13171. `GetDecoder`
14182. `Decode`
15193. `Cleanup` (optional)
1620
1721   Aquí una breve descripción del funcionamiento con un decodificador externo:
1822
1923#### GetDecoder
2024
2125``` pascal
2226function GetDecoder(const AEncoding: string; out Decoder: TDecoder): Boolean; stdcall;
2327```
2428
2529   En el momento de la iniciación del programa, el decodificador se registra llamando al procedimiemto `XMLRead.RegisterDecoder` y pasando la función `GetDecoder` como argumento.    Cada vez que el lector se encuentra con una etiqueta de codificación que no controla internamente, llama a todas las funciones `GetDecoder` registradas en el mismo orden en que se registraron, hasta que una de ellas devuelve **true**.    Los argumentos de la función `GetDecoder` son el nombre de la codificación y el registro `TDecoder` que la función debe llenar. El nombre de codificación se limita a los caracteres de rango \['Z' .. 'A ', 'a' .. 'z', '0 '.. '9',, '.' '-','_'\], y no distingue entre mayúsculas y minúsculas. Si el decodificador es compatible con la codificación dada, la función debe establecer al menos el miembro `Decode` del registro suministrado y devolver *True*. Cumplimentar otros miembros de `Decoder` es opcional.
2630
2731#### Cleanup
2832
2933``` pascal
3034 procedure Cleanup(Context: Pointer); stdcall;
3135```
3236
3337   Si `GetDecoder` establece el miembro `Decoder.Cleanup`, se llamará por el lector de una vez, después de la transformación de la entidad actual esté acabada. Como sugiere el nombre, el decodificador debe liberar todos los recursos asignados.
3438
3539   El valor de `Decoder.Context` se pasa a los procedimientos `Decode` y `Cleanup` cada vez que es llamado. El lector no da ningún significado a este valor.
3640
3741#### Decode
3842
3943``` pascal
4044 function Decode(Context: Pointer; InBuf: PChar; var InCnt: Cardinal; OutBuf: PWideChar; var OutCnt: Cardinal): Integer; stdcall;
4145```
4246
4347   La función `Decode` hace el trabajo principal. Convierte los datos de entrada apuntados por `inbuf` a UTF-16 formato de boble byte de la plataforma actual y la pone en `outbuf`. El tamaño del espacio de entrada se muestra en `InCnt`, el espacio disponible en el espacio de salida se encuentra en `OutCnt`.
4448
4549   Una diferencia importante a destacar es que `InCnt` se da en **bytes**, mientras que `OutCnt` está en **WideChars**.
4650
4751   La función debe decrementar `InCnt` y `OutCnt` de acuerdo a la cantidad de datos procesados. Cada carácter procesados disminuye `OutCnt` en una unidad (o dos en caso de que el sustituto escrito sea doble), la cantidad a disminuir de `InCnt` depende de la codificación real.
4852
4953   No debe hacerse níngun presunción sobre el tamaño inicial de la memoria de trabajo: por ejemplo, el lector puede llamar al decodificador con sólo unos pocos bytes en la memoria de entrada. La función decodificador debe volver cero para indicar que nada se ha procesado, y el lector pondrá más datos en la entrada y llamará de nuevo al decodificador.
5054
5155   La función debe devolver un valor positivo si ha procesado algo, cero si no (por ejemplo, porque no hay espacio disponible en cualquiera de las memorias de entrada o de salida), y negativo en el caso de datos de entrada con secuencias ilegales. En el futuro, se intentará categorizar los errores de decodificación, pero en la actualidad cualquier valor de retorno negativo simplemente cancela la lectura con el mensaje 'Decoding error'.
5256
5357   Aún en el caso de error en los datos de entrada el decodificador debe disminuir `OutCnt` para reflejar el número de caracteres procesado con éxito. Esto será utilizado por el lector para ofrecer información de localización en el mensaje de error de excepción.
5458
5559### Ejemplo de decodificador
5660
5761   Lo que sigue es un ejemplo de una unidad que decodifica cp866. Este decodificador no tiene estado, por lo que no utiliza los miembros `Cleanup` y `Context`. Este ejemplo es muy fácil de modificar para manejar cualquier codificación similar de un solo byte con sólo reemplazar la tabla de conversión.
5862
5963``` pascal
6064 unit xmlcp866;
6165
6266 interface
6367
6468 implementation
6569
6670 uses
6771 SysUtils, xmlread;
6872
6973 const
7074 cp866table: array[#128..#255] of WideChar=(
7175 #$0410, #$0411, #$0412, #$0413, #$0414, #$0415, #$0416, #$0417,
7276 #$0418, #$0419, #$041A, #$041B, #$041C, #$041D, #$041E, #$041F,
7377 #$0420, #$0421, #$0422, #$0423, #$0424, #$0425, #$0426, #$0427,
7478 #$0428, #$0429, #$042A, #$042B, #$042C, #$042D, #$042E, #$042F,
7579 #$0430, #$0431, #$0432, #$0433, #$0434, #$0435, #$0436, #$0437,
7680 #$0438, #$0439, #$043A, #$043B, #$043C, #$043D, #$043E, #$043F,
7781 #$2591, #$2592, #$2593, #$2502, #$2524, #$2561, #$2562, #$2556,
7882 #$2555, #$2563, #$2551, #$2557, #$255D, #$255C, #$255B, #$2510,
7983 #$2514, #$2534, #$252C, #$251C, #$2500, #$253C, #$255E, #$255F,
8084 #$255A, #$2554, #$2569, #$2566, #$2560, #$2550, #$256C, #$2567,
8185 #$2568, #$2564, #$2565, #$2559, #$2558, #$2552, #$2553, #$256B,
8286 #$256A, #$2518, #$250C, #$2588, #$2584, #$258C, #$2590, #$2580,
8387 #$0440, #$0441, #$0442, #$0443, #$0444, #$0445, #$0446, #$0447,
8488 #$0448, #$0449, #$044A, #$044B, #$044C, #$044D, #$044E, #$044F,
8589 #$0401, #$0451, #$0404, #$0454, #$0407, #$0457, #$040E, #$045E,
8690 #$00B0, #$2219, #$00B7, #$221A, #$2116, #$00A4, #$25A0, #$00A0);
8791
8892 function cp866Decode(Context: Pointer; InBuf: PChar; var InCnt: Cardinal; OutBuf: PWideChar;
8993 var OutCnt: Cardinal): Integer; stdcall;
9094 var
9195 I: Integer;
9296 cnt: Cardinal;
9397 begin
9498 cnt := OutCnt; // num of widechars
9599 if cnt > InCnt then
96100 cnt := InCnt;
97101 for I := 0 to cnt-1 do
98102 begin
99103 if InBuf[I] < #128 then
100104 OutBuf[I] := WideChar(ord(InBuf[I]))
101105 else
102106 OutBuf[I] := cp866table[InBuf[I]];
103107 end;
104108 Dec(InCnt, cnt);
105109 Dec(OutCnt, cnt);
106110 Result := cnt;
107111 end;
108112
109113 function GetCP866Decoder(const AEncoding: string; out Decoder: TDecoder): Boolean; stdcall;
110114 begin
111115 // Most encodings typically have one or more alias names.
112116 if SameText(AEncoding, 'IBM866') or
113117 SameText(AEncoding, 'cp866') or
114118 SameText(AEncoding, '866') or
115119 SameText(AEncoding, 'csIBM866') then
116120 begin
117121 Decoder.Decode := @cp866Decode;
118122 Decoder.Cleanup := nil;
119123 Decoder.Context := nil;
120124 Result := True;
121125 end
122126 else
123127 Result := False;
124128 end;
125129
126130 initialization
127131 RegisterDecoder(@GetCP866Decoder);
128132 end.
129133```
130134
131135## Ver también
132136
133137- [[XML Tutorial/es]]
134138
135139---
136140*From the Free Pascal wiki, page "XML Decoders/es", as it stood on 2020-03-03 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
137-Category: Castellano
138-Category: Español

Back to history