2003-10-24

Unicode et C++

Ces derniers temps j'ai pas mal travaillé sur la dkstd. J'ai enfin décidé d'inclure une classe C++ pour gérer les chaines Unicode.

Malheureusement, si gérer un chaine traditionnelle (avec un octet par caractère) est assez simple et direct, la gestion d'une chaine Unicode est beaucoup plus délicate. L'Unicode ne définit qu'une chose : un nombre correspond à un caractère. Mais comment stocker ces nombres ? On compte plusieurs encodages :

  • UCS-2 : chaque caractère est stocké sur 16 bits, mais on se limite à 65536 caractères Unicode (par chance ce sont les plus courant).
  • UCS-4 : chaque caractère est stocké sur 32 bits, on peut donc virtuellement coder tous les caractères possibles. Malheureusement, 32 bits accordés à chaque caractère représente un assez gros gaspillage en terme de mémoire et de temps machine.
  • UTF-8 : chaque caractère est stocké par une suite d'octets. Ça permet d'avoir une place mémoire utilisée assez faible quand on stocke des chaines dans les langues occidentales. Malheureusement, travailler avec de l'UTF-8 en mémoire n'est pas chose aisée. Couper une chaine UTF-8 en deux par exemple nécessite de la parcourir depuis le début.
  • UTF-16 : ressemble beaucoup à UCS-2, mais certains caractères sont codés en regroupants deux mots de 16 bits, formant ainsi une paire. On a donc une série de caractères sur 16 bits, et parfois un caractère stocké sur 32 bits. Là encore il est difficile de manipuler la chaine en mémoire.

La décision a été difficile à prendre. J'ai finallement opté pour l'UCS-2, avec une possibilité de créer un jour si on le souhaite une 3e classe de gestion de chaine utilisant l'UCS-4. J'incluerai des fonctions de conversions pour les autres formes d'encodage, notamment l'UTF-8 qui est répandu pour écrire des fichiers XML.

Qu'est-ce qui m'a aidé à prendre cette décision ? Je fais pas mal de logiciels sous Windows, et c'est l'UCS-2 qui est le format utilisé pour les fonctions traitant l'Unicode. C'est aussi il me semble le format utilisé par Java. Bref, j'ai opté pour la solution susceptible de m'offrir la meilleure interopérabitilité avec les systèmes existants. Encore maintenant j'espère avoir pris la bonne décision, on verra à l'usage, c'est dans des cas pratiques qu'on met à l'épreuve un design logiciel.

Par ailleurs, je vous recommande la lecture d'un très bon article sur l'Unicode de Joel On Software.