2.12.1 独自のバッファ・タイプの定義

領域の割当てと解放、メッセージの送受信など、バッファを操作するコードを記述するのはアプリケーション・プログラマです。デフォルトのバッファ・タイプではアプリケーションのニーズを満たすことができない場合、ほかのバッファ・タイプを定義し、新しいルーチンを記述してバッファ・タイプ・スイッチに組み込むことができます。

ほかのバッファ・タイプを定義するには、次のステップに従います。

  1. 必要なスイッチ要素ルーチンのコードを記述します。
  2. tm_typeswに、新しいタイプとバッファ管理モジュールの名前を追加します。
  3. 新しい共有オブジェクトまたはDLLをビルドします。共有オブジェクトまたはDLLには、更新されたバッファ・タイプ・スイッチとそれに対応する関数が含まれていなければなりません。
  4. 新しい共有オブジェクトまたはDLLをインストールして、すべてのサーバー、クライアント、およびOracle Tuxedoシステムで提供される実行可能ファイルが実行時に動的にロードされるようにします。

静的ライブラリが使用されるアプリケーションで、カスタム・バッファ・タイプ・スイッチを使う場合は、カスタム・サーバーをビルドして、新しいタイプ・スイッチにリンクする必要があります。詳細は、buildwsh (1)、TMQUEUE (5)、TMQFORWARD (5)を参照してください。

このトピックの残りの項では、前述の手順にリストされたステップで、共有オブジェクトまたはDLL環境で新しいバッファ・タイプを定義します。最初に、Oracle Tuxedoシステム・ソフトウェアに提供されているバッファ・スイッチを参照してみます。次のリストは、システムに提供されているスイッチです。

デフォルトのバッファ・タイプ・スイッチのリスト

#include <stdio.h>
#include <tmtypes.h>
/* 
 * Initialization of the buffer type switch.
 */
struct tmtype_sw_t tm_typesw[] = {
{
      "CARRAY",       /* type */
      "*",            /* subtype */
      0               /* dfltsize */
      NULL,           /* initbuf */
      NULL,           /* reinitbuf */
      NULL,           /* uninitbuf */
      NULL,           /* presend */
      NULL,           /* postsend */
      NULL,           /* postrecv */
      NULL,           /* encdec */
      NULL,           /* route */
      NULL,           /* filter */
      NULL,           /* format */
      NULL,           /* presend2 */
      NULL            /* multibyte code-set encoding conversion */
},
{
      "STRING",       /* type */
      "*",            /* subtype */
      512,            /* dfltsize */
      NULL,           /* initbuf */
      NULL,           /* reinitbuf */
      NULL,           /* uninitbuf */
      _strpresend,    /* presend */
      NULL,           /* postsend */
      NULL,           /* postrecv */
      _strencdec,     /* encdec */
      NULL,           /* route */
      _sfilter,       /* filter */
      _sformat,       /* format */
      NULL,           /* presend2 */
      NULL            /* multibyte code-set encoding conversion */
},
{
      "FML",          /* type */
      "*",            /* subtype */
      1024,           /* dfltsize */
      _finit,         /* initbuf */
      _freinit,       /* reinitbuf */
      _funinit,       /* uninitbuf */
      _fpresend,      /* presend */
      _fpostsend,     /* postsend */
      _fpostrecv,     /* postrecv */
      _fencdec,       /* encdec */
      _froute,        /* route */
      _ffilter,       /* filter */
      _fformat,       /* format */ 
      NULL,           /* presend2 */
      NULL            /* multibyte code-set encoding conversion */
},
{
      "VIEW",        /* type */
      "*",           /* subtype */
      1024,          /* dfltsize */
      _vinit,        /* initbuf */
      _vreinit,      /* reinitbuf */
      NULL,          /* uninitbuf */
      _vpresend,     /* presend */
      NULL,          /* postsend */
      NULL,          /* postrecv */
      _vencdec,      /* encdec */
      _vroute,       /* route */
      _vfilter,      /* filter */
      _vformat,      /* format */
      NULL,          /* presend2 */
      NULL           /* multibyte code-set encoding conversion */
},
{
      /* XATMI - identical to CARRAY */ 
      "X_OCTET",     /* type */
      "*",           /* subtype */
      0              /* dfltsize */
},
{     /* XATMI - identical to VIEW */ 
      {'X','_','C','_','T','Y','P','E'},          /* type */
      "*",          /* subtype */
      1024,         /* dfltsize */
      _vinit,       /* initbuf */
      _vreinit,     /* reinitbuf */
      NULL,         /* uninitbuf */
      _vpresend,    /* presend */
      NULL,         /* postsend */
      NULL,         /* postrecv */
      _vencdec,     /* encdec */
      _vroute,      /* route */
      _vfilter,     /* filter */
      _vformat,     /* format */
      NULL,         /* presend2 */
      NULL          /* multibyte code-set encoding conversion */
},
{
      /* XATMI - identical to VIEW */ 
      {'X','_','C','O','M','M','O','N'},         /* type */
      "*",         /* subtype */
      1024,        /* dfltsize */
      _vinit,      /* initbuf */
      _vreinit,    /* reinitbuf */
      NULL,        /* uninitbuf */
      _vpresend,   /* presend */
      NULL,        /* postsend */
      NULL,        /* postrecv */
      _vencdec,    /* encdec */
      _vroute,     /* route */
      _vfilter,    /* filter */
      _vformat,    /* format */
      NULL,        /* presend2 */
      NULL         /* multibyte code-set encoding conversion */
},
{
      "FML32",       /* type */
      "*",           /* subtype */
      1024,          /* dfltsize */
      _finit32,      /* initbuf */
      _freinit32,    /* reinitbuf */      
      _funinit32,    /* uninitbuf */
      _fpresend32,   /* presend */
      _fpostsend32,  /* postsend */
      _fpostrecv32,  /* postrecv */
      _fencdec32,    /* encdec */
      _froute32,     /* route */
      _ffilter32,    /* filter */
      _fformat32,    /* format */
      _fpresend232,  /* presend2 */
      _fmbconv32     /* multibyte code-set encoding conversion */
},
{
      "VIEW32",      /* type */
      "*",           /* subtype */
      1024,          /* dfltsize */
      _vinit32,      /* initbuf */
      _vreinit32,    /* reinitbuf */
      NULL,          /* uninitbuf */
      _vpresend32,   /* presend */
      NULL,          /* postsend */
      NULL,          /* postrecv */
      _vencdec32,    /* encdec */
      _vroute32,     /* route */
      _vfilter32,    /* filter */
      _vformat32,    /* format */
      NULL,          /* presend2 */
      _vmbconv32,    /* multibyte code-set encoding conversion */
},
{
      "XML",         /* type */ 
      "*",           /* subtype */ 
      0,             /* dfltsize */ 
      NULL,          /* initbuf */ 
      NULL,          /* reinitbuf */ 
      NULL,          /* uninitbuf */ 
      NULL,          /* presend */ 
      NULL,          /* postsend */ 
      NULL,          /* postrecv */ 
      NULL,          /* encdec */ 
      _xroute,       /* route */ 
      NULL,          /* filter */ 
      NULL,          /* format */
      NULL,          /* presend2 */
      NULL           /* multibyte code-set encoding conversion */
},
{
      "MBSTRING",    /* type */
      "*",           /* subtype */
      0,             /* dfltsize */
      _mbsinit,      /* initbuf */
      NULL,          /* reinitbuf */
      NULL,          /* uninitbuf */
      _mbspresend,   /* presend */
      NULL,          /* postsend */
      NULL,          /* postrecv */
      NULL,          /* encdec */
      NULL,          /* route */
      NULL,          /* filter */
      NULL,          /* format */      
      NULL,          /* presend2 */
      _mbsconv       /* multibyte code-set encoding conversion */
},
{
       "RECORD",     /* type */
       "*",          /* subtype */
       1024,         /* dfltsize */
       _rinit,       /* initbuf */
       _rreinit,     /* reinitbuf */
       _runinit,     /* uninitbuf */
       _rpresend,    /* presend */
       NULL,         /* postsend */
       NULL,         /* postrecv */
       _rencdec,     /* encdec */
       NULL,         /* route */
       NULL,         /* filter */
       NULL,         /* format */
       NULL          /* presend2 */
},
{
""
} 
};
struct tmtype_sw_t _TM_FAR *
_TMDLLENTRY
_tmtypeswaddr(void)
{
   return(tm_typesw);
}

この例をよく理解できるように、次のリストに示すバッファ・タイプ構造体の宣言を参照してください。

バッファ・タイプ構造体のリスト

/*
 * The following definitions are in $TUXDIR/include/tmtypes.h
 */
#define TMTYPELEN ED_TYPELEN 
#define TMSTYPELEN ED_STYPELEN
struct tmtype_sw_t {
    char type[TMTYPELEN];       /* type of buffer */
    char subtype[TMSTYPELEN];   /* subtype of buffer */
    long dfltsize;              /* default size of buffer */
/* buffer initialization function pointer */
int (_TMDLLENTRY *initbuf) _((char _TM_FAR *, long));
/* buffer reinitialization function pointer */
int (_TMDLLENTRY *reinitbuf) _((char _TM_FAR *, long));
/* buffer un-initialization function pointer */
int (_TMDLLENTRY *uninitbuf) _((char _TM_FAR *, long));
/* pre-send buffer manipulation func pointer */
long (_TMDLLENTRY *presend) _((char _TM_FAR *, long, long));
/* post-send buffer manipulation func pointer */
void (_TMDLLENTRY *postsend) _((char _TM_FAR *, long, long));
/* post-receive buffer manipulation func pointer*/
long (_TMDLLENTRY *postrecv) _((char _TM_FAR *, long, long));
/* XDR encode/decode function pointer */
long (_TMDLLENTRY *encdec) _((int, char _TM_FAR *, long, char _TM_FAR *, 
long));
/* routing function pointer */
int (_TMDLLENTRY *route) _((char _TM_FAR *, char _TM_FAR *, char _TM_FAR *, 
long, char _TM_FAR *));
/* buffer filtering function pointer */
int (_TMDLLENTRY *filter) _((char _TM_FAR *, long, char _TM_FAR *, long));
/* buffer formatting function pointer */
int (_TMDLLENTRY *format) _((char _TM_FAR *, long, char _TM_FAR *, 
char _TM_FAR *, long));
/* process buffer before sending, possibly generating copy */
long (_TMDLLENTRY *presend2) _((char _TM_FAR *, long, 
long, char _TM_FAR *, long, long _TM_FAR *));
/* Multibyte code-set encoding conversion function pointer*/
long (_TMDLLENTRY *mbconv) _((char _TM_FAR *, long, 
char _TM_FAR *, char _TM_FAR *, long, long _TM_FAR *));
/* this space reserved for future expansion */
void (_TMDLLENTRY *reserved[8]) _((void));
};
/* 
 * application types switch pointer
 * always use this pointer when accessing the table
 */
extern struct tmtype_sw_t *tm_typeswp;

前述のデフォルト・バッファ・タイプ・スイッチの例は、バッファ・タイプ・スイッチの初期化を示しています。9つのデフォルト・バッファ・タイプの後に、サブタイプの名前を指定するフィールドがあります。VIEW (X_C_TYPEX_COMMON)型を除き、サブタイプはNULLです。VIEWのサブタイプは``*''として指定されています。これは、デフォルトのVIEW型のサブタイプに制約がないことを示します。つまり、VIEW型のすべてのサブタイプは同じ方法で処理されます。

次のフィールドには、バッファのデフォルト(最小)サイズが指定されています。CARRAY (X_OCTET)型の場合、このフィールドに0が指定されています。これは、CARRAY型バッファを使用するルーチンでは、CARRAY型に必要な領域をtpalloc()で割り当てなければならないことを示します。

それ以外のバッファ・タイプの場合、tpalloc()が呼び出されて、dfltsizeフィールドに指定されている領域がOracle Tuxedoシステムによって割り当てられます。ただし、tpalloc()のサイズを示す引数にこれより大きな値が設定されていない場合にかぎります。

バッファ・タイプ・スイッチのエントリで、残りの8つのフィールドには、スイッチ要素ルーチンの名前が指定されています。これらのルーチンの詳細は、『Oracle Tuxedo C言語関数リファレンス』buffer(3c)を参照してください。ルーチン名からそのルーチンの処理内容がわかります。たとえば、FML型の_fpresendは、送信前にバッファを操作するルーチンを指すポインタです。送信前処理が必要ない場合は、NULLポインタを指定します。NULLは、特に処理が必要ないことを示し、その結果デフォルトの処理が行われます。詳細は、buffer(3c)を参照してください。

スイッチの最後にNULLエントリがあることに注目してください。変更時には、配列の終わりに必ずNULLエントリを置いてください。