[前へ] [次へ] [目次]

## サーバ上の書籍一覧

EBNET サーバから遠隔アクセスを行う際、サーバがそのクライアントに対して アクセスを許可している書籍や appendix データの一覧を取得することが できます。

このとき、EBNET サーバを指定する遠隔アクセス記述子には、特定の書籍や appendix データに対するアクセスとは異なり、書籍名は指定しません。 すなわち、一般形は次のようになります。

>     ebnet://ホスト:ポート/

末尾の `/' はなくても構いません。 `:` とそれに続くポート番号は省略可能で、その場合は 22010 番ポートを利用することを意味します。

ebinfo コマンドの --book-list オプション指定時の挙動は、EB ライブラリ のこの機能によって実装されています。 (ebinfo についての詳細は、 @pxref{Book list on EBNET server, , EBNET サーバの書籍一覧, ebinfo-ja, ebinfo-ja}。)

>     % ebinfo --book-list ebnet://localhost
>     名前             題名
>     encycl           ブラウンコンサイス百科事典
>     encycl.app       ブラウンコンサイス百科事典 (appendix)
>     crossword        クロスワードパズル辞典
>     travel           ワールドトラベルガイド

名前の末尾が `.app` になっているものは appendix データで、 その他は書籍本体です。 この例の書籍 `encycl` に対してアクセスするなら、 遠隔アクセス識別子は `ebnet://localhost/encycl` になります。

なお、クライアントに対してアクセスを許可していない書籍や appendix データ は、サーが側で一覧から除外されます。

### `EB_BookList` オブジェクト

EBNET サーバの提供する書籍および appendix データの一覧を取得するには、 まず `EB_BookList` 型のオブジェクトを用意する必要があります。

>     EB_BookList bl;

オブジェクトの領域は、`malloc()` で確保しても構いません。

>     EB_BookList *bl_pointer;

>     bl_pointer = (EB_BookList *) malloc(sizeof(EB_BookList));

`EB_Book` オブジェクトと同様に、`EB_BookList` オブジェクトも使う前に中身を初期化する必要があります。 これは、`eb_initialize_booklist()` という関数で行います。

>     eb_initialize_booklist(&bl);
>     eb_initialize_booklist(bl_pointer);

初期化が完了したら、特定のサーバとオブジェクトを結びつけます。 たとえば、`ebnet://localhost` で表されるサーバに対して、 オブジェクトを結びつけるには次のようにします。

>     if (eb_bind_booklist(&bl, "ebnet://localhost") != EB_SUCCESS) {
>         printf("eb_bind_booklist() failed\n");
>         return;
>     }

これはちょうど、`EB_Book` オブジェクトに対して `eb_bind()` を呼ぶのと同じです。

こうして、ようやく書籍一覧の情報を取り出すことができます。 これには `eb_booklist_book_count()`, `eb_booklist_book_name()`, `eb_booklist_book_title()` という 3 つの関数を使用します。 これらの関数はそれぞれ、クライアントがアクセス可能な書籍の数、各書籍 および appendix データの名称 (アクセス識別子として指定する名前)、各書籍 と appendix データの題名を得ることができます。

>     char *name, *title;
>     int count, i;

>     count = eb_booklist_book_count(&bl);
>     for (i = 0; i < count; i++) {
>         if (eb_booklist_book_name(&bl, i, &name) != EB_SUCCESS) {
>             printf("eb_booklist_book_name(%d) failed\n", i);
>             return;
>         }
>         if (eb_booklist_book_title(&bl, i, &title) != EB_SUCCESS) {
>             printf("eb_booklist_book_title(%d) failed\n", i);
>             return;
>         }
>         printf("name = %s, title = %s\n", name, title);
>     }

`EB_BookList` オブジェクトを使い終わったら、必ず後始末を 行います。

>     eb_finalize_booklist(&bl);
>     eb_finalize_booklist(bl_pointer);

オブジェクトの領域を `malloc()` で確保した場合は、 `eb_finalize_booklist()` を呼んだ後ならば、オブジェクトの領域 を安全に解放することができます。

>     free(bl_pointer);

### データ型の詳細

この節で説明しているデータ型を使うには、次のようにヘッダファイルを 読み込んで下さい。

>     #include <eb/booklist.h>

#### `EB_BookList` 型

`EB_BookList` 型は、EBNET サーバ上が使っている書籍および appendix の一覧を取得する際に用いるオクジェクトの型です。

`EB_BookList` オブジェクトを使用する際は、まずそのオブジェクト に対して `eb_initialize_booklist()` を呼んで初期化する必要が あります。

### 関数の詳細

この節で説明している関数を使うには、次のようにヘッダファイルを読み込んで 下さい。

>     #include <eb/booklist.h>

#### `void eb_initialize_booklist (EB_BookList *bl)`

関数 `eb_initialize_booklist()` は、bl の指す `EB_BookList` オブジェクトを初期化します。 `EB_BookList` オブジェクトに対して EB ライブラリの他の関数を 呼ぶ前に、必ずそのオブジェクトを初期化しなくてはなりません。 初期化していないオブジェクトに対して、EB ライブラリの他の関数を呼んだ 場合の動作は未定義です。 また、すでに初期化したオブジェクトに対して、 再度 `eb_initialize_booklist()` を呼んではいけません。 呼んだ場合の動作は未定義です。

#### `EB_Error_Code eb_bind_booklist (EB_BookList *bl, const char *path)`

関数 `eb_bind_booklist()` は、app の指す `EB_BookList` オブジェクトを、遠隔アクセス記述子 path で指定された EBNET サーバに結び付けます。

オブジェクトがすでにサーバに結び付いていた場合、そのサーバとの結び付き を解いてから、path にあるサーバに結び付けます。

成功すると、関数は `EB_SUCCESS` を返します。 失敗すると、オブジェクトをサーバとの結び付きを解かれた状態にして、原因 を示すエラーコードを返します。

path は、`EB_MAX_PATH_LENGTH` バイトに収まて いなくてはなりません。 これを超えると、`EB_ERR_TOO_LONG_FILE_NAME` を返します。 また、書籍名を指定していない遠隔アクセス記述子でなければなりません。 それ以外の形式だと、`EB_ERR_BAD_FILE_NAME` を返します。

使用している EB ライブラリのバイナリが、遠隔アクセスに非対応のもので ある場合、`EB_ERR_EBNET_UNSUPPORTED` が返ります。

#### `void eb_finalize_booklist (EB_BookList *bl)`

関数 `eb_finalize_booklist()` は、bl が指す `EB_BookList` オブジェクトの後始末を行います。

オブジェクトが割り当てて管理していたメモリはすべて解放され、 ファイルディスクリプタもすべて閉じられます。 オブジェクトが EBNET サーバと結び付いていた場合は、結び付きが解かれます。

後始末をしたオブジェクトに対して `eb_bind_booklist()` を呼ぶ ことで、オブジェクトを再利用することができます。

#### `int eb_booklist_book_count (EB_BookList *bl)`

関数 `eb_booklist_book_count()` は、EBNET サーバがこの クライアントに対してアクセスを許可している書籍および appendix データの数 を取得します。

オブジェクト bl の指す `EB_BookList` オブジェクトは、 あらかじめ EBNET サーバに結びついている必要があります。 結びついていない場合は、`EB_ERR_UNBOUND_BOOKLIST` を返します。

#### `EB_Error_Code eb_booklist_book_name (EB_BookList *bl, int i, char **name)`

#### `EB_Error_Code eb_booklist_book_title (EB_BookList *bl, int i, char **title)`

関数 `eb_booklist_book_name()` は、EBNET サーバの書籍や appendix データの名称を取得します。 ここで言う「名称」とは、遠隔アクセス識別子で指定する書籍名のことです。 つまり、`ebnet://localhost/dict` の `dict` の部分 を指します。 同様に、関数 `eb_booklist_book_title()` は、書籍や appendix の題名を取得します。

いずれの関数も、EBNET サーバ上の何番目の書籍もしくは appendix の情報を 取得するのかを、引数 i で指定します。 先頭は 1 番目ではなく 0 番目になります。

成功すると、関数は書籍の名称、題名へのポインタを *name, *title に書き込み、`EB_SUCCESS` を返します。 なお、このポインタ値は オブジェクト `bl` が保持している 文字列を指すようになっています。 `bl` に対して `eb_finalize_booklist()` を呼んで しまうと、この文字列も参照不可能になってしまいますので、注意して下さい。

オブジェクト bl の指す `EB_BookList` オブジェクト は、あらかじめ EBNET サーバに結びついている必要があります。 結びついていない場合は、`EB_ERR_UNBOUND_BOOKLIST` を返します。 また、i は 0 以上かつサーバが提供している書籍および appendix の総数未満でなければなりません。 これ以外の値のときは、`EB_ERR_NO_SUCH_BOOK` が返ります。

### サンプルプログラム

>     /*                                                            -*- C -*-
>      * Copyright (c) 2003-2006  Motoyuki Kasahara
>      *
>      * Redistribution and use in source and binary forms, with or without
>      * modification, are permitted provided that the following conditions
>      * are met:
>      * 1. Redistributions of source code must retain the above copyright
>      *    notice, this list of conditions and the following disclaimer.
>      * 2. Redistributions in binary form must reproduce the above copyright
>      *    notice, this list of conditions and the following disclaimer in the
>      *    documentation and/or other materials provided with the distribution.
>      * 3. Neither the name of the project nor the names of its contributors
>      *    may be used to endorse or promote products derived from this software
>      *    without specific prior written permission.
>      *
>      * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
>      * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
>      * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
>      * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
>      * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
>      * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
>      * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
>      * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
>      * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
>      * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>      * SUCH DAMAGE.
>      */

>     /*
>      * 使用方法:
>      *     booklist <remote-access-ideintifier>
>      * 例:
>      *     booklist ebnet://localhost
>      * 説明:
>      *     <remote-access-ideintifier> で指定した EBNET サーバに接続し
>      *     て、サーバの提供する書籍、appendix の一覧を表示します。
>      */
>     #include <stdio.h>
>     #include <stdlib.h>

>     #include <eb/eb.h>
>     #include <eb/error.h>
>     #include <eb/booklist.h>

>     int
>     main(int argc, char *argv[])
>     {
>         EB_Error_Code error_code;
>         EB_BookList bl;
>         int book_count;
>         char *name, *title;
>         int i;

>         /* コマンド行引数をチェック。*/
>         if (argc != 2) {
>             fprintf(stderr, "Usage: %s book-path remote-access-identifier\n",
>                 argv[0]);
>             exit(1);
>         }

>         /* EB ライブラリと `bl' を初期化。*/
>         eb_initialize_library();
>         eb_initialize_booklist(&bl);

>         /* EBNET サーバを `bl' に結び付ける。*/
>         error_code = eb_bind_booklist(&bl, argv[1]);
>         if (error_code != EB_SUCCESS) {
>             fprintf(stderr, "%s: failed to bind the EBNET server, %s: %s\n",
>                 argv[0], eb_error_message(error_code), argv[1]);
>             goto die;
>         }

>         /* サーバ上の書籍、appendix の個数を取得。*/
>         error_code = eb_booklist_book_count(&bl, &book_count);
>         if (error_code != EB_SUCCESS) {
>             fprintf(stderr, "%s: failed to get the number of books, %s\n",
>                 argv[0], eb_error_message(error_code));
>             goto die;
>         }

>         for (i = 0; i < book_count; i++) {
>             /* 書籍、appendix の名称を取得。*/
>             error_code = eb_booklist_book_name(&bl, i, &name);
>             if (error_code != EB_SUCCESS) {
>                 fprintf(stderr, "%s: failed to get book name #%d, %s\n",
>                     argv[0], i, eb_error_message(error_code));
>                 goto die;
>             }

>             /* 書籍、appendix の題名を取得。*/
>             error_code = eb_booklist_book_name(&bl, i, &title);
>             if (error_code != EB_SUCCESS) {
>                 fprintf(stderr, "%s: failed to get book title #%d, %s\n",
>                     argv[0], i, eb_error_message(error_code));
>                 goto die;
>             }

>             printf("%-20s  %s\n", name, title);
>         }

>         /* `bl' と EB ライブラリの利用を終了。*/
>         eb_finalize_booklist(&bl);
>         eb_finalize_library();
>         exit(0);

>         /* エラー発生で終了するときの処理。*/
>       die:
>         eb_finalize_booklist(&bl);
>         eb_finalize_library();
>         exit(1);
>     }

[前へ] [次へ] [目次]