2010-09-15 7 views
1

J'ai besoin de convertir un groupe d'octets dans ISO-2022-JP et ISO-2022-JP-2 (et d'autres variations de ISO-2022) en Unicode. J'essaie d'utiliser ICU (link text), mais le code suivant ne fonctionne pas.Chaîne de codage C++ vers Unicode - bibliothèque ICU

std::string input = "\x1B\x28\x4A" "ABC\xA6\xA7"; //the first 3 chars are escape sequence to use JIS_X201 character set in GL/GR 
UErrorCode status = U_ZERO_ERROR; 
UConverter *conv; 
// set up the converter 
conv = ucnv_open("ISO-2022-JP", &status); 
if (status != U_ZERO_ERROR) return false; //couldn't find character set 

UChar * convDest = new UChar[2*input.length()]; //ucnv_toUChars will use up to 2*length 

// convert to Unicode 
int resultLen = (int)ucnv_toUChars(conv, convDest, 2*input.length(), input.c_str(), input.length(), &status); 

Cela ne fonctionne pas. Le résultat contient '?' charcters pour tout ce que je mets dans ce qui était au-dessus ASCII. Le statut n'a aucune erreur. Qu'est-ce que je fais mal? En plus de cela, j'avais des difficultés à compiler la bibliothèque 4.4 car le projet MSVC 9 ne serait pas converti en projet MSVC 10.

Je connais également la librairie open source libiconv. Je ne pouvais pas compiler celui-là sur Windows. Si quelqu'un a des conseils sur une bibliothèque différente, c'est aussi la bienvenue.

Merci.

EDIT La séquence d'échappement que j'ai utilisée à l'origine était erronée. Alors maintenant ICU prend la chaîne, supprime la séquence d'échappement - ce qui est un pas dans la bonne direction. Mais le résultat contient toujours '?' caractères. La raison pour laquelle je n'ai pas pu convertir en projet MSVC 10 était que la plate-forme x64 n'était pas installée (ce n'est pas le cas par défaut). Sinon, je pourrais ouvrir tous les projets dans l'éditeur de texte et supprimer toute mention de cible x64.

Répondre

1

Je n'ai pas réussi à faire fonctionner la conversion pour le jeu de caractères JIS_X201 dans le codage ISO-2022-JP. Et je ne pouvais pas générer un "valide" en utilisant tous les outils à ma disposition - essayé Java (ICU et non ICU implémentation de ISO2022) et C++.

J'ai donc simplement écrit une fonction pour faire une recherche de code et la convertir en Unicode en utilisant cette table: wikipedia. Lorsque j'ai commencé à remplir le rapport de bogue, je voulais inclure le RFC pour ISO-2022-JP. Puis j'ai trouvé cette ligne dans la RFC "L'ensemble Kana de JIS X 0201 n'est pas utilisé dans les messages ISO-2022-JP." link text. Il semble donc que la norme ne définit pas réellement les bits supérieurs. L'ISO-2022-JP-3 va cartographier les bits supérieurs, mais à bas plan. Je dois donc prendre chaque octet et soustraire 0x80 de lui, et le passer à travers ISO-2022-JP-3, et prendre les autres octets < 128 et les passer par le convertisseur ISO-2022-JP pour le jeu de caractères complet JIS_X201. Eh bien, c'est beaucoup plus facile de le faire moi-même.

Donc, à vrai dire, je dirais que ce n'est pas un bug. C'est un énorme mal de tête cependant.

P.S. tout le flot foiré que j'essaye de décoder vient de DICOM. Voir pdf page 107 pour voir ce qu'ils considèrent comme acceptable.

+0

Très intéressant. Avez-vous essayé de convertir de 2022 à Unicode en utilisant Java (non ICU)? –

+0

J'ai essayé: Charset iso2022JP = Charset.forName ("ISO-2022-JP"); Résultat CharBuffer = iso2022JP.decode (ByteBuffer.wrap (octets)); où le jeu de caractères était sun.nio.cs.ext.ISO2022_JP et les résultats sont identiques à ceux d'ICU. Il ne s'agit pas fondamentalement de cartographier les caractères au-dessus de 128. – Budric

+0

Budric pourriez-vous déposer un bug sur ICU à http://bugs.icu-project.org/trac/newticket et mentionner ces résultats? Vraiment étrange que ni l'un ni l'autre ne supporte cela dans l'encodage. –

3

Cela ne ressemble pas à un encodage ISO 2022. Les bits élevés sont supposés être zéro. La séquence d'échappement semble quelque peu reconnaissable, mais elle commence par ESC. 0x1b, pas 0xb0. Aucune idée de ce que signifient ces valeurs d'octets.

+1

Vous avez raison. La séquence d'échappement était erronée. Erreur stupide.Cependant, je pensais que la chaîne d'entrée était correcte pour ISO 2022. La norme prend en charge l'encodage à 8 octets - c'est pourquoi vous avez des plans GL et GR. En regardant aussi http://en.wikipedia.org/wiki/ISO/IEC_2022 pour ISO-2022-JP, étant donné que la séquence d'échappement, il devrait lier http://en.wikipedia.org/wiki/JIS_X_0201 jeu de caractères, ce qui fait cartographier les octets supérieurs. J'utilise cette référence pour ISO-2022: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-035.pdf la section 8 décrit les codes à 8 bits. – Budric

+1

C'est un bugger complet d'un encodage, sur le pire que j'ai jamais vu. Il est extraordinairement sensible à l'état du décodeur, assurez-vous d'utiliser les données * real * d'une source connue. Une façon d'obtenir cela si vous n'avez pas de bonnes données est de * encoder * ce que vous vous attendez à voir en premier, puis de repasser au décodeur. –

+0

Je suis complètement d'accord. Un cauchemar absolu à gérer. Je vais essayer de m'assurer que mes commentaires sont bons. – Budric

1

(Cette question semble familier, Salut à nouveau.)

Un nit mineur, mineur: Vous voulez vérifier l'état d'erreur avec if(U_FAILURE(status)) (ou inversement, U_SUCCESS(status)).