28 Diciembre 2009

charsets y codepages

Archivado en: ABAP/IV — voet

No siempre tenemos que preocuparnos de la codificación de caracteres de los ficheros que abrimos y cerramos en R/3, pero en ocasiones sí. Por ejemplo, cuando destinados a un proyecto en Japón debemos hacer una carga de clientes con nombres etruscos.

Si realmente no estás familiarizado/a con el concepto de juegos de caracteres, es muy importante superar el mito extendidísimo de que un caracter de texto ocupa siempre un byte. Eso es cierto para la mayoría de textos en inglés que no usan caracteres extraños, o cuando utilizamos textos de windows y nuestro SAPGUI está enterado de por donde se mueve. Pero no siempre ocurre así.

Podría extenderme sobre las diversas variaciones de juegos de caracteres, sistemas de codificación, etc… pero no lo voy a hacer porque ya hay un estupendo artículo que explica en que consisten y, esencial, porque llegaron a ser como son: Lo Absolutamente Mínimo que cada Desarrollador de Software, Absoluta y Positivamente, Debe Saber sobre Unicode y Juegos de Caracteres. Este texto, muy clarificador, unido a este FAQ sobre UTF, debería ser bastante para entender lo esencial sobre este asunto.

El código que adjunto es una demostración de cómo se pueden utilizar objetos ABAP para convertir textos de unos sistemas de codificación a en otros. Para facilitar las pruebas, hago uso de la interesante función SCMS_STRING_TO_XSTRING para transformar el texto del parámetro de entrada del report en xstring. ¿Por qué?

Obviamente no podemos trabajar con strings puros, ya que de ese modo su contenido real, sus bytes, permanecen opacos a nuestra vista durante su tratamiento. Por eso se hace absolutamente necesario el uso de xstrings, con lo que a la hora de cargar y grabar ficheros codificados de modo extraño lo haremos en modo binario.

Es importante señalar que ABAP no utiliza los diversos nombres y alias de los distintos juegos de caracteres para realizar las conversiones, ya que utiliza un código numérico interno para definirlos. Existe una función que traduce, más bien intenta, los nombres estándar a estos códigos internos. Pero funciona tan horrorosamente mal y es tan poco práctica que ni la menciono. Es mucho mejor mirar directamente el contenido de la tabla TCP00, cruzar los dedos y deducir, a base de pruebas (este mismo programa puede ayudar) cual es el código numérico que necesitamos. Digo lo de las pruebas porque las descripciones son espantosas y muy poco clarificadoras.

Como curiosidad: el programa RSCPINST muestra los juegos de caracteres utilizados en SAPGUI, servidor y base de datos. Quizás sirva de ayuda.

REPORT  zzcharsetsycodepages NO STANDARD PAGE HEADING.
"As seen on http://glob.cranf.net

DATA windows1252 TYPE xstring. "xcadena en windows1252
DATA utf8 TYPE xstring. "xcadena en UTF-8
DATA utf16 TYPE xstring. "xcadena en UTF-16
DATA conversionutf8 TYPE REF TO cl_abap_conv_x2x_ce. "instancia de la conversión
DATA conversionutf16 TYPE REF TO cl_abap_conv_x2x_ce. "instancia de la conversión
DATA longitud TYPE i. "lo necesitamos, queramos o no

"parámetro de entrada
PARAMETERS cadena TYPE string LOWER CASE DEFAULT 'España Cañí y Olé'.

"**********************************************************************
*     _        _            __           _        _
* ___| |_ _ __(_)_ __   __ _\ \__  _____| |_ _ __(_)_ __   __ _
*/ __| __| '__| | '_ \ / _` |\ \ \/ / __| __| '__| | '_ \ / _` |
*\__ \ |_| |  | | | | | (_| |/ />  <\__ \ |_| |  | | | | | (_| |
*|___/\__|_|  |_|_| |_|\__, |_//_/\_\___/\__|_|  |_|_| |_|\__, |
*                      |___/                              |___/
"en un primer paso tiramos de la función de conversión de string en xstring,
"pasándole el código interno de charset ABAP (están en la tabla TCP00)
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
  EXPORTING
    text     = cadena
    encoding = '1160' "windows1252, véase tabla TCP00 para deducir número
  IMPORTING
    buffer   = windows1252
  EXCEPTIONS
    failed   = 1
    OTHERS   = 2.
"esta función nos puede bastar para conversión de un string en la cadena hexadecimal
"con el charset que nos dé la gana. estupenda, ¿verdad?

"**********************************************************************
*     _                     _                                  _
*  ___ |__  __ _ _ _____ ___ |_   ___ ___ _ ___   ____ _ _____(_)___ _ __
* / __|'_ \/ _` | '__|__| _ \__| / __| _ \ '_ \\ / /_ \ '__|__| | _ \ '_ \
*| (__ | | |(_| | | \__ \ __/|_ | (__ (_) || | |V / __/ | \__ \ |(_) || | |
* \___|| |_|__,_|_| |___/___|__| \___|___/_| |_|_/\___|_| |___/_|___/_| |_|
*
"pero ahora vamos a pasar de un xstring a otro xstring con distinta codificación
"instanciamos primero el objeto conversor
TRY.
    CALL METHOD cl_abap_conv_x2x_ce=>create
      EXPORTING
        in_encoding  = '1160' "windows1252
        ignore_cerr  = abap_false
        out_encoding = '4110' "código utf-8, véase tabla TCP00
        input        = windows1252
      RECEIVING
        conv         = conversionutf8. "es la instancia de un objeto, ojo!
  CATCH cx_parameter_invalid_type .
  CATCH cx_parameter_invalid_range .
  CATCH cx_sy_codepage_converter_init .
ENDTRY.

"convertimos occidental a UTF-8
TRY.
  CALL METHOD conversionutf8->convert_c
    IMPORTING
      len = longitud.
ENDTRY.

"y obtenemos el valor UTF8 como xstring
CALL METHOD conversionutf8->get_out_buffer
  RECEIVING
    buffer = utf8.

"**********************************************************************
"para rizar el rizo, pasamos de UTF8 a UTF16 little endian
TRY.
    CALL METHOD cl_abap_conv_x2x_ce=>create
      EXPORTING
        in_encoding  = '4110' "código utf-8, véase tabla TCP00
        ignore_cerr  = abap_false
        out_encoding = '4103' "utf-16 little endian (4102 sería big endian)
        out_endian   = 'L' "indica opcionalmente big endian / little endian
        input        = utf8
      RECEIVING
        conv         = conversionutf16. "instancia del objeto
  CATCH cx_parameter_invalid_type .
  CATCH cx_parameter_invalid_range .
  CATCH cx_sy_codepage_converter_init .
ENDTRY.

"hacemos la conversión de UTF8 a UTF16
TRY.
  CALL METHOD conversionutf16->convert_c
    IMPORTING
      len = longitud.
ENDTRY.

"obtenemos finalmente el valor UTF16 como xstring
CALL METHOD conversionutf16->get_out_buffer
  RECEIVING
    buffer = utf16.

"**********************************************************************
"y aquí los resultados
WRITE: / 'String      :', cadena.
WRITE: / 'windows1252 :', windows1252.
WRITE: / 'UTF-8       :', utf8.
WRITE: / 'UTF-16      :', utf16.

Tras ejecutarse el programa con el parámetro por defecto, veremos un resultado tal que así:

String      : España Cañí y Olé
windows1252 : 45737061F161204361F1ED2079204F6CE9
UTF-8       : 45737061C3B161204361C3B1C3AD2079204F6CC3A9
UTF-16      : 4500730070006100F1006100200043006100F100ED002000790020004F006C00E900

Espero que os sea de utilidad.

Archivado en: ABAP/IV

celda 211

Archivado en: Análisis, Cine — voet

Este viernes pasado fui al cine a ver Avatar, la última peli de Cameron, con tan mala suerte que en uno de los cines se estropeó la copia 3D y en otro se habían agotado las entradas. Tampoco me importó tanto, ya que iba a verla por curiosidad técnica. La historia, evidentemente, no es más que una excusa para el despliegue de fuegos artificiales de Cameron, un director al que hay que reconocerle una potencia visual fuera de lo común.

Así que entré a ver Celda 211. La verdad es que me daba buena espina tras haber comprobado la credibilidad y presencia de Luis Tosar en el trailer.

Y no me arrepiento de haberlo hecho.

El argumento es sencillo: un funcionario de prisiones novato se queda atrapado en medio de un motín en la cárcel de Zamora y no tiene más remedio que hacerse pasar por un preso más si quiere sobrevivir.

Celda 211 No sólo está muy bien dirigida y cuenta una historia compacta con gran sentido del ritmo: tiene unos personajes excelentemente construidos y coherentes y, lo que es mejor, muy bien interpretados. En todo momento su comportamiento, así como la evolución de la relación entre los protagonistas, es perfectamente lógico y creíble, aunque algunas de las situaciones externas que condicionan sus decisiones sean un tanto forzadas.

Obviamente, cuando se trata una temática tan propicia a tópicos como el mundo carcelario, se cae en el riesgo de hacer el ridículo. Pero por lo poco que conozco de ese ambiente (por amigos que trabajan en él), tengo la sensación de que el director se ha molestado mucho en documentarse y hacer un retrato fiel de las cárceles españolas y sus inquilinos.

Ojo que la película no es para estómagos sensibles. La escena inicial es realmente dura y desagradable, pero afortunadamente no se limita a eso. Hay abundantes toques de humor, la mayoría provenientes del cinismo y la retranca de Malamadre, el preso interpretado por Luis Tosar.

Tampoco es especialmente proquinqui en el sentido de que ponga a los presos como buenos y los funcionarios como malos. Por ejemplo, Malamadre es legal, como se conoce en las prisiones a la gente de honor, y llega a despertar simpatía en ese sentido, pero no queda claro si lo invitarías a cenar a tu casa. Y uno de los funcionarios (Resines, que por una vez no hace de Resines) es un sádico hijoputa; pero es una excepción dentro de la plantilla y son sus propios compañeros los primeros que censuran su comportamiento. Digamos que el juego de luces y sombras sobre los personajes, aunque bastante elemental, evita que la película caiga en el maniqueísmo.

En definitiva, os la recomiendo vivamente.

Archivado en: Análisis, Cine

26 Diciembre 2009

miedo/cubo

Archivado en: Dibujo, Galería — voet

miedo/cubo

Archivado en: Dibujo, Galería

25 Diciembre 2009

sandra y susana simpsonizadas

Archivado en: Dibujo, Galería — voet

sandra ysusana simpsonizadas

Archivado en: Dibujo, Galería

documentos sobre la colonización de tacirupeca

Archivado en: Dibujo, Ficción, Galería — voet

colonización de tacirupeca
De entre los pioneros que participaron en colonización de Tacirupeca (actual Taizi-Dupék), una casta de hombres y mujeres alcanzaron estatus mítico por su arriesgada labor de transporte de mercancías durante cientos de kilómetros desde el cosmódromo de Ferslandin hasta la Grieta de Borges a través del desierto de Mud. Ellos posibilitaron que la Grieta de Borges acabara siendo el núcleo humano más importante de todos los sistemas estelares que acabaron formando el Adset de Omb Mlana. Esta ilustración de autor desconocido muestra a un orgulloso transportista al lado de su vehículo tras su llegada a destino.

accidente
De la misma época tenemos este esbozo a lápiz que recoge uno de los accidente habituales que sufrían estos transportistas. Este en concreto fue encontrado junto a los cadáveres de las personas retratadas y una tercera a la que suponemos autor del dibujo.

Archivado en: Dibujo, Ficción, Galería
índice   cranf.net   wordnadapress
12345