Bon, j’expose le probleme, il est assez simple : j’implemente un client IRC.
Le flux TCP est lu par un StreamReader tout ce qu’il y’a de plus classique, avec un encoding dérivé de l’ASCII (genre iso-8859-1), pasque le protocole il dit que c’est ce que les serveurs ils comprennent (ce qui est le cas).
Bref, je me retrouves avec des lignes que je peux interpreter et tout, merci les regex, tout ca.
Une fois interprété, passé dans la moulinette, viens le moment de l’affichage des messages… et la, c’est le drame. Si les codes et le protocole est bien ASCII only, les clients, eux peuvent envoyer n’importe quoi, genre de l’UTF8, par exemple (genre, l’exemple…).
Donc le probleme, tout con :
J’ai une string qu’on va appeller “message”, lue comme de l’ascii, comment que je sais si y’a de l’UTF8 dedans (genre, pour refaire la correction a la volée) ?
Le but, au final, est d’afficher correctement les messages qui viennent de clients ISO-latin, et de clients UTF8, tout ca de maniere transparente, bien evidement.
A ma connaissance, Y a pas moyen ™
Le probleme vient du fait que c’est l’OS qui fait l’affichage du charset avec l’encoding specifie. C’est pas un hasard si on a rajoute « content-type » dans les headers email et dans les pages html: les detections auto se chie la gueule une fois sur deux.
Si tu peux differencier de l’ASCII 7 bits et de l’UTF8 facilement, ca se complique entre de l’ISO-8859-1 et de l’UTF8: En UTF8, si un code ASCII a son bit de poids fort a 1, ca veut dire que c’est un caractere compose de 2 octets. En 8858-1, toute la table est code sur 256 caracteres et le bit de poids fort n’a pas de signification particuliere.
J’entrevois bien une solution, mais elle est empirique:
Proposer a l’utilisateur une liste de charset que ses amis sur IRC sont susceptibles d’utiliser: 8859-1 et UTF8. A chaque ligne, tenter de voir ce que ca donne en UTF8: Si le caractere n’'est pas dans la liste 8859-1 - typiquement les accents, (tout le monde parle la meme langue a priori, donc tu vas pas de retrouver avec un kanji dans une phrase francaise) afficher en 8859-1.
Evidement, si je choisis IS0-2022-JP et 8859-1, tu vas pleurer: Toutefois, si je parle en japonais, tout le texte sera en 16 bits, soit en 2022, soit en UTF8.
Dans tous les cas, cette solution n’est pas ideal, ceci dit.
Autre solution plus simple a mettre en place, mettre un systeme d’option sur chaque user et dire « good_boy=UTF8 », « LoneWolf1=8859-1 ». Donc la, facile, je vois que GB cause en crypte, je clique sur son nick, j’active l’option « personnal charset » et je lui colle de l’UTF8.
Je ne sais pas vraiment si ma réponse va correspondre à 100% avec ce que tu désires:
pour les chaînes codées et envoyés via un stream il existe ce qu’on appelle le Byte-Order Mark (ou BOM pour les intimes). Je pense d’ailleurs que le .NET Framework supporte la détection automatique du BOM. Le BOM est facilement identifiable par les octets EF BB BF (pour de l’UTF-8) en début de stream.
Cependant je ne sais pas s’il existe un BOM pour autre chose que de l’unicode.
LeBaronNoir > C’est ce qu’on fait d’habitude, il me semble, mais pour le convertir faut d’abord savoir en quel encoding on le reçoit et c’est justement ça la question.
Ge-Off > A ce que j’ai compris le BOM c’est pour si c’est déjà en UTF-8 hors ici c’est pas le cas.
Il existe des methodes pour essayer de deviner l’encoding, c’est ce que Mozilla utilise lorsqu’aucun encoding n’est spécifié dans une page HTML, malheureusement ca fonctionne pas à 100% et j’ai aucune idée de comment ca marche.
Le moins prise de tête c’est de faire comme dans les autres clients IRC, tu demande au gens de spécifier leur charset par serveur (a la limite par chan). En sachant que 90% du temps un chan est limité à une langue et donc à un seul charset. (Par exemple dans les chans français c’est l’ISO-8859-15 et si tu utilise de l’utf-8 tu te fait engueler parce que personne voit tes accents)
Au pire tu laisse le framework .NET se débrouiller tout seul en convertissant tout en UTF-8 et tu espère que ca passe