ClozureCL で文字のバイト数を判定
ClozureCLでマルチバイト文字のバイト数を判定する - Shammerismでは、encode-string-to-octets を使用したが、mutiple-value-bind を使用しないといけないなど、面倒な点があったので、純粋に文字のバイト数をカウントする処理を実装。UTF-8 のみに対応という状態だが。
(defun utf-8-string-byte-size (s) (if (stringp s) (let ((char-array (coerce s 'list)) (length 0)) (dolist (x char-array) (setf x (char-code x)) (cond ((equal x 10) (setf length (+ length 2))) ((or (<= x #x7f) (equal x #xa0)) (setf length (+ length 1))) ((and (>= x #x80) (<= x #x7ff)) (setf length (+ length 2))) ((and (>= x #x800) (<= x #xffff)) (setf length (+ length 3))) ((and (>= x #x10000) (<= x #x1fffff)) (setf length (+ length 4))) ((and (>= x #x200000) (<= x #x3ffffff)) (setf length (+ length 5))) ((and (>= x #x4000000) (<= x #x7fffffff)) (setf length (+ length 6))))) length) 0))
とりあえず、文字だったら問答無用で UTF-8 とみなして判定する。0x80 とかは、#x80 という感じにすることでヘキサで扱えるようだ。
以下、実行結果。
? (utf-8-string-byte-size "あいうえおabcdefg") 22 ? (encode-string-to-octets "あいうえおabcdefg" :external-format :utf-8) #(227 129 130 227 129 132 227 129 134 227 129 136 227 129 138 97 98 99 100 101 102 103) 22 ?