APR の配列!

もう一度 APR のハッシュテーブルを紹介!の前に、配列 (apr_array_t) を紹介します。

#include <stdio.h>
#include <assert.h>

#include <apr_pools.h>
#include <apr_strings.h>
#include <apr_tables.h>

/*
 * コンパイルのしかた:
 *   gcc -Wall -pedantic `pkg-config --cflags --libs apr-1` hoge.c
 *
 * API リファレンス:
 *   https://apr.apache.org/docs/apr/1.5/group__apr__tables.html
 */

int main(int argc, char *argv[])
{
  apr_pool_t *mp;
  apr_status_t rv;

  apr_array_header_t *ary;
  void **item;
  int i;

  apr_array_header_t *another_ary;
  apr_array_header_t *new_ary;

  /* APR の初期化 */
  rv = apr_initialize();
  assert(rv == APR_SUCCESS);
  /* メモリプールの作成 */
  apr_pool_create(&mp, NULL);

  /* 配列の作成
   * 第一引数はメモリプール、第二引数は配列の要素数の初期値、
   * 第三引数は各要素の大きさ
   * 配列の長さは必要に応じて自動的に伸長する
   *
   * ここで void* 型の配列を作成しているので、ary->elts は void** になる
   */
  ary = apr_array_make(mp, 0, sizeof(void*));

  /* 要素の追加
   * 任意の場所に挿入する API はない
   */
  item = apr_array_push(ary);
  *item = "最初の要素";
  /* このように省略することもできる */
  *(void**)(apr_array_push(ary)) = "2番目の要素";
  /* 便利なマクロもある */
  APR_ARRAY_PUSH(ary, void*) = "3番目の要素";
  /* apr_pstrdup はメモリプール版の strdup.
   * free してはいけない
   */
  APR_ARRAY_PUSH(ary, void*) = apr_pstrdup(mp, "4番目の要素");

  /* 各要素の取得 */
  for (i = 0; i < ary->nelts; i++) {
    item = APR_ARRAY_IDX(ary, i, void*);
    /* APR_ARRAY_IDX マクロを使わない場合はこのようになる
     *   item = ((void**)(ary)->elts)[i];
     */
    printf("%d: %s\n", i, (char*)item);
  }

  /* 要素の取り出しと削除
   * 任意の場所の要素を削除する API はない
   * 要素が存在しない場合、NULL が返る
   *
   * 要素を free してはいけない (メモリプールが壊れる) ので、
   * apr_pstrdup や apr_palloc で作成した要素を削除したい時は、
   * 単に返り値を無視すればよい
   */
  (void)apr_array_pop(ary);

  /* 要素が文字列の場合、全要素を連結した文字列を作ることができる
   * (いわゆる join)
   * 返り値の文字列はメモリプール上に作成される
   */
  printf("\n----- 文字列の連結 (デリミタに '\\n' を指定) -----\n\n");
  printf("%s\n", apr_array_pstrcat(mp, ary, '\n'));

  another_ary = apr_array_make(mp, 0, sizeof(void*));
  APR_ARRAY_PUSH(another_ary, void*) = "5番目の要素";

  /* 2つの配列を連結して新しい配列を作る */
  new_ary = apr_array_append(mp, ary, another_ary);
  printf("\n----- 新しい配列 -----\n\n");
  for (i = 0; i < new_ary->nelts; i++) {
    item = APR_ARRAY_IDX(new_ary, i, void*);
    printf("%d: %s\n", i, (char*)item);
  }

  /* 既存の配列に別の配列をつなげる */
  apr_array_cat(another_ary, ary);
  printf("\n----- 配列の連結 -----\n\n");
  for (i = 0; i < another_ary->nelts; i++) {
    item = APR_ARRAY_IDX(another_ary, i, void*);
    printf("%d: %s\n", i, (char*)item);
  }

  /* 配列のコピー */
  new_ary = apr_array_copy(mp, another_ary);
  printf("\n----- 配列のコピー -----\n\n");
  for (i = 0; i < new_ary->nelts; i++) {
    item = APR_ARRAY_IDX(new_ary, i, void*);
    printf("%d: %s\n", i, (char*)item);
  }

  /* メモリプールの破壊 */
  apr_pool_destroy(mp);

  return 0;
}

実行結果:

0: 最初の要素
1: 2番目の要素
2: 3番目の要素
3: 4番目の要素

----- 文字列の連結 (デリミタに '\n' を指定) -----

最初の要素
2番目の要素
3番目の要素

----- 新しい配列 -----

0: 最初の要素
1: 2番目の要素
2: 3番目の要素
3: 5番目の要素

----- 配列の連結 -----

0: 5番目の要素
1: 最初の要素
2: 2番目の要素
3: 3番目の要素

----- 配列のコピー -----

0: 5番目の要素
1: 最初の要素
2: 2番目の要素
3: 3番目の要素

(コウヅ)

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中