
辞書の形式

辞書は、

ヘッダー、コメント、品詞リスト、頻度、品詞、漢字、
登録可能形式インデックス1(テーブル)、
逆変換インデックス1(読み)、逆変換インデックス1(漢字)、
インデックス2(本体)、逆変換インデックス2

からなる。

インデックスに関する情報は、辞書の種類によって存在したりしなかったりす
るが、存在しないというのは、プログラムの中では、存在するが大きさが0と
して扱われている。

	どの形式の辞書で、どのインデックス部分を用いているか。

					固定	逆変換	登録

登録可能形式インデックス1(テーブル)			○
逆変換インデックス1(読み)			○	
逆変換インデックス1(漢字)			○	
インデックス2(本体)			○		○
逆変換インデックス2				○	

●ヘッダ
ヘッダは、128バイトの大きさを持つ。これは、ファイルのヘッダ
に続いて置かれる。内容は、

syurui(固定 = 1、登録 = 2、逆変換 = 3)
maxcomment(コメントの長さ)
maxhinsi_list(品詞リストの大きさ)
maxserial(シリアル番号の最大値)
maxkanji(漢字部分の長さ)
maxtable(登録可能形式インデックス1の長さ = struct uind1 の個数)
maxhontai(インデックス2の長さ)
gosuu(辞書の語数)
hpasswd(辞書内頻度部分を変更するためのパスワード(WNN_PASSWD_LEN))
total(トータル頻度(未使用))
maxri1[D_YOMI](逆変換インデックス1(読み)の長さ = struct rind1 の個数)
maxri1[D_KANJI](逆変換インデックス1(漢字)の長さ = struct rind1 の個数)
maxri2(逆変換インデックス2の長さ = struct rind2 の個数)
56バイト 未使用領域(0)
  
ヘッダー部分を含め、全ての部分のバイトオーダは、ビッグ・インディアン
(68000系)である。

●コメント
maxcomment の大きさの w_char の配列

●品詞リスト
maxhinsi の大きさの w_char の配列。実際のhinsi_node の構造は、
辞書を読み込む時に作られる。

●頻度
maxserial の大きさの unsigned char の配列

●品詞
maxserial の大きさの unsigned short の配列

●漢字
漢字、読み、およびコメントの情報を持つ。(辞書の形式により、持つ情報は異なる。)
可変長のデータ。(maxkanji が大きさを表している)
各漢字情報は、ワード境界に合っている必要がある。
同じ読みを持ち、シリアル番号が連続したエントリの漢字部分は、連続していな
くてはならない。そのため、例えば、forward を行なった時、forward 先の
漢字部分の前後の漢字部分に対応するシリアル番号が連続しないように
する必要がある。

この部分の構造は、将来的に変更になる可能性がある。
(bug が恐くて変更したいが変更ができない)

各漢字情報のデータ形式

長さ(1バイト) unsigned char での漢字情報の大きさ。
(すなわち、漢字、読み、コメントを合わせて 256バイトの制限がある。)

この漢字情報の状態state(1バイト)
	第0ビット(HAS_YOMI) : 読みの情報も持っているかどうか。
	第1ビット(HAS_KANJI) : コメントの情報も持っているかどうか。
	第2ビット(FORWARDED) : フォアワードされているかどうか。
	第3-7ビット : 未使用

以下、state の状態に応じて、残りのデータの形式を述べる。

◎state & FORWARDED が 0 でない時
	この後に、forward された先の番地が、この漢字情報の先頭からの
相対の数字として置かれる。この数字を表すのに、4バイト用いている。
forward 先は、常に、現在の漢字情報の位置より先でなくてはならない。
ワード境界の関係上、forward先の番地は
先頭の 2 バイトが上位2バイト、次の2バイトが下位2バイトとなっている。
すなわち、kptr が漢字情報の先頭への unsigned char のポインタの時、
forward 先のアドレスは、
	(*(w_char *)(kptr + 2)) << 16 | (*(w_char *)(kptr + 4))
で得られる。
forward は、comment set のために、漢字情報の内容に変更を受け、
現在の漢字情報の領域に書き切れない時に、用いられる。

◎state & FORWARDED が 0 で、state & HAS_YOMI が 0 でないとき。
	これは、逆変換形式の時の形式である。読み、漢字が、
内部 UJIS の文字列として置かれる。また、state & HAS_COMMENT が 0 でないとき
には、エントリのコメントが内部 UJIS の文字列としてこの後に続く。

◎state & FORWARDED が 0 で、state & HAS_YOMI が 0 のとき。
	これは、登録可能形式、固定形式の場合である。漢字が
内部 UJIS の文字列として置かれる。また、state & HAS_COMMENT が 0 でないとき
には、エントリのコメントが内部 UJIS の文字列としてこの後に続く。

なお、全ての内部 UJIS の文字列は、null terminate をしている。

●逆変換形式のインデックス。
逆変換形式のインデックスは、
逆変換インデックス1(読み)、逆変換インデックス1(漢字)、
逆変換インデックス2 の 3つの部分からなる。

逆変換インデックス1(読み)、逆変換インデックス1(漢字)は、struct rind1 の
配列で、それぞれ maxri1[D_YOMI]、maxri1[D_KANJI] の大きさを持つ。
逆変換インデックス2 は、struct rind2 の配列で、maxri2 の大きさを持つ。

struct rind1 {
  int pter1;                    /* pointer to rind1 */
  int pter;                     /* pinter to rind2 */
};

struct rind2 {
  int next[2];                  /* pointer to rind2 */
  int kanjipter;
};

struct rind2 は、各エントリを表している。
逆変換インデックス2 の中での struct rind2 のインデックスは、その
エントリのシリアル番号を表している。next[D_YOMI] は
同じ読みを持つ次の rind2 のインデックスを、next[D_KANJI] は
同じ漢字を持つ次の rind2 のインデックスを指している。これらの
インデックスの最後は、RD_ENDPTR = 0xffffffff である。

逆変換インデックス1(読み)、逆変換インデックス1(漢字)の
struct rind1 は、それぞれ同じ読み、同じ漢字のエントリの集合に
を表している。pter は、それぞれの struct rind1 の表す読み、漢字を持つ先頭の
rind2 のインデックスである。また、pter1 は、このrind1 の表す読み、漢字
の最長部分文字列をあらわす rind1 のインデックスである。
部分文字列の rind1 が存在しない時には、 pter1 の値は RD_ENDPTR である。

＃rind1.pter1, rind1.pter, rind2.next[D_YOMI], rind2.next[D_KANJI]
＃は、全て int であるが、辞書の語数を 65535 までに制限するならば、
＃これらは unsigned short でよい。この変更を加えると、辞書のサイズは
＃大幅に小さくなる。

