Archive for 2011年1月|Monthly archive page
pack と unpack
UTF-8 版 newLISP では、explode が文字単位で動作します。だから、マニュアルの例にある
> (explode "¥000¥001¥002¥003") ("¥000" "¥001" "¥002" "¥003")
が使えません。なので、バイナリ・データを扱う時、UTF-8 版は使えないと思っていたのですが、私の理解が足りないだけでした(汗)。元ネタは、こちら。
こういった場合、unpack を使います。
(define (str2bytes str) (unpack (dup "b" (length str)) str))
ここで、"b" は符号なし8ビット数を指定しています。ちなみに、"c" だと符号付き8ビット数です。
これを使えば、
> (str2bytes "¥000¥001¥002¥003") (0 1 2 3)
となります。扱いやすいように数値に変換していますが、文字列のままにしたい時は、unpack で "s" を指定します。
> (unpack (dup "s" 4) "¥000¥001¥002¥003") ("¥000" "¥001" "¥002" "¥003")
さて、バイト数列から、バイナリ・データ(文字列)に変換するには、当然 pack を使います。
(define (bytes2str lst) (pack (dup "b" (length lst)) lst))
UTF-8 版 newLISP でなければ、(mappend は newlisp-utility.lsp に定義してあります。)
(define (bytes2str lst) (mappend char lst))
or(define (bytes2str lst) (apply append (map char lst)))
とも書けます。
ということで、UTF-8 版 newLISP でもバイナリ・データを扱えるようになりました。つまり、UTF-8 版 newLISP 上でShift-JIS データを UTF-8 データに変換できるということ。
これで、Windows 環境でも UTF-8 版 newLISP だけでアプリケーションを組めるようになりました(笑)。
以上、如何でしょうか?
newLISP v10.2.18 の翻訳マニュアル
newLISP の開発バージョンが v10.2.18 にバージョンアップされたので、このバージョンのマニュアルの翻訳を up しました。
もちろん、目次も日本語併記にしてあります。
変更された関数は、extend、net-liten、ref、ref-all、signal です。詳細はマニュアルでどうぞ。
また、同梱されている guiserver は、v1.43 です。
いつものように、間違いやおかしな点が有りましたら、こちらの blog までご一報下さい。
以上、如何でしょうか?
newLISP マニュアル・アップデート v.10.2.8 rev-22
newLISP のマニュアルが rev-22 のバージョンアップされたので、それに合わせたアップデートです。
変更内容は、組込set-ref と set-ref-all の一部表現の変更です。関数の機能が変わったわけではありません。
ただし、ついでに、日本語訳を一部訂正しています(汗)。
newLISP マニュアル & リファレンス の全訳のリリースで、現在のバージョンは、v.10.2.8 rev 22 です。
目次も含め日本語併記にしてあります。
いつものように、間違いやおかしな点が有りましたら、こちらの blog までご一報下さい。
以上、如何でしょうか?
newLISP で音楽を楽しむ...UTF-8化(解説編)
“newLISP で音楽を楽しむ...UTF-8化”は、如何だったでしょうか?
WideChar 対応で使う Windows API は、
(import "winmm.dll" "mciSendStringW")
(import "winmm.dll" "mciGetErrorStringW")
となります。ただし、ファイル名を使わないコマンドには、WideChar は必要ないので、
(import "winmm.dll" "mciSendStringA")
も残してあります。
UTF-8 版 newLISP の文字列は、当然、文字コードがUTF-8 コードですので、それを WideChar に変換するには、組込unicode を使います。
ただし、組込unicode の戻り値は、4バイトの UNICODE文字列。日本語 Windows の WideChar は、2バイトなので、変換しなければなりません。
(define (long2word str)
(let (res "")
(dotimes (i (/ (length str) 4))
(let (c (slice str (* 4 i) 2))
(unless (= c "¥000¥000")
(extend res c))))
res))
組込explode や暗黙のインデックス機能が使えれば良いのですが、どちらも文字単位で動作します。
そこで、バイト単位で動作する組込slice を使って上位2バイトの “/000/000” を削除しています。
WideChar から UTF-8 に変換するには、組込utf8 を使います。しかし、引数は 4バイトの UNICODE文字列です。
そこで、WideChar に上位2バイトの “/000/000” を付加する関数も用意します。
(define (word2long str)
(let (res "")
(dotimes (i (/ (length str) 2))
(let (c (slice str (* 2 i) 2))
(unless (= c "¥000¥000")
(extend res c "¥000¥000"))))
(extend res "¥000¥000¥000¥000")))
これらを、組込unicode と utf8 に組み合わせるだけです。
(define (toWchar str)
(long2word (unicode str)))
(define (toChar str)
(utf8 (word2long str)))
関数toWchar が UTF-8 文字列を WideChar 文字列に変換し、関数toChar がその逆です。
そして、ファイルが必要な関数 music:open と エラー内容を表示する関数 get-err-str に組み込めば終わりです。
残りは、以前の“newLISP で音楽を楽しむ...context 化”と一緒です。
以上、如何でしょうか?
newLISP で音楽を楽しむ...UTF-8化
以前、Windows API を使った音楽ファイルを再生するスクリプトを紹介しましたが、WideChar には、対応していなかったので、”é” を含むようなファイル名の音楽ファイルには、使えませんでした(汗)。
現在では、WIndows 上でも、UTF-8版 newLISP を使えるので、WideChar 対応にできるはず(guiserver.jar には開発版のV1.43がお薦め)。
ということで、スクリプトを作ってみました。
(context 'MAIN:music)
(import "winmm.dll" "mciSendStringW")
(import "winmm.dll" "mciSendStringA")
(import "winmm.dll" "mciGetErrorStringW")
(define l_rtnStr 128)
(define rtnStr (dup "¥000" (+ 1 l_rtnStr)))
(define (long2word str)
(let (res "")
(dotimes (i (/ (length str) 4))
(let (c (slice str (* 4 i) 2))
(unless (= c "¥000¥000")
(extend res c))))
res))
(define (word2long str)
(let (res "")
(dotimes (i (/ (length str) 2))
(let (c (slice str (* 2 i) 2))
(unless (= c "¥000¥000")
(extend res c "¥000¥000"))))
(extend res "¥000¥000¥000¥000")))
(define (toWchar str)
(long2word (unicode str)))
(define (toChar str)
(utf8 (word2long str)))
(define (get-err-str n)
(mciGetErrorStringW n rtnStr l_rtnStr)
(println (toChar rtnStr)))
(define alias-name " Music")
(define wait-time 500)
(define (music:open m)
(mciSendStringW (toWchar (string "open \"" m "\" alias" alias-name)) 0 0 0))
(define-macro (make-status)
(letex (_cmd (string "status" alias-name " " (args 0))
_func (sym (string (args 0))))
(define (_func) (mciSendStringA _cmd rtnStr l_rtnStr 0) rtnStr)))
(make-status "mode")
(make-status "position")
(make-status "length")
(define-macro (make-music)
(letex (_cmd (string (args 0) alias-name)
_func (sym (string (args 0))))
(define (_func) (mciSendStringA _cmd 0 0 0))))
(make-music "close")
(make-music "play")
(make-music "stop")
(make-music "pause")
(define (volume-off)
(mciSendStringA "set Music audio all off" 0 0 0))
(define (volume-on)
(mciSendStringA "set Music audio all on" 0 0 0))
(context MAIN)
使い方は、“newLISP で音楽を楽しむ...context 化”と一緒ですが、動作には、Windows の UTF-8版newLISP が必要です。お間違えなく(笑)。
WideChar対応の解説は、次回に。
以上、如何でしょうか?