# idnkitライブラリのAPI

idnkitライブラリ (およびidnkitliteライブラリ) では、アプリケーション を国際化ドメイン名に対応させるために必要な処理をC言語向けのAPIとして 提供しています。 この文書は、ライブラリの提供するAPIについて解説します。

- idnkitライブラリのモジュール
- apiモジュール
- resモジュール
- resconfモジュール
- resultモジュール
- versionモジュール

## idnkitライブラリのモジュール

idnkitライブラリおよびidnkitliteライブラリ (以下、単にidnkitライブラリ と表記。ただし両者を厳密に区別する必要がある場合はその旨を明示する) が提供する機能は、主として国際化ドメイン名のエンコードおよびデコード です。 エンコードやデコードの処理において、具体的にどのようなことを内部 で実行しているのかは、 「idnkitの変換処理の詳細」 に詳しく書いてありますので、そちらを参照して下さい。

idnkitでは、一般アプリケーション向けに、APIを機能別にいくつかの モジュールに分けて公開しています。

モジュール名 | 説明
--- | ---
api | idnkitライブラリでは「高レベルAPI」と呼んでいるモジュール。 このAPIを使用すれば、アプリケーションに国際化ドメイン名の処理を簡単に 追加することができますが、その反面、細かい設定はできません。
res | 「低レベルAPI」モジュール。 高レベルAPIでは実現できないような、細かい設定を必要とするアプリケーション 向けのAPIです。 高レベルAPIは、この低レベルAPIの上に作られています。
resconf | 低レベルAPIで使用する、「変換コンテキスト」の操作用モジュール。 低レベルAPIを使用する際は、必ず本モジュールも併せて使用する必要 があります。
result | エラーコードを定義しているモジュール。 また、エラーコードを文字列に変換するAPIも提供しています。
version | バージョン番号情報を取得するためのモジュール。

idnkitライブラリの主要機能は、高レベルAPIモジュールと低レベルAPIモジュール で提供されています。 したがって、どちらかを使ってアプリケーションを作成することになります。 主に次のようなことをしたいときは、高レベルAPIでは実現できないため、 低レベルAPIを使用することになります。 特にこうしたことを実現する必要がなければ、高レベルAPIを使用すること をお薦めします。

- 複数の異なる設定を、同時に扱いたい
- 標準とは異なるパスにある設定ファイルを、明示的に読み込みたい
- 設定ファイルの内容をファイルではなく文字列で保持しておいて、 それを読み込みたい
- 処理の途中で、設定をやり直したい

高レベルAPI、低レベルAPIを含め、多くの関数は処理が成功したか失敗したか を表す、エラーコードを返します。 成功すると`idn_success`という値を返し、失敗すれば原因に 応じて様々な値を返します。 エラーコードの一覧は、「resultモジュール」の章に 記されています。

以下に、エラーコードを用いた典型的なサンプルプログラムを示します。

>     idn_result_t r;

>     r = idn_encodename(IDN_ENCODE_LOOKUP, from, to, tolen);
>     if (r != idn_success)
>         my_error("idn_encodename() failed\n");

次より、それぞれのモジュールについて詳述します。

## apiモジュール

apiモジュールは「高レベルAPI」とも呼ばれ、国際化ドメイン名の変換処理を 比較的容易に扱えるようになっています。 apiモジュールは、次の関数から構成されます。

関数 | 説明
--- | ---
`idn_nameinit()` | 高レベルAPIモジュールの初期化
`idn_encodename()` | 国際化ドメイン名のエンコード
`idn_decodename()` | 国際化ドメイン名のデコード
`idn_decodename2()`
`idn_comparenames()` | ドメイン名同士の比較
`idn_comparenames2()`
`idn_checkname()` | ドメイン名の検証
`idn_setlocalencoding()` | ローカルエンコーディングの設定
`idn_setlanguage()` | 「現在の言語」の設定
`idn_setlocalcheckfile()` | ローカルチェック用のセットファイルの設定

低レベルAPIとは異なり、高レベルAPIは変換コンテキストを使用しないため、 より少ない記述量でidnkitライブラリを扱うことができます。 反面、変換コンテキストを用いた細かな設定は行えません。 高レベルAPIを用いたプログラムの例 (抜粋) を、以下に記します。

>     idn_result_t r;

>     /* モジュール初期化 */
>     r = idn_nameinit(1);
>     if (r != idn_success)
>         my_error("idn_nameinit() failed\n");

>     /* エンコード */
>     r = idn_encodename(IDN_ENCODE_LOOKUP, from, to, tolen);
>     if (r != idn_success)
>         my_error("idn_encodename() failed\n");

APIモジュールの初期化を行う`idn_nameinit()`関数を除き、 apiモジュールのすべての関数は、resモジュール (低レベルAPI) ないし resconfモジュール (低レベルAPIで使用する変換コンテキストの操作 モジュール) に、同等の働きをする関数が1対1で存在します。

以下、apiモジュールのそれぞれの関数について説明します。

### `idn_nameinit()`

[書式]

> `#include <idn/api.h>`
> `idn_result_t idn_nameinit(int load_file);`

idn_nameinit()は、高レベルAPI全体の初期化関数です。 load_fileに0以外を指定すると、idnkitの設定ファイルを探して 読み込みます (「設定ファイルについて」 参照)。

この関数は高レベルAPI利用時、最初に一度だけ呼び出すことを想定しています。 二度目以降の呼び出しでは、単に`idn_success`を返すだけで何も 行いません。 たとえ、二度目の呼び出しで`load_file`の値を前回と変えても、 ファイルの読み込み直しや設定内容のクリアは行いません。

`idn_nameinit()`を呼ばないうちに、他の高レベルAPI関数を 呼び出すと、暗黙的に`idn_nameinit()`が呼び出されます。 暗黙的に呼び出された場合、`load_file`には必ず0が指定されます。

本関数は、正常に処理が完了すれば`idn_success`を返し、 何かエラーが発生すれば理由を示すエラーコードを返します。

### `idn_encodename()`

[書式]

> `#include <idn/api.h>`
> `idn_result_t idn_encodename(idn_action_t actions, const char *from, char *to, size_t tolen);`

NUL文字で終端されたドメイン名文字列fromをエンコード (Punycodeへ変換) し、結果をポインタtoで指定された領域に 書き込みます。 領域toには(末尾のNUL文字を含めて) tolenバイト分 だけ書き込める大きさがあるものとします。

エンコード処理は、actions (アクション) で指定された工程だけ を実行します。 指定可能なアクションは、次の通りです。

アクション | 説明
--- | ---
`IDN_UNICODECONV` | ローカルエンコーディングからUnicode (UTF-8) への変換
`IDN_MAP` | マッピング
`IDN_ASCLOWER` | ASCIIの英大文字を小文字に変換
`IDN_RTCONV` | PunycodeからUnicodeへ変換
`IDN_PROHCHECK` | 禁止コードポイントチェック
`IDN_UNASCHECK` | 未割り当てコードポイントチェック
`IDN_NFCCHECK` | NFC適用済みチェック
`IDN_PREFCHECK` | ACE接頭辞チェック
`IDN_HYPHCHECK` | ハイフンチェック
`IDN_COMBCHECK` | 合成文字チェック
`IDN_CTXJCHECK` | 「連結制御文脈依存文字 (CONTEXTJ)」チェック
`IDN_CTXOCHECK` | ドメイン名登録プロトコル用「その他文脈依存文字 (CONTEXTO)」チェック
`IDN_CTXOLITECHECK` | ドメイン名参照プロトコル用「その他文脈依存文字 (CONTEXTO)」チェック
`IDN_BIDICHECK` | BIDI (bidirectional display; 双方向表示) チェック
`IDN_LOCALCHECK` | ローカルチェック
`IDN_IDNCONV` | UnicodeからPunycodeへの変換
`IDN_LENCHECK` | ラベル長チェック
`IDN_RTCHECK` | ラウンドトリップチェック
`IDN_UNDOIFERR` | 特殊アクション: 各種「チェック」系のアクションでエラーが発生 した場合、入力時の状態までラベルの状態を戻し、エラーを無視する。

各アクションは実際には整数値で、複数の工程を指定するには、次のように アクション値の論理和 (OR) を指定します。

> `idn_encodename(IDN_UNICODECONV | IDN_MAP, from, to, tolen);`

上記の各アクションを一つ一つ指定するのは大変なので、エンコード時に 通常行う処理をすべて実行する「複合アクション」が提供されています。 通常は、こちらを指定することになると思います。

アクション | 説明
--- | ---
`IDN_ENCODE_REGIST` | ドメイン名登録プロトコルによるエンコード処理を、一通り行います。 idnkitライブラリでは、`IDN_CTXOLITECHECK`, `IDN_LOCALCHECK`を除く、すべてのアクションを実行します。 idnkitliteライブラリでは、`IDN_UNICODECONV`, `IDN_CTXOLITECHECK`, `IDN_LOCALCHECK`を除く、 すべてのアクションを実行します。
`IDN_ENCODE_LOOKUP` | ドメイン名参照プロトコルによるエンコード処理を、一通り行います。 idnkitライブラリでは、`IDN_CTXOCHECK`, `IDN_LOCALCHECK`を除く、すべてのアクションを実行します。 idnkitliteライブラリでは、`IDN_UNICODECONV`, `IDN_CTXOCHECK`, `IDN_LOCALCHECK`を除く、 すべてのアクションを実行します。

`IDN_UNICODECONV`を実行しない場合、fromには ドメイン名がUTF-8で書かれているものと見なされます。 エンコード処理について詳しくは、 「エンコード処理の詳細」 を参照して下さい。

本関数は、正常に処理が完了すれば`idn_success`を返し、 何かエラーが発生すれば理由を示すエラーコードを返します。

### `idn_decodename()`

[書式]

> `#include <idn/api.h>`
> `idn_result_t idn_decodename(idn_action_t actions, const char *from, char *to, size_t tolen);`

NUL文字で終端されたドメイン名文字列fromをデコード (PunycodeからUnicodeないしローカルエンコーディングへ変換) し、結果を ポインタtoで指定された領域に書き込みます。 領域toには(末尾のNUL文字を含めて) tolenバイト分 だけ書き込める大きさがあるものとします。

デコード処理は、actions (アクション) で指定された工程だけ を実行します。 指定可能なアクションは、次の通りです。

アクション | 説明
--- | ---
`IDN_UNICODECONV` | ローカルエンコーディングからUnicode (UTF-8) への変換
`IDN_MAP` | マッピング
`IDN_ASCLOWER` | ASCIIの英大文字を小文字に変換
`IDN_IDNCONV` | PunycodeからUnicodeへの変換
`IDN_PROHCHECK` | 禁止コードポイントチェック
`IDN_UNASCHECK` | 未割り当てコードポイントチェック
`IDN_NFCCHECK` | NFC適用済みチェック
`IDN_PREFCHECK` | ACE接頭辞チェック
`IDN_HYPHCHECK` | ハイフンチェック
`IDN_COMBCHECK` | 合成文字チェック
`IDN_CTXJCHECK` | 「連結制御文脈依存文字 (CONTEXTJ)」チェック
`IDN_CTXOCHECK` | ドメイン名登録プロトコル用「その他文脈依存文字 (CONTEXTO)」チェック
`IDN_CTXOLITECHECK` | ドメイン名参照プロトコル用「その他文脈依存文字 (CONTEXTO)」チェック
`IDN_BIDICHECK` | BIDI (bidirectional display; 双方向表示) チェック
`IDN_LOCALCHECK` | ローカルチェック
`IDN_RTCHECK` | ラウンドトリップチェック
`IDN_LOCALCONV` | Unicode (UTF-8) からローカルエンコーディングへの変換
`IDN_UNDOIFERR` | 特殊アクション: 各種「チェック」系のアクションでエラーが発生 した場合、入力時の状態までラベルの状態を戻し、エラーを無視する。

各アクションは実際には整数値で、複数の工程を指定するには、次のように アクション値の論理和 (OR) を指定します。

> `idn_decodename(IDN_UNICODECONV | IDN_MAP, from, to, tolen);`

上記の各アクションを細かく指定するのは大変なので、複数のアクションを一度 に実行する「複合アクション」が提供されています。

アクション | 説明
--- | ---
`IDN_DECODE_REGIST` | ドメイン名登録プロトコルによるデコード処理を、一通り行います。 idnkitライブラリでは、`IDN_CTXOLITECHECK`, `IDN_LOCALCHECK`を除く、すべてのアクションを実行します。 idnkitliteライブラリでは、`IDN_UNICODECONV`, `IDN_CTXOLITECHECK`, `IDN_LOCALCHECK`, `IDN_LOCALCONV`を除く、すべてのアクションを実行します。
`IDN_DECODE_LOOKUP` | ドメイン名参照プロトコルによるデコード処理を、一通り行います。 idnkitライブラリでは、`IDN_CTXOCHECK`, `IDN_LOCALCHECK`を除く、すべてのアクションを実行します。 idnkitliteライブラリでは、`IDN_UNICODECONV`, `IDN_CTXOCHECK`, `IDN_LOCALCHECK`, `IDN_LOCALCONV` を除く、すべてのアクションを実行します。

`IDN_UNICODECONV`を実行しない場合、fromには ドメイン名がUTF-8で書かれているものと見なされます。 同様に`IDN_LOCALCONV`を実行しない場合、to には変換結果のドメイン名がUTF-8で書かれます。 デコード処理について詳しくは、 「デコード処理の詳細」 を参照して下さい。

本関数は、正常に処理が完了すれば`idn_success`を返し、 何かエラーが発生すれば理由を示すエラーコードを返します。

### `idn_decodename2()`

[書式]

> `#include <idn/api.h>`
> `idn_result_t idn_decodename2(idn_action_t actions, const char *from, char *to, size_t tolen, const char *auxencoding);`

`idn_decodename2()`は`idn_decodename()`と同様に デコードを行う関数ですが、auxencodingという引数が足され ている点が異なります。

auxencodingにはエンコーディング名 (例: "euc-jp" や "ISO8859-1") を表す文字列を渡します。 文字列fromは、まずauxencodingエンコーディング からUTF-8に変換され、その後でデコード処理が行われます。 デコード処理では、たとえactionsに `IDN_UNICODECONV`アクション (ローカルエンコーディングから Unicodeへの変換) が指定されていても無視されます。

それ以外はすべて、`idn_decodename()`と同じです。 auxencodingにNULLを渡すと、UTF-8と見なされます。

### `idn_comparenames()`

[書式]

> `#include <idn/api.h>`
> `idn_result_t idn_comparenames(idn_action_t actions, const char *name1, const char *name2);`

NUL文字で終端されたドメイン名文字列name1および name2が、ドメイン名として一致しているかどうか調べます。 name1およびname2を、まず指定されたアクション値 actionsにしたがってエンコードし、エンコードした結果同士の 一致比較を行います。 2つのドメイン名が一致していれば`idn_success`を返し、 一致していなければ`idn_neq`を返します。 一致比較の際、ASCIIの英大文字と小文字の違いは無視されます。 name1, name2は国際化ドメイン名である必要はなく、 従来の英数字とハイフンからなるドメイン名でも一致すれば `idn_success`が返ります。

ドメイン名のどちらか一方が、一致比較前のエンコードでエラーになると、 その原因を示すエラーコードを返します。 ドメイン名が両方ともエンコードでエラーになる場合、どちらのエラー原因 に基づくエラーコードを返すのかは、未定義です。

本関数用に、専用の複合アクションが用意されています。 ただし、現状では`IDN_COMPARE_REGIST`は `IDN_ENCODE_REGIST`と定義は同じであり、 `IDN_COMPARE_LOOKUP`も `IDN_ENCODE_LOOKUP`と同じ定義になっています。

アクション | 説明
--- | ---
`IDN_COMPARE_REGIST` | ドメイン名登録プロトコルによるエンコード処理を、一通り行います。 idnkitライブラリでは、`IDN_CTXOLITECHECK`, `IDN_LOCALCHECK`を除く、すべてのアクションを実行します。 idnkitliteライブラリでは、`IDN_UNICODECONV`, `IDN_CTXOLITECHECK`, `IDN_LOCALCHECK`を除く、 すべてのアクションを実行します。
`IDN_ENCODE_LOOKUP` | ドメイン名参照プロトコルによるエンコード処理を、一通り行います。 idnkitライブラリでは、`IDN_CTXOCHECK`, `IDN_LOCALCHECK`を除く、すべてのアクションを実行します。 idnkitliteライブラリでは、`IDN_UNICODECONV`, `IDN_CTXOCHECK`, `IDN_LOCALCHECK`を除く、 すべてのアクションを実行します。

### `idn_comparenames2()`

[書式]

> `#include <idn/api.h>`
> `idn_result_t idn_comparenames2(idn_action_t actions1, const char *name1, actions2, const char *name2);`

`idn_comparenames2()`は、`idn_comparenames()`と 同様に一致比較を行う関数ですが、name1をエンコードする際は アクション値actions1を用い、name2をエンコード する際はアクション値actions2を用いる点が異なります。

### `idn_checkname()`

[書式]

> `#include <idn/api.h>`
> `idn_result_t idn_checkname(idn_action_t actions, const char *name);`

NUL文字で終端されたドメイン名文字列nameが、国際化ドメイン名 として正しいかどうかチェックします。つまり、

> `idn_encodename(actions, name, to, tolen);`

を呼び出して返されるのと同じエラーコード値を、本項の関数は返します。 (ここで、変換結果の格納先 toは十分に大きく、tolenも領域toの 大きさを正確に表しているものとします。) ただし例外として、メモリ不足のようなシステムエラーを表すエラーコード が返ってきた場合は、エンコード関数を呼んでも同じエラーコードを返すか どうかは、保証の限りではありません。

国際化ドメイン名として正しければ`idn_successが`返り、 何らかのチェックに引っかればその原因を示すエラーコードが返ります。 nameに従来のドメイン名を渡した場合も、ラベル長チェック などのチェックに引っかからなければ、`idn_success` が返ります。

本関数には、専用の複合アクションが用意されています。 ただし、現状では`IDN_CHECK_REGIST`は `IDN_ENCODE_REGIST`と定義は同じであり、 `IDN_CHECK_LOOKUP`も `IDN_ENCODE_LOOKUP`と同じ定義になっています。

アクション | 説明
--- | ---
`IDN_CHECK_REGIST` | ドメイン名登録プロトコルによるエンコード処理を、一通り行います。 idnkitライブラリでは、`IDN_CTXOLITECHECK`, `IDN_LOCALCHECK`を除く、すべてのアクションを実行します。 idnkitliteライブラリでは、`IDN_UNICODECONV`, `IDN_CTXOLITECHECK`, `IDN_LOCALCHECK`を除く、 すべてのアクションを実行します。
`IDN_CHECK_LOOKUP` | ドメイン名参照プロトコルによるエンコード処理を、一通り行います。 idnkitライブラリでは、`IDN_CTXOCHECK`, `IDN_LOCALCHECK`を除く、すべてのアクションを実行します。 idnkitliteライブラリでは、`IDN_UNICODECONV`, `IDN_CTXOCHECK`, `IDN_LOCALCHECK`を除く、 すべてのアクションを実行します。

### `idn_setlocalencoding()`

[書式]

> `#include <idn/api.h>`
> `idn_result_t idn_setlocalencoding(const char *name);`

ローカルエンコーディングをnameにセットします。 この関数でローカルエンコーディングを指定すると、環境変数 `IDN_LOCAL_CODESET`やロケールの設定にかかわらず、 エンコーディング名が強制的にセットされます。 ローカルエンコーディングのセットは、本関数を再び呼ぶまで有効です。 ただし、nameにNULLを指定すると、強制セットは解除され、 環境変数`IDN_LOCAL_CODESET`がセットされていればその値、 セットされてなければロケールの設定から導出したローカルエンコーディング が使用されるという、元の状態に戻ります。

ロケールの設定からローカルエンコーディングを決定する場合、 ローカルエンコーディングの決定処理は、ローカルエンコーディング値 の参照が必要な都度 (つまり、エンコードやデコードを行う度に) 行われ ます。 これは、ロケールの設定を変えると、ローカルエンコーディングも自動的 に変化することを意味します。

本関数は、正常に処理が完了すれば`idn_success`を返し、 何かエラーが発生すれば原因を示すエラーコードを返します。

### `idn_setlanguage()`

[書式]

> `#include <idn/api.h>`
> `idn_result_t idn_setlanguage(const char *name);`

「現在の言語」をnameにセットします。 これは設定ファイルの 「`language`」エントリ で指定するものと同じです。 設定ファイルでセットされた内容を、本関数は上書きしてセットします。 セットした「現在の言語」は、本関数を再び呼ぶまで有効です。 ただし、nameにNULLを指定すると、ロケールの設定から言語 を決定することを意味します。

ロケールの設定から「現在の言語」を決定する場合、「現在の言語」の 決定処理は「現在の言語」値の参照が必要な都度　(つまり、エンコード やデコードを行う度に) 行われます。 これは、ロケールの設定を変えると、「現在の言語」も自動的に変化する ことを意味します。

本関数は、正常に処理が完了すれば`idn_success`を返し、 何かエラーが発生すれば理由を示すエラーコードを返します。

### `idn_setlocalcheckfile()`

[書式]

> `#include <idn/api.h>`
> `idn_result_t idn_setlocalcheckfile(const char *file);`

エンコード処理、デコード処理には、ローカルチェックというアクション (`IDN_LCOALCHECK`) があります。 IDNの各レジストリは、ドメイン名の登録規定として「利用可能なコード ポイント」の集合をそれぞれ独自に定めています。 ローカルチェックを実行することで、レジストリが定めた「利用可能な コードポイント」の範囲内でドメイン名が表現されているかどうかをチェック することができます。

`idn_setlocalcheckfile()`関数は、「利用可能なコードポイント」 の一覧が書かれたセットファイルfileを読み込みます。 読み込んだ後、エンコード処理ないしデコード処理の際にローカルチェック を実行するように指示すると、本関数で読み込んだ内容に基づいてドメイン名 に使用されているコードポイントの検査を行います。 ファイルに載っていないコードポイントが使用されていると、エンコード/ デコード処理関数からはエラーコード`idn_localcheck_error` が返ります。

セットァイルの記述方法については、 「セットファイル」 を参照して下さい。

本関数は、正常に処理が完了すれば`idn_success`を返し、 何かエラーが発生すれば理由を示すエラーコードを返します。

## resモジュール

resモジュールは「低レベルAPI」とも呼ばれ、国際化ドメイン名の変換処理を 細かいレベルで制御できるようになっています。 次の関数で構成されています。

関数 | 説明
--- | ---
`idn_res_encodename()` | 国際化ドメイン名のエンコード
`idn_res_decodename()` | 国際化ドメイン名のデコード
`idn_res_decodename2()`
`idn_res_comparenames()` | ドメイン名同士の比較
`idn_res_comparenames2()`
`idn_res_checkname()` | ドメイン名の検証

低レベルAPIでは必ず、変換コンテキストを使用します。 低レベルAPIの各関数の第一引数は、必ず変換コンテキストになります。 変換コンテキストの生成や操作は、「resconfモジュール」 で行います。 変換コンテキストに各種の状態設定を行うことで、エンコードやデコード の内部処理が変化します。

低レベルAPIの各関数には、対応する高レベルAPI関数が必ずあります。 低レベルAPIは関数名が "`idn_res_`" で始まり、 高レベルAPIは "`idn_`" だけで始まりますが、その後ろ の部分の名称がまったく同じ関数が両モジュールにそれぞれ存在します。 また、両者の引数列の違いは、変換コンテキストを取るか取らないか の差だけです。

低レベルAPIを用いたプログラムの例 (抜粋) を、以下に記します。

>     idn_result_t r;
>     idn_resconf_t ctx;

>     /* コンテキスト生成 */
>     r = idn_resconf_create(&ctx);
>     if (r != idn_success)
>         my_error("idn_resconf_create() failed\n");

>     /* 設定ファイル読み込み */
>     r = idn_resconf_loadfile(ctx, "/etc/idn2.conf");
>     if (r != idn_success)
>         my_error("idn_resconf_loadfile() failed\n");

>     /* エンコード */
>     r = idn_res_encodename(ctx, IDN_ENCODE_LOOKUP, from, to, tolen);
>     if (r != idn_success)
>         my_error("idn_res_encodename() failed\n");

>     /* 後始末 */
>     idn_resconf_destroy(ctx);

以下、resモジュールのそれぞれの関数について説明します。

### `idn_res_encodename()`

[書式]

> `#include <idn/res.h>`
> `idn_result_t idn_res_encodename(idn_resconf_t ctx, idn_action_t actions, const char *from, char *to, size_t tolen);`

高レベルAPIのエンコード関数 `idn_encodename()` の低レベルAPI版です。 変換コンテキストctxを引数に取る以外は、高レベルAPIと同じ です。

### `idn_res_decodename()`

[書式]

> `#include <idn/res.h>`
> `idn_result_t idn_res_decodename(idn_resconf_t ctx, idn_action_t actions, const char *from, char *to, size_t tolen);`

高レベルAPIのデコード関数 `idn_decodename()` の低レベルAPI版です。 変換コンテキストctxを引数に取る以外は、高レベルAPIと同じ です。

### `idn_res_decodename2()`

[書式]

> `#include <idn/res.h>`
> `idn_result_t idn_res_decodename2(idn_resconf_t ctx, idn_action_t actions, const char *from, char *to, size_t tolen, const char *auxencoding);`

高レベルAPIのデコード関数 `idn_decodename2()` の低レベルAPI版です。 変換コンテキストctxを引数に取る以外は、高レベルAPIと同じ です。

### `idn_res_comparenames()`

[書式]

> `#include <idn/res.h>`
> `idn_result_t idn_res_comparenames(idn_resconf_t ctx, idn_action_t actions, const char *name1, const char *name2);`

高レベルAPIの一致比較関数 `idn_comparenames()` の低レベルAPI版です。 変換コンテキストctxを引数に取る以外は、高レベルAPIと同じ です。

### `idn_res_comparenames2()`

[書式]

> `#include <idn/res.h>`
> `idn_result_t idn_res_comparenames2(idn_resconf_t ctx, idn_action_t actions1, const char *name1, actions2, const char *name2);`

高レベルAPIの一致比較関数 `idn_comparenames2()` の低レベルAPI版です。 変換コンテキストctxを引数に取る以外は、高レベルAPIと同じ です。

### `idn_res_checkname()`

[書式]

> `#include <idn/res.h>`
> `idn_result_t idn_res_checkname(idn_resconf_t ctx, idn_action_t actions, const char *name);`

高レベルAPIのチェック関数 `idn_checkname()` の低レベルAPI版です。 変換コンテキストctxを引数に取る以外は、高レベルAPIと同じ です。

## resconfモジュール

resconfモジュールはresモジュール (低レベルAPI) で 使われる「変換コンテキスト」の生成と制御を行います。

resconfモジュールは、次の関数から構成されます。

関数 | 説明
--- | ---
`idn_resconf_initialize()` | resconfモジュールの初期化
`idn_resconf_create()` | 変換コンテキストの生成
`idn_resconf_destroy()` | 変換コンテキストの開放
`idn_resconf_setdefaults()` | 変換コンテキストの再初期化
`idn_resconf_loadfile()` | 設定ファイルの読み込み
`idn_resconf_loadstrings()` | 設定文字列の読み込み
`idn_resconf_getlocalencoding()` | ローカルエンコーディングの取得
`idn_resconf_setlocalencoding()` | ローカルエンコーディングの設定
`idn_resconf_getlanguage()` | 「現在の言語」の取得
`idn_resconf_setlanguage()` | 「現在の言語」の設定
`idn_resconf_setlocalcheckfile()` | ローカルチェック用セットファイルの設定

変換コンテキストは、読み込んだの設定ファイルの内容や ローカルエンコーディング、「現在の言語」設定、読み込んだ ローカルチェック用セットファイルの内容などを内部で保持しています。 変換コンテキストは、resモジュールのエンコード関数やデコード関数に 引数として渡しますが、コンテキストの保持する設定に応じて、エンコード やデコードの処理が変化します。

以下、それぞれの関数について説明します。

### `idn_resconf_initialize()`

[書式]

> `#include <idn/resconf.h>`
> `idn_result_t idn_resconf_initialize(void);`

resconfモジュールを初期化します。 具体的には、「エンコーディング別名定義ファイル」の読み込みと、 「言語別名定義ファイル」の読み込みを行います。 この関数は、resconfモジュールの他の関数を使用する前に呼び出し、初期化 を完了させなければなりません。 この関数を呼んでモジュールの初期化を完了させずに他の関数を呼び出した ときの動作は、未定義です。

本関数は、正常に処理が完了すれば`idn_success`を返し、 何かエラーが発生すれば理由を示すエラーコードを返します。 `idn_success`が返らなかった場合、モジュールの初期化は 完了していません。 初期化が既に済んでいる状態で、再度この関数を呼び出すことはできますが、 関数内では何も行いません。(別名定義ファイルの読み込み直しは行いません。)

### `idn_resconf_create()`

[書式]

> `#include <idn/resconf.h>`
> `idn_result_t idn_resconf_create(idn_resconf_t *ctxp);`

変換コンテキストを1つ生成します。 生成直後のコンテキストは、標準の状態を有しています。 これは、空の設定ファイルを読み込み、ローカルエンコーディングを強制 指定せず、セットファイルも指定していない状態と同等です。

正常に処理が完了すると、変換コンテキストのために確保したメモリ領域 へのポインタを`*ctxp`にセットし、 `idn_success`を返します。 生成に失敗した場合、原因を表すエラーコードを返します。 このとき、`*ctxp`の指す値は未定義であり、参照 すべきではありません。

### `idn_resconf_destroy()`

[書式]

> `#include <idn/resconf.h>`
> `void idn_resconf_destroy(idn_resconf_t ctx);`

`idn_resconf_create()`で生成した変換コンテキストを、消去します。 変換コンテキストのために確保されたメモリが、開放されます。

ctxには、`idn_resconf_create()`の呼び出しによって `*ctxp`にセットされた値を渡します。 消去した後でctxにアクセスしたときの動作は、未定義です。 すでに消去が済んでいるctxに対して、本関数をもう一度呼んだ ときの動作は未定義です。

### `idn_resconf_setdefaults()`

[書式]

> `#include <idn/resconf.h>`
> `idn_result_t idn_resconf_setdefaults(idn_resconf_t ctx);`

変換コンテキストの内部設定を、コンテキスト生成直後の時点に戻します。

正常に処理が完了すれば`idn_success`を返し、何かエラーが 発生すれば理由を示すエラーコードを返します。 `idn_success`が返らなかった場合、変換コンテキストの内部 状態は、本関数を呼び出す直前と同じ状態を保ちます。

### `idn_resconf_loadfile()`

[書式]

> `#include <idn/resconf.h>`
> `idn_resconf_loadfile(idn_resconf_t ctx, const char *file);`

設定ファイルを読み込み、設定内容を変換コンテキストctx内部 で保持するようにします。 以降、この変換コンテキストを用いて (resモジュールを用いた) エンコード やデコードを行うと、読み込んだ設定ファイルの内容に応じた処理が行われ ます。 fileには、設定ファイルのパスを指定します。 NULLを指定すると、標準のパスにある設定ファイル (「設定ファイルについて」 参照) を読み込みます。

正常に処理が完了すれば`idn_success`を返し、何かエラーが 発生すれば理由を示すエラーコードを返します。 `idn_success`が返らなかった場合、変換コンテキストの内部 状態は、未定義です。

### `idn_resconf_loadstrings()`

[書式]

> `#include <idn/resconf.h>`
> `idn_result_t idn_resconf_loadstrings(idn_resconf_t ctx, char *strings[]);`

設定内容を記した文字列配列stringsを、変換コンテキスト ctxに反映します。 以降、この変換コンテキストを用いて (resモジュールを用いた) エンコード やデコードを行うと、読み込んだ設定ファイルの内容に応じた処理が行われ ます。

stringsは、必ず配列の末尾を表す要素として、NULLを配置します。 たとえば、設定ファイルに

>     language ja
>     map lowercase width nfkc delimitermap
>     delimiters 3002

と書いてそれを `idn_resconf_loadfile()` 関数で読み込むことは、次のように本関数を呼び出すことと等価です。

>     static char *conf[] = {
>         "language ja",
>         "map lowercase width nfkc delimitermap",
>         "delimiters 3002",
>         NULL
>     };
>     idn_resconf_loadstrings(ctx, conf);

正常に処理が完了すれば`idn_success`を返し、何かエラーが 発生すれば理由を示すエラーコードを返します。 `idn_success`が返らなかった場合、変換コンテキストの内部 状態は、未定義です。

### `idn_resconf_getlocalencoding()`

[書式]

> `#include <idn/resconf.h>`
> `const char *idn_resconf_getlocalencoding()`

変換コンテキストctxにセットされたローカルエンコーディング 名称を返します。 後述する、`idn_resconf_setlocalencoding()`関数で ローカルエンコーディングを強制的にセットしていれば、そのときセットした 名称が返ります。 (ただし、セットされたのがエンコーディングの別名だった場合は、正式名に 変換されたものが返ります。) 強制的にセットしていない場合、環境変数`IDN_LOCAL_CODESET` をセットしていればその値が返ります。 (ここでも同様に、環境変数の値がエンコーディングの別名だった場合は、 正式名に変換されたものが返ります。) 環境変数をセットしていなければ、ロケール情報に応じて決定された ローカルエンコーディング名称が返ります。

この関数が返す文字列は、変換コンテキストの内部に保持されているメモリ 領域のポインタを返します。 resconfモジュールの他の関数や、resモジュールの関数に変換コンテキスト を引数に与える等すると、内容が変化してしまいますので、注意して下さい。

### `idn_resconf_setlocalencoding()`

[書式]

> `#include <idn/resconf.h>`
> `idn_result_t idn_resconf_setlocalencoding(idn_resconf_t ctx);`

変換コンテキストのローカルエンコーディングをnameにセット します。 本関数は、高レベルAPIの `idn_setlocalencoding()` に対応します。 `idn_setlocalencoding()`は高レベルAPIモジュールの ローカルエンコーディングを設定し、本関数は変換コンテキスト1個の ローカルエンコーディングを設定するという点が異なりますが、 それ以外はすべて同じです。

### `idn_resconf_getlanguage()`

[書式]

> `#include <idn/resconf.h>`
> `const char *idn_resconf_getlanguage(idn_resconf_t ctx);`

変換コンテキストctxにセットされた「現在の言語」名称を 返します。 後述する、`idn_resconf_setlanguage()`関数や読み込んだ 設定ファイル、設定文字列配列で「現在の言語」をセットしていれば、 そのときセットした名称が返ります。 (ただし、セットされたのが言語の別名だった場合は、正式名に変換された ものが返ります。) 明示的に「現在の言語」をセットしていなければ、ロケール情報に応じて 決定された名称が返ります。

この関数が返す文字列は、変換コンテキストの内部に保持されているメモリ 領域のポインタを返します。 resconfモジュールの他の関数や、resモジュールの関数に変換コンテキスト を引数に与える等すると、内容が変化してしまいますので、注意して下さい。

### `idn_resconf_setlanguage()`

[書式]

> `#include <idn/resconf.h>`
> `idn_result_t idn_resconf_setlanguage(idn_resconf_t ctx);`

変換コンテキストの「現在の言語」をnameにセットします。 本関数は、高レベルAPIの `idn_setlanguage()` に対応します。

`idn_setlanguage()`は高レベルAPIモジュールの「現在の言語」 を設定し、本関数は変換コンテキスト1個の「現在の言語」を設定すると いう点が異なりますが、それ以外はすべて同じです。

### `idn_resconf_setlocalcheckfile()`

[書式]

> `#include <idn/resconf.h>`
> `idn_result_t idn_resconf_setlocalcheckfile(idn_resconf_t ctx, const char *file);`

ローカルチェック用のセットファイルfileを読み込み、 内容を変換コンテキストに保持します。 高レベルAPIの `idn_setlocalcheckfile()` に対応します。

`idn_setlocalcheckfile()`は高レベルAPIモジュールの ローカルチェック用セットファイルを設定し、本関数は変換コンテキスト 1個のセットファイルを設定するという点が異なりますが、それ以外は すべて同じです。

## resultモジュール

resultモジュールではエラーコードの定義と、エラーコードに関連する関数 の宣言を行っています。 idnkitライブラリのエラーコードは列挙型`idn_result_t`で表現 され、以下のエラーコード値が定義されています。(ただし、現在使われて いないエラーコードや、ライブラリ内限定で使用されるためアプリケーション に返されることのないエラーコード等は、省略しています。)

エラーコード | 説明
--- | ---
`idn_success` | エラーなし。成功。
`idn_invalid_encoding` | 入力データのエンコーディングが正しくない。
`idn_invalid_syntax` | 読み込んだファイルの構文が正しくない。
`idn_invalid_name` | 知らないエンコーディング名や言語名、マッピング工程が指定された。
`idn_invalid_action` | 指定されたアクション値が不正。 各アクションには、それぞれ固有のint値が割り当てられている。 このエラーコードは、アクションとして指定されたint値がおかしいことを意味する。
`idn_invalid_codepoint` | 指定されたコードポイント値が不正 (U+10FFFFより大きい、サロゲート・ペア領域U+D8000～D+DFFFである等)。
`idn_buffer_overflow` | 結果を格納するには、指定された領域では小さすぎる。
`idn_nomemory` | 処理に必要なメモリが足りない。
`idn_nofile` | ファイルが読み込めない (ファイルが存在しない、ファイルは存在するがアクセス権がない等)。
`idn_nomapping` | 変換対象の文字列は、変換先のエンコーディングでは表せないコードポイントを含んでいる。
`idn_prohcheck_error` | 禁止コードポイントチェックに引っかかった。
`idn_unascheck_error` | 未割り当てコードポイントチェックに引っかかった。
`idn_nfccheck_error` | NFC適用済みチェックに引っかかった。
`idn_prefcheck_error` | ACE接頭辞チェックに引っかかった。
`idn_hyphcheck_error` | ハイフンチェックに引っかかった。
`idn_combcheck_error` | 合成文字チェックに引っかかった。
`idn_ctxjcheck_error` | 「連結制御文脈依存文字 (CONTEXTJ)」チェックに引っかかった。
`idn_ctxocheck_error` | ドメイン名登録プロトコル用ないし参照プロトコル用の 「その他文脈依存文字 (CONTEXTO)」チェックに引っかかった。
`idn_bidicheck_error` | BIDI (bidirectional display; 双方向表示) チェックに引っかかった。
`idn_localcheck_error` | ローカルチェックに引っかかった。
`idn_lencheck_error` | ラベル長チェックに引っかかった。
`idn_rtcheck_error` | ラウンドトリップチェックに引っかかった。
`idn_tr46check_error` | UTS (Unicode Technical Standard) #46チェックに引っかかった。
`idn_neq` | 2つのドメイン名は一致しなかった。 一致比較関数から返されるエラーコード。
`idn_failure` | その他のエラー。他のいずれのエラーコードにも当てはまらないエラーを表す。

resultモジュールが提供する関数は、次の通りです。

関数 | 説明
--- | ---
`idn_result_tostring()` | エラーコードを簡潔に表した文字列の取得

以下、関数について説明します。

### `idn_result_tostring()`

[書式]

> `#include <idn/result.h>`
> `const char *idn_result_tostring(idn_result_t result);`

エラーコードresultを、ごく簡単な英語で表現した文字列を返します。 未知のエラーコードに対しては、`"unknown result code"` という文字列を返します。 本関数が返す文字列は、静的な領域へのポインタです。 同じエラーコードに対しては、常に同じポインタ値を返します。

以下は、エラーコードと返される文字列の対応表です。

エラーコード | 関数の返す文字列
--- | ---
`idn_success` | `"success"`
`idn_invalid_encoding` | `"invalid encoding found"`
`idn_invalid_syntax` | `"syntax error"`
`idn_invalid_name` | `"invalid name"`
`idn_invalid_action` | `"invalid action"`
`idn_invalid_codepoint` | `"invalid code point"`
`idn_buffer_overflow` | `"buffer overflow"`
`idn_nomemory` | `"out of memory"`
`idn_nofile` | `"no such file"`
`idn_nomapping` | `"no mapping to output codeset"`
`idn_prohcheck_error` | `"prohibited check failed"`
`idn_unascheck_error` | `"unassigned check failed"`
`idn_nfccheck_error` | `"NFC validation check failed"`
`idn_prefcheck_error` | `"ACE prefix check failed"`
`idn_hyphcheck_error` | `"hyphen check failed"`
`idn_combcheck_error` | `"combining class check failed"`
`idn_ctxjcheck_error` | `"CONTEXTJ check failed"`
`idn_ctxocheck_error` | `"CONTEXTO check failed"`
`idn_bidicheck_error` | `"Bidi check failed"`
`idn_localcheck_error` | `"local check failed"`
`idn_lencheck_error` | `"label length check failed"`
`idn_rtcheck_error` | `"round trip check failed"`
`idn_tr46check_error` | `"TR #46 check failed"`
`idn_neq` | `"not equivalent domain names"`
`idn_failure` | `"generic failure"`

## versionモジュール

versionモジュールは、バージョン番号を返す関数群で構成されます。

関数 | 説明
--- | ---
`idn_version_unicode()` | Unicodeバージョン番号の取得
`idn_version_idnatable()` | IDNA導出プロパティ (IDNA Derived Properties) のバージョン番号の取得
`idn_version_libidn()` | idnkitライブラリのバージョン番号の取得
`idn_version_getstring()` | Unicode、IDNA導出プロパティ、idnkitライブラリの各バージョン 番号をすべて含んだ文字列の取得

### `idn_version_unicode()`

[書式]

> `#include <idn/version.h>`
> `const char *idn_version_unicode(void);`

indkitライブラリは、Unicode文字データベース (Unicode Character Database) を基にした、各種のテーブルを内部で保持しています。 そのテーブルがUnicodeのどのバージョンから生成されたものなのかを、本関数 は文字列形式で返します。 たとえば、Unicode 6.0.0であれば、"6.0.0" という文字列を返します。 本関数が返す関数は、静的な領域へのポインタです。 idnkitライブラリのコンパイル時にこのバージョン番号は確定し、実行時に 変化することはありません。

### `idn_version_idnatable()`

[書式]

> `#include <idn/version.h>`
> `const char *idn_version_idnatable(void);`

indkitライブラリは、 IDNA導出プロパティ (IDNA Derived Properties) のデータをテーブル化して、内部で保持しています。 そのテーブルのバージョン番号を文字列形式で返します。 文字列の形式は、

> 参照ドキュメント `(最終更新日)`

となっています。 たとえば、参照ドキュメントがRFC6452、最終更新日が2011-11-14であれば、 本関数の返す文字列は、

> `rfc6452 (2011-11-14)`

となります。 本関数が返す関数は、静的な領域へのポインタです。 idnkitライブラリのコンパイル時にこのバージョン番号は確定し、実行時に 変化することはありません。

### `idn_version_libidn()`

[書式]

> `#include <idn/version.h>`
> `const char *idn_version_unicode(void);`

idnkitライブラリ自身のバージョン番号を返します。 このバージョン番号はidnkitの配布ソースコードのバージョンと同一で、 たとえばidnkitのバージョンが "2.2" であれば、本関数が返す文字列も "2.2" となります。 同じ配布ソースコードからコンパイルしたidnkitライブラリとidnkitlite ライブラリは、同一のバージョン番号を返します。

本関数が返す関数は、静的な領域へのポインタです。 idnkitライブラリのコンパイル時にこのバージョン番号は確定し、実行時に 変化することはありません。

### `idn_version_getstring()`

[書式]

> `#include <idn/version.h>`
> `const char *idn_version_unicode(void);`

Unicode、IDNA導出プロパティテーブル、idnkitライブラリの バージョン番号を一通り表した文字列を返します。 文字列の形式は、次のようになります。

> `Unicode version: バージョン1; IDNA Table version: バージョン2; libidn version: バージョン3`

ここで、バージョン1は`idn_version_unicode()`が返す文字列、バージョン2は`idn_version_idna()`が返す文字列、 バージョン3は`idn_version_libidn()`が返す文字列と なります。

本関数が返す関数は、静的な領域へのポインタです。 idnkitライブラリのコンパイル時にこのバージョン番号は確定し、実行時に 変化することはありません。