Partage de mon script de remodelage du clavier QWERTY…
[progfou.git] / ctypes / iconv.py
CommitLineData
4dabedd6
P
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3"""
4Module de support iconv pour Python.
5
6Copyright : Agence universitaire de la Francophonie
7Licence : GNU General Public Licence, version 2
8Auteur : Jean Christophe André
9Date de création : 20 mars 2009
10"""
11
12from ctypes import *
13from ctypes.util import find_library
14
15# on n'exporte que la fonction iconv ('a marche pô ?!)
16__all__ = ["iconv"]
17
18# la librairie C
19_libc = CDLL(find_library("c"))
20
21# un type spécifique à iconv (pour stoquer l'état de son automate)
22_iconv_t = c_void_p
23
24# prototype de la fonction iconv_open(3)
25_iconv_open = _libc.iconv_open
26_iconv_open.argtypes = [c_char_p, c_char_p]
27_iconv_open.restype = _iconv_t
28
29# prototype de la fonction iconv(3)
30_iconv = _libc.iconv
31_iconv.argtypes = [_iconv_t,
32 POINTER(POINTER(ARRAY(c_char, 1024))), POINTER(c_size_t),
33 POINTER(POINTER(ARRAY(c_char, 4096))), POINTER(c_size_t)]
34_iconv.restype = c_size_t
35
36# prototype de la fonction iconv_close(3)
37_iconv_close = _libc.iconv_close
38_iconv_close.argtypes = [_iconv_t]
39_iconv_close.restype = c_int
40
41def iconv(from_code, to_code, string):
42 """
43 from_code : encodage d'origine de string
44 to_code : encodage souhaité en retour
45 string : la chaîne dont il faut convertir l'encodage
46
47 On pourra utiliser to_code='ascii//TRANSLIT' pour supprimer les accents.
48 Attention : ça ne fonctionne pas à 100% !
49
50 Plus de détails dans la page de manuel de iconv(1).
51 """
52
53 # on commence par créer un contexte de conversion
54 cp = _iconv_open(c_char_p(to_code), c_char_p(from_code))
55
56 # on prépare les structures de données à transmettres
57 inbuf = create_string_buffer(string, 1024)
58 inbytesleft = c_size_t(len(inbuf))
59 outbuf = create_string_buffer(4096)
60 outbytesleft = c_size_t(len(outbuf))
61
62 # on effectue la conversion
63 _iconv(cp, byref(pointer(inbuf)), byref(inbytesleft),
64 byref(pointer(outbuf)), byref(outbytesleft))
65 result = outbuf.value[:outbytesleft.value]
66
67 # on détruit le contexte de conversion et on retourne le résultat
68 _iconv_close(cp)
69 return result
70
71if __name__ == "__main__":
72 # on précise la translitération via un environnement linguistique
73 from locale import setlocale, LC_ALL
74 setlocale(LC_ALL, 'en_US.UTF-8')
75
76 # test de cas limites (en français, vietnamien et japonais)
77 from unicodedata import normalize
78 t = u"fête cœur français tiếng việt đường プログフ"
79 i = iconv("utf-8", "ascii//TRANSLIT", t.encode('utf-8'))
80 u = normalize("NFKD", t).encode('ascii','ignore')
81 print u"TEST: texte original: '%s'" % t
82 print u"TEST: iconv(utf8..ascii//TRANSLIT): '%s'" % i
83 print u"TEST: normalize(NFKD).encode(ascii,ignore): '%s'" % u
84