/* ktable.c * テーブルの例 * TABLE: apr_table_make / apr_table_set / apr_table_setn / * apr_table_get / apr_table_elts / apr_table_add / apr_table_unset / * apr_is_empty_table / apr_table_clear */ #include "apr_general.h" #include "apr_file_io.h" #include "apr_tables.h" #include "apr_strings.h" #include "mystab.h" /* * apr_table_do 用コールバック関数 * ctxにはコールバック関数へのコンテクストデータ。 * この例ではファイルポインタ渡しに使用。 */ int table_cb (void *ctx, const char *key, const char *value) { apr_file_t *out = (apr_file_t*)ctx; apr_file_printf(out, "(%s)=(%s)\n", key, value); return TRUE;/* TRUE:continue iteration. FALSE:stop iteration */ } /* * apr_table_do 用コールバック関数 * この例ではキー・値をコンカテネートしてみる。 */ typedef struct mydata { apr_pool_t *pool; char *str; /* あらかじめ、"" で初期化すること*/ } mydata; int table_cb2 (void *ctx, const char *key, const char *value) { mydata *md = (mydata*)ctx; md->str = apr_psprintf(md->pool, "%s{%s}={%s}\n", md->str, key, value); return TRUE;/* TRUE:continue iteration. FALSE:stop iteration */ } int apr_my_main (int ac, char **av, apr_file_t * astdin, apr_file_t * astdout, apr_file_t * astderr, apr_pool_t * pool) { char *keys[] = { "key0" , "key1" , "key2" , "key3" }; char *values[] = { "value0" , "value1" , "value2" , "value3" }; /* apr_table_make / apr_table_set / apr_table_setn / apr_table_get / apr_table_elts / apr_table_add * apr_table_unset / apr_is_empty_table apr_table_clear * INCLUDE: apr_tables.h * LIBS: libapr-1.lib */ { apr_table_t * tab; int i; /* テーブルの生成 */ tab = apr_table_make(pool, 10); /* 第二引数はテーブルのサイズを指定するが、動的に変化する。*/ /* テーブルは空?(1 になるはず) */ apr_file_printf(astdout, "apr_is_empty_table=[%d]\n", apr_is_empty_table(tab)); /* キー・値の追加 */ for (i=0; i<4; i++) { /* apr_table_set はキーとバリューの値を「複製」する。apr_table_setn とすると「複製」されない*/ apr_table_set(tab, keys[i], values[i]); } apr_table_set(tab, "FOO", "VALUE0"); apr_table_set(tab, "BAR", "VALUE1"); apr_table_set(tab, "QUUX", "VALUE2"); /* テーブルは空?(0 になるはず) */ apr_file_printf(astdout, "apr_is_empty_table=[%d]\n", apr_is_empty_table(tab)); /* キーに対応する値の表示 */ apr_file_printf(astdout, "---------------------------------------------\n"); apr_file_printf(astdout, "[%s]=>[%s]\n", "QUUX", apr_table_get(tab, "QUUX")); for (i=0; i<4; i++) { apr_file_printf(astdout, "[%s]=>[%s]\n", keys[i], apr_table_get(tab, keys[i])); } /* 存在しないキーに対応する値の表示(NULL になる)*/ apr_file_printf(astdout, "[%s]=>[%s]\n", "UNKNOWN", apr_table_get(tab, "UNKNOWN")); /* 格納されたキー・値の個数の表示 */ if (1) { const apr_array_header_t *tarr = apr_table_elts(tab); apr_file_printf(astdout, "---------------------------------------------\n"); apr_file_printf(astdout, "size=[%d]\n", tarr->nelts); } /* 格納されたキー・値の一覧表示(その1) */ if (1) { const apr_table_entry_t *telts; const apr_array_header_t *tarr = apr_table_elts(tab); telts = (const apr_table_entry_t*)tarr->elts; apr_file_printf(astdout, "---------------------------------------------\n"); for (i = 0; i < tarr->nelts; i++) { apr_file_printf(astdout, "%d: [%s]=[%s]\n", i, telts[i].key, telts[i].val); } } /* 格納されたキー・値の一覧表示(その2) */ if (1) { apr_file_printf(astdout, "---------------------------------------------\n"); apr_table_do(table_cb, astdout, tab, NULL); } /* 格納されたキー・値の一覧表示(その2・コールバック関数もう一例) */ if (1) { mydata md; apr_file_printf(astdout, "#---------------------------------------------\n"); md.pool = pool; md.str = ""; apr_table_do(table_cb2, &md, tab, NULL); apr_file_printf(astdout, "%s", md.str); } /* 格納されたキー・値の一覧表示(その2・コールバック関数もう一例+フィルタ) */ if (1) { mydata md; apr_file_printf(astdout, "#---------------------------------------------\n"); md.pool = pool; md.str = ""; apr_table_do(table_cb2, &md, tab, "FOO", "BAR", "QUUX", NULL); /* キーが FOO, BAR, QUUX となるもののみ処理される*/ apr_file_printf(astdout, "%s", md.str); } /* 値の変更 */ apr_table_set(tab, "QUUX", "ANOTHER VALUE"); apr_table_set(tab, "key3", "ANOTHER VALUE2"); /* 格納されたキー・値の一覧表示 */ if (1) { apr_file_printf(astdout, "---------------------------------------------\n"); apr_table_do(table_cb, astdout, tab, NULL); } /* すでに存在するキーの値の追加(多重値) */ /* apr_table_add はキーとバリューの値を「複製」する。apr_table_addn とすると「複製」されない*/ apr_table_add(tab, "FOO", "ANOTHER VALUE3"); apr_table_add(tab, "key2", "ANOTHER VALUE4"); /* 格納されたキー・値の一覧表示 */ if (1) { apr_file_printf(astdout, "---------------------------------------------\n"); apr_table_do(table_cb, astdout, tab, NULL); } /* 多重値になっているキーの値を apr_table_get すると(最初に登録したものになる) */ if (1) { apr_file_printf(astdout, "---------------------------------------------\n"); apr_file_printf(astdout, "[%s]=>[%s]\n", "FOO", apr_table_get(tab, "FOO")); apr_file_printf(astdout, "[%s]=>[%s]\n", "key2", apr_table_get(tab, "key2")); } /* キー・値の削除 */ apr_table_unset(tab, "BAR"); apr_table_unset(tab, "key0"); /* 格納されたキー・値の一覧表示 */ if (1) { apr_file_printf(astdout, "---------------------------------------------\n"); apr_table_do(table_cb, astdout, tab, NULL); } /* 多重値になっているキー・値の削除 */ apr_table_unset(tab, "FOO"); apr_table_unset(tab, "key2"); /* 格納されたキー・値の一覧表示 */ if (1) { apr_file_printf(astdout, "---------------------------------------------\n"); apr_table_do(table_cb, astdout, tab, NULL); } /* テーブルのクリア */ apr_table_clear(tab); /* テーブルは空?(1 になるはず) */ apr_file_printf(astdout, "apr_is_empty_table=[%d]\n", apr_is_empty_table(tab)); /* 格納されたキー・値の一覧表示(空なのでコールバック関数は呼ばれない) */ if (1) { apr_file_printf(astdout, "---------------------------------------------\n"); apr_table_do(table_cb, astdout, tab, NULL); } /* より汎用的には、こんな使い方が安全なのでは? */ if (tab && ! apr_is_empty_table(tab)) { apr_table_do(table_cb, astdout, tab, NULL); } } apr_file_printf(astdout, "\ndone.\n"); return 0; /* 正常終了 */ }