Pause-Café Volubis

pause-café

rendez-vous technique
Pause-Café est une réunion technique
destinée aux informaticiens sur plateforme IBM i.
Elle a lieu 3 fois par an : en général en Bretagne et sur internet.

Pause-café #79

Septembre 2018
le 24 par Internet , le 25 à Paris avec Common France

UNICODE.

Unicode ?

A l'origine, sur nos machines, était le CCSID.

Avec un jeu de caractères donné (Latin-1, cyrillique, hébreu par ex.) définition d'une grille de codification de tous les caractères pour un pays donné :

Nous avons le même jeu de caractères que les espagnols, nous n'avons pas le même code page (codification).


Le CCSID est la codification du jeu de caractères et du code page d'origine d'une donnée.

"Cette données est Française ! " (CCSID au niveau zone, venant du CCSID du fichier, lui même venant du job de création)

si le CCSID du job (qui lit le fichier) est différent (il vient de la langue de l'utilisateur, sinon de QCCSID), il faut modifier la valeur héxa afin que le "é" Français s'affiche é pour l'utilisateur Espagnol ou Danois et non "{" (par exemple).


La codification UNICODE est une codification sur plusieurs octets permettant dans une même grille, de coder tous les caractères du monde
(y compris chinois, bengali, braille, symboles mathématiques et notes de musique !)


Définition

Le standard Unicode est constitué d'un répertoire de plus de 110 000 caractères couvrant 100 écritures, d'un ensemble de tableaux de codes pour référence visuelle (braille), d'une méthode de codage et de plusieurs codages de caractères standard, d'une énumération des propriétés de caractère (lettres majuscules, minuscules, symboles, ponctuation, etc.) d'un ensemble de fichiers de référence des données informatiques, et d'un certain nombre d'éléments liés, tels que des règles de normalisation, de décomposition, de tri, de rendu et d'ordre d'affichage bidirectionnel (pour l'affichage correct de texte contenant à la fois des caractères d'écritures droite à gauche, comme l'arabe et l'hébreu, et de gauche à droite).

En pratique, Unicode reprend intégralement la norme ISO/CEI 10646, puisque cette dernière ne normalise que les caractères individuels en leur assignant un nom et un numéro normatif (appelé point de code) et une description informative très limitée.



Voici une toute petite partie des tables UNICODE (les nombres sont présentés en notation hexadécimal):

(GIF 21 ko) (GIF 22 ko) (GIF 21 ko) (GIF 20 ko)
Caractères Unicode
0000 à 007F (0 à 127)
(caractères latins)
Caractères Unicode
0080 à 00FF (128 à 255)
(caractères latins, dont accentués)
Caractères Unicode
0900 à 097F (2304 à 2431)
(caractères devanagari/sanskrit)
Caractères Unicode
1100 à 117F (4352 à 4479)
(caractères hangul jamo/coréen)

Vous pourrez trouver plus d'informations sur l'UNICODE sur http://www.unicode.org.

Dans la table des caractères Unicode on ajoute  un index numérique associé à chaque caractère. Notons bien qu’il ne s’agit pas d’une représentation en mémoire, juste d’un nombre entier, appelé point de code. L'espace de codage de ces nombres est divisé en 17 zones de 65 536 points de codes. Ces zones sont appelées plans.
Le point de code est noté U+xxxx où xxxx est en hexadécimal, et comporte 4 à 6 chiffres :

Ainsi, le caractère nommé « Lettre majuscule latine c cédille » a un index de U+00C7.
Il appartient au premier plan.

En principe toutes les positions de code entre U+0000 et U+10FFFF sont disponibles, mais certains intervalles sont perpétuellement réservés à des usages particuliers, notamment une zone d'indirection exclue pour permettre le codage UTF-16 (cf. ci-dessous), les zones à usage privé et quelques régions (par exemple U+FFFE ou U+FFFF) contenant des non-caractères dont l'usage est interdit dans un échange de données conforme. Les autres positions de code sont soit déjà assignées à des caractères, soit réservées pour normalisation future.

Unicode v6 a 7 catégories de caractères:

 UTF-8

Techniquement, il s’agit de coder les caractères Unicode sous forme de séquences de un à quatre codets d’un octet chacun. La norme Unicode définit entre autres un ensemble (ou répertoire) de caractères. Chaque caractère est repéré dans cet ensemble par un index entier aussi appelé « point de code ». Par exemple le caractère « € » (euro) est le 8365e caractère du répertoire Unicode, son index, ou point de code, est donc 8364 (on commence à compter à partir de 0).
Le répertoire Unicode peut contenir plus d’un million de caractères, ce qui est bien trop grand pour être codé par un seul octet (limité à des valeurs entre 0 et 255). La norme Unicode définit donc des méthodes standardisées pour coder et stocker cet index sous forme de séquence d’octets : UTF-8 est l'une d’entre elles, avec UTF-16, UTF-32 et leurs différentes variantes.
La principale caractéristique d’UTF-8 est qu’elle est rétro-compatible avec la norme ASCII, c’est-à-dire que tout caractère ASCII se code en UTF-8 sous forme d’un unique octet, identique au code ASCII. Par exemple « A » (A majuscule) a pour code ASCII 65 et se code en UTF-8 par l'octet 65. Chaque caractère dont le point de code est supérieur à 127 (caractère non ASCII) se code sur 2 à 4 octets. Le caractère « € » (euro) se code par exemple sur 3 octets : 226, 130, et 172.

 

UTF-16

L’UTF-16 est un bon compromis lorsque la place mémoire n’est pas trop restreinte, car la grande majorité des caractères Unicode assignés pour les écritures des langues modernes (dont les caractères les plus fréquemment utilisés) le sont dans le plan multilingue de base et peuvent donc être représentés sur 16 bits.


Codage UTF-16

hi \ lo

DC00

DC01

   …   

DFFF

D800

10000

10001

103FF

D801

10400

10401

107FF

:

/

/

...

/

DBFF

10FC00

10FC01

10FFFF

Les points de code des seize plans supplémentaires nécessitent une transformation sur deux mots de 16 bits :

En résumé, il y a 2 plages réservées :
Haute : X'D800' – X'DBFF' = 4 * 256 combinaisons
Basse : X'DC00' – X'DFFF' = 4 * 256 combinaisons
soit 1024 * 1024 caractères supplémentaires


codage sur 2 octets pour les 63488 premiers caractères (comme UCS-2 ci-dessous)
codage sur 4 octets pour les autres caractères (subrogate characters)


UCS-2 est la version simplifiée de UTF-16 ne prévoyant pas les indirections et ne permet donc que de stocker des caractères appartenant au premier plan. (arrivée avant UTF-16, c'est un peu obsolète aujourd’hui)


• UTF-16 intège le sens de lecture droite->gauche/gauche->droite, pas UCS2
• UTF-16 intègre une normalisaiton (un nommage) de chaque caractère, pas UCS2
• UCS2 peut être transformé en UTF-16, le contraire n'est pas forcément vrai
   • voir ici les plans supplémentaires d'UTF-16, non implémentés par UCS2


UTF-32

L’UTF-32 est utilisé lorsque la place mémoire n’est pas un problème et que l’on a besoin d’avoir accès à des caractères de manière directe et sans changement de taille (hiéroglyphes par ex.).

 

Sur IBM i , les différentes versions Unicode sont représentées par un code page

UCS-2                         ->        CCSID(13488)
UTF-8                         ->        CCSID(1208)
UTF-16                       ->        CCSID(1200)
UTF-32                       ->        (non implémentée)    

Il faut parallèlement avoir installé la bibliothèque ICU (option 39 du système)

Voir https://www-01.ibm.com/software/globalization/ccsid/ccsid_registered.html

Avec UCS-2 et UTF-16, une zone base de données de 20 caractères = 40 Octets
Avec UTF-8 une zone 20 caractères = 20 Octets, donc potentiellement trop courte, pour les caractères accentués

à réserver au VARCHAR, CLOB et fichiers IFS.

         A         UCS2       10G    CCSID(13488)
A* Lg de stockage = 20 octets
A UTF16 10G CCSID(1200)
A* Lg de stockage = 20 octets
A UTF8 10A CCSID(1208)
A* Lg de stockage = 10 octets



Soit une base de données (vinicole) en EBCDIC


DSPFFD


Une version UTF-8

DSPFFD identique


ET une version UTF-16


DSPFFD


La taille des champs NCHAR (ou GRAPHIC) est doublée



Pour alimenter la version UTF-16, nous ne rencontrons pas de problèmes

Puis


Par contre pour la version UTF-8, nous rencontrons le message SQL0404, pour cause de caractère accentué qui prend 2 octets.



Nous sommes obligés d'écrire :




Bref, mieux vaut utiliser UCS-2 ou UTF-16 dans la base de données.

Quelques questions existentielles

ET si je dois faire un test?


Testez le(s) caractère(s) de votre choix, la constante sera passée en unicode afin d'être comparée correctement à la variable

ET si je dois faire un SST


pensez "position du caractère" (ici le 3eme) jamais en octet...

Affichage et impression

RDI sait partiellement traiter l'Unicode

ACS, sait afficher de l'UNICODE

 

les DSPF connaissent les CCSID 13488 et 1200, par le biais du mot-clé CCSID

CCSID

 

Soit un fichier Base de données avec des zones GRAPHIC CCSID(13488)

CREATE TABLE AF4TEST.UNITEST13 (
CODECLI INTEGER NOT NULL ,
RAISOC GRAPHIC(80) CCSID 13488 DEFAULT NULL ,
VILLE GRAPHIC(50) CCSID 13488 DEFAULT NULL ,
DEPCLI DECIMAL(2, 0) DEFAULT NULL )
RCDFMT UNITEST ;

Le DSPF est construit en faisant Référence

Le programme de test fait un simple affichage

si vos fichier sont codés avec CCSID(1200) la conversion 1200 -> 13488 se fera souvent sans problèmes, les caractères étant largement communs.

 

Sur une session 5250 de Client Access :

Il fallait avant utiliser l'émulateur de Web Access (Client Access for the Web) qui est un émulateur 5250 compatible Unicode.

 

Avec L'émulateur de IBM i Access Client Solution :

- il vous faudra les options suivantes

Lors de la définition de la session 5250 HOD

    il faut activer le support d'Unicode.

et utilisez la police adéquat

 

Pour afficher du Chinois (Police WT SansDuo TW ou WT SerifDuo TW en 7.2)

S'il le faut téléchargez les polices dans /QIBM/ProdData/OS400/Fonts/TTFonts (option 43 de SS1)



 

 

Malgrès cela, même sur une session configurée pour Unicode, vous oubliez DFU et QUERY...




Pour imprimer de l'UNICODE, voyez ce PRTF :

Rappel : la police 'Monotype Sans Duospace WT SC' est apportée par l'installation de l'option 43

 

Il faut ensuite le compiler avec DEVTYPE(*AFPDS)

 

ici visualisation du résultat avec AFP Workbench Viewer.

Pour l'impression utilisez une Imprimante Réseau AVEC MFRTYPMDL(*HPDBCS), voyez :


Exportation

Exportez par CPYTOSTMF ou CPYTOIMPF

SI le CCSID d'origine est connu laissez *FILE dans FROMCCSID, sinon (65535) forcez un CCSID.

Indiquez 1200 dans TOCCSID  (*PCASCII aurait transformé tout le texte en ANSI de Windows, cela ne serait plus de l'Unicode)



Résultat


Pour voir le fichier, faites un partage Windows et utilisez Word (par exemple)

Importation (depuis Excel, par exemple)

cela génère de l'Unicode LE (Litte Endian, non reconnu par IBM i)

 

Malheureusement NetServer a sauvegardé ce document en 1252 (Ansi), la notion de CCSID n'étant pas implémentée par Windows

Et voilà

 


Langage de contrôle (CL) et commandes système


CPYF

OPNQRYF


De manière générale, la documentation indique que le CL admet l'Unicode depuis la 7.3. (bien partiellement à notre avis)

https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_73/rbam6/rbam6unicode.htm

En effet :


Si vous saisissez une valeur EBCDIC elle sera transformée et envoyée en UNICODE


Traitement en RPG

Top