[Anthy-dev 2515] Re: r5rs: portの抽象化

Back to archive index

Jun Inoue jun.l****@gmail*****
2005年 10月 11日 (火) 20:06:22 JST


On Mon, 10 Oct 2005 02:53:45 +0900
YamaKen <yamak****@bp*****> wrote:

> …とここまで書いて気付いたんですが、vtblのアドレス自身を型IDと見
> なせば何も消費しませんね。vtbl全体をconstにもできるし。

Singleton でよかったんですか。じゃあそれで。


> > あ、ところで member 変数名は cport より info か desc の方がよいでする。
> 
> ScmCPortは抽象portの実体そのものなので、infoやdescといった具象デー
> タを想起させるような名前は誤解の元だと思います。むしろimplとかに
> してしまった方がいいかも。

へ? 実体 = 具象 data じゃないんですか? ScmFilePort は FILE* 持ってるし、
ScmStrPort は buffer 持ってるし、もろにその port instance の具象
metadata (というか state) を表現する descriptor だと思うんですが。


> > > > これは get_byte(), peek_byte(), byte_readyp() or number_of_bytes_ready
> > > > () にしましょう。Multibyte port を読むとき次の文字が何 bytes 含むかの判
> > > > 定は SigScheme 側で書きたいところです。
> > > 
> > > その方がいいですね。3つ目の関数名はbytelen_ready()なんてどうでしょ
> > > う。
> > 
> > 意味はわかるけど何か変ですねぇ…
> 
> > bytes_ready (port, SCM_MB_MAX_LEN);
> > => SCM_MB_MAX_LEN 以下の非負整数
> > みたいな使い方を想定しています。File port に毎回 file 終端までのサイズを
> > 返させるわけにはいきませんので。
> そういう目的でしたか。その例を見て気付いたんですが、
> encoding-awareなport(QtのQTextStreamをwrapするportとか)に対して
> はcharを直接入出力できた方が嬉しいですね。
> 
> というわけで、以下のような2段構成はどうでしょうか? この場合上記
> の例はScmStdCharPortのrbufが溜まるまでbyte_readp()を繰り返す事で
> 実現できます。

そうですね…双方向 multibyte port ができないかと色気を出してたんですが、
無理なのでそれで行きましょう。ただし rbuf/wbuf は区別する意味がありませ
ん。SigScheme 側から write-char するなら必ず文字単位で data が提供される
し、write-byte したときはそもそも文字が完成する事が期待できません。そし
て multibyte bidirectional port を support しない (できない) ので
memory の無駄です。

ちなみに何で mb bidi port ができないかわからなければ
cat "^[$ErR" > tmp
して以下の script を走らせたときの動作を想像してください。
(with-encoding
 'iso-2022-jp
 (with-io-file ; 双方向 port
  "tmp"
  (lambda ()
    (read-char) ; 何が返ってくる?
    (write-char #\a); 何 byte 目に書き込まれる?
    )))
Gauche も modgauche.texi によればこのへん妥協してますね。っていうかそも
そも可変長の object 単位で read/write しときながらエラー処理と整合性を両
立しようというのが間違ってる。

ところで encoding 指定は symbol 推奨。case 句に渡せるし、比較 predicate
が全部効くし、string-append で構築したくなるような事もないでしょう。もし
あっても symbol-append 作れば済みますし。


> R5RSがinteger->char, char->integerという形でcharを扱うので、Cレ
> ベルではintとして扱うようにしています。char自体にはencoding情報
> が保持できないのでプログラマが明示的に管理する必要がありますが、
> (with-encoding enc thunk)とかでデフォルトencodingが切り換えられ
> るようになってれば十分だと思います。少なくともuim的には。
> encoding変換機能はSigScheme本体で提供する必要はないと思います。

了解。いざとなれば iconv binding とか書く方向で。


> struct ScmPortCell_ {
>     enum ScmPortDirection direction;
>     ScmCharPort *impl;
> } port;

ScmObj 圧縮したら direction は ScmCharPort の方に入れることになるのかな…?


> struct ScmCharPortVTbl_ {
>     int (*close)(ScmCharPort cport);
>     /* returns "UTF-8", "eucJP" and so on */
>     const char *(*encoding)(ScmCharPort cport);

戻り値は symbol に。


>     /* output */
>     int (*vprintf)(ScmBytePort bport, const char *str, va_list args); /* tmp */
>     int (*put_str)(ScmBytePort bport, const char *str);
>     size_t (*put_bytestr)(ScmBytePort bport, size_t len, const char *str);
>     int (*flush)(ScmBytePort bport);
> };

flush 要らんす。VOLATILE_OUTPUT も要らんす。あれは C level で crash した
ときにもどこまで実行できたか確認するための機能ですが、よく考えたら
main.c で setbuf (stderr, NULL) した方が早いです。
put_bytestr () は名前が非常に misleading。put_str() の方が文字コード変換
をしそうに見える。普通に write () と puts() でいいと思うんですが…


> struct ScmFilePort_ {
>     const ScmBytePortVTbl *vptr;
> 
>     FILE *file;
> };

ScmStdCharPortVTbl 持っとく必要があります。


> struct ScmStrPort_ {
>     const ScmBytePortVTbl *vptr;
> 
>     char *str;
>     char *cur_pos;
>     size_t buf_size;
> };

struct {
  char *dat;
  char *cur; /* or `next' */
  char *end;
} buf;
希望。End pointer か buf_size かは書く人のお好みで。

-- 
Jun Inoue
jun.l****@gmail*****



Anthy-dev メーリングリストの案内
Back to archive index