Lisp: Besoin d'aide pour obtenir le comportement correct de SBCL lors de la conversion d'un flux d'octets en EUC-JP avec des octets mal formés
Question
Ce qui suit ne fonctionne pas dans ce cas particulier, se plaignant que tout ce que vous donnez ne soit pas un caractère.
(handler-bind ((sb-int:character-coding-error
#'(lambda (c)
(invoke-restart 'use-value #\?))))
(sb-ext:octets-to-string *euc-jp* :external-format :euc-jp))
Où * euc-jp *
est une variable contenant le binaire du texte codé EUC-JP.
J'ai aussi essayé # \ KATAKANA_LETTER_NI
au lieu de # \? et aussi juste """. Rien n'a fonctionné jusqu'à présent.
Toute aide serait grandement appréciée!
EDIT: pour reproduire * EUC-JP *
, récupérez http://blogs.yahoo.co.jp/akira_w0325/27287392.html à l'aide de drakma.
La solution
Le mb-util.lisp
de SBCL 1.0.18 contient une expression ressemblant à ceci:
(if code
(code-char code)
(decoding-error array pos (+ pos bytes) ,format
',malformed pos))
Je ne connais pas très bien les éléments internes de la SBCL, mais cela ressemble à un bug. La conséquence retourne un caractère, alors que l’alternative retourne une chaîne (quoi que vous lui donniez via USE-VALUE
, elle est toujours convertie en chaîne au moyen de STRING
. voir la définition de DECODING-ERROR
dans octets.lisp
).
Autres conseils
Cela fonctionne pour moi:
CL-USER> (handler-bind ((sb-int:character-coding-error
#'(lambda (c)
(declare (ignore c))
(invoke-restart 'use-value #\?))))
(sb-ext:octets-to-string (make-array '(16)
:element-type '(unsigned-byte 8)
:initial-contents '#(181 65 217 66 164 67 181 217 164 223 164 222 164 185 161 163))
:external-format :euc-jp))
"?A?B?C休みます。"
Le * euc-jp *
pourrait-il être autre chose qu'un (vecteur (octet non signé 8))??