テキストの管理

次のドキュメント

■ テキストデータの保持

 プレーンなテキストデータを計算機内部に保持する方法は様々ありますが、 現状のViViは双方向リンクによる管理方法を採用しています。具体的にはMFCが提供する CStringList クラスを使用しています(なあんだ、と思われる方もいるかもしれませんが、内実はそんなもんです)。
 しかし開発言語はC++を採用しているので、適当にカプセル化されており、 データの管理方法に何らかの問題があると解ったら、 必要最低限度の修正でデータ構造を変更することができるはずです。 この辺がOOPの実際的な利益のひとつであると考えています。
 テキストデータを管理するクラスは CStringList の派生クラスである CDocLineMgr です。 このクラスはデータメンバとして双方向リンクによりテキストデータを保持し、そのデータを参照・ 修正するいくつかのメソッドを持っています。OOP風に図示すると以下のようになります。

CDocLineMgr:
┏━━━━━━━━━━━━━┓
┃  参照・編集メソッド  ┃
┃┌───────────┐┃
┃│ドキュメントが保持する│┃
┃│テキストデータ    │┃
┃└───────────┘┃
┗━━━━━━━━━━━━━┛

 参照メソッドは指定した範囲の文字列を返します。編集メソッドは指定位置に文字列を挿入、置換、移動、 削除を行います。これらのメソッド以外にもサポート的なメソッドが少しあります。
 クラスの定義は以下のような感じです(SLTextPos については次節を参照)。

    class CDocLineMgr : public CStringList {
        .....
    public:
        CDocLineMgr(void) : CStringList(1000)   { init(); };
        ~CDocLineMgr(void);

        const CString   &getLineString(int line);
        int         getText(const SLTextPos *, const SLTextPos *, CString &);

        void        insertText(SLTextPos *, const char *);
        void        deleteText(const SLTextPos *, const SLTextPos *, CString &);
        void        replaceText(const SLTextPos *, const SLTextPos *, SLTextPos *,
                                            const char *, CString &);
        void        moveText(SLTextPos *, SLTextPos *, SLTextPos *);
        void        doShiftLeft(int, int, int &, int *&);
        void        doShiftRight(int, int, int , const int *);
        void        doChangeLineorder(int, int, const int *, int rev=0);
        void        doLineorderRevers(int, int);
        void        doChangeBlockorder(int, int, int, const int *, int rev=0);
        .....
    };

■ 文字位置の指定方法

 前節で示したように、CDocLineMgr のメソッドは引数に文字位置を取ります。文字位置を表わすための構造体が SLTextPos です。
 SLTextPos のメンバ変数は行番号と行の先頭からのオフセット(文字数ではなくバイト数)の2つの数値です。 行番号は画面のレイアウトとは無関係に改行コードで区切られる単位で、ViViではこれを論理行と呼びます。 したがって、論理行番号と論理行の先頭からのオフセットによる位置の指定を論理座標系による指定と呼びます (この他にも後述するレイアウト座標系もあるが、構造体(SVTextPos)の定義は同一です)。
 定義は以下のようになっています。各種コンストラクタに加え、前後の比較を行う演算子を定義しています。
    struct SLTextPos {
        int     m_line;                 //  行番号(0オリジン)
        int     m_offset;               //  行頭からのオフセット
    public:
        SLTextPos(void);
        SLTextPos(int line, int offset);
        SLTextPos(const SLTextPos &pos);
        SLTextPos(const SLTextPos *pos);

        BOOL operator==(const SLTextPos &pos) const;
        BOOL operator!=(const SLTextPos &pos) const;
        BOOL operator>(const SLTextPos &pos) const;
        BOOL operator>=(const SLTextPos &pos) const;
        BOOL operator<(const SLTextPos &pos) const;
        BOOL operator<=(const SLTextPos &pos) const;
    };

次のドキュメント  ViViのページに戻る。

Copyright (c) 1997 by Nobuhide Tsuda, All Right Reserved.
このホームページに関するご質問、ご要望、バグレポート等は  ntsuda@beam.or.jp  までメールをいただければ幸いです。