Data Effectorの条件式からcall関数で呼び出す、ユーザー定義関数の作成例を示します。
ユーザー定義関数の仕様
入力文字列中の半角英字を大文字に変換します。
以下に、ユーザー定義関数の作成例を示します。
#if defined( WIN32 )
#define DEFUNC_QUALIFIER __declspec(dllexport)
#else
#define DEFUNC_QUALIFIER
#endif
#if defined(__cplusplus)
extern "C" DEFUNC_QUALIFIER int Defunc( int, void **, void ** );
#endif
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
#include "libAsis.h"
/* ユーザー定義関数の仕様
* ・引数として、ASCII文字だけから構成される文字列を受け取る
* ・その文字列に含まれる小文字を大文字に変換した文字列を返す
*/
/* エラーコード */
enum {
C_UFNC_NORMAL_END = 0,
C_UFNC_ERR_UNKNOWN_CALLCODE,
C_UFNC_ERR_INSUFFICIENT_MEMORY,
C_UFNC_ERR_NULL_HANDLE,
C_UFNC_ERR_NULL_DATA,
C_UFNC_ERR_TOO_FEW_OR_TOO_MANY_ARGUMENTS,
C_UFNC_ERR_INVALID_ARGUMENT,
C_UFNC_ERR_NULL_RETURN_DATA
};
/* ハンドル */
struct userhandle_tag {
int sz_buffer; /* 作業領域のサイズ */
char *buffer; /* 作業領域 */};
/* 呼び出しコード別の処理 */
/* 環境開設 */
struct userhandle_tag* defunc_open( void );
/* 環境閉鎖 */
void defunc_close(
struct userhandle_tag*
);
/* 変換実行 */
int defunc_exec(
struct userhandle_tag*,
int,
char **,
char **
);
/* 領域解放 */
void defunc_free(
struct userhandle_tag*,
char *
);
/* ユーザー定義関数の実装 */
DEFUNC_QUALIFIER int Defunc(
int Oper, /* 呼び出し種別 */
void **Handle, /* ハンドル */
void **Data /* 引数, および返却用の領域 */
)
{
struct userhandle_tag *handle = NULL;
int ret = C_UFNC_NORMAL_END;
switch( Oper ) {
case DE_USER_FUNCTION_THREAD_OPEN:
/* 環境の開設 */
handle = defunc_open( );
if( handle == NULL ) {
/* 失敗 */
ret = C_UFNC_ERR_INSUFFICIENT_MEMORY;
}
else {
/* ハンドルを返却 */
*Handle = handle;
}
break;
case DE_USER_FUNCTION_THREAD_CLOSE:
/* 環境の閉鎖 */
handle = (struct userhandle_tag*)*Handle;
defunc_close( handle );
break;
case DE_USER_FUNCTION_EXEC:
/* 変換の実行 */
if( *Handle == NULL ) {
return C_UFNC_ERR_NULL_HANDLE;
}
if( *Data == NULL ) {
return C_UFNC_ERR_NULL_DATA;
}
handle = (struct userhandle_tag *)*Handle;
{
int num_arg; /* 引数の数 */
int offset;
char **arg_list; /* 引数のリスト */
char *result; /* 結果が格納された領域のポインタ */
/* 引数の情報の分解 */
memcpy(&num_arg, (char*)(Data[0]), sizeof(int));
memcpy(&offset, (char*)(Data[0]) + sizeof(int), sizeof(int));
arg_list = (char**)((char*)(Data[0]) + + sizeof(int)*2 + offset);
/* 変換処理の実施 */
ret = defunc_exec(handle, num_arg, arg_list, &result );
if( ret != C_UFNC_NORMAL_END ) {
return ret;
}
else {
/* 変換結果の設定 */
Data[0] = result;
}
}
break;
case DE_USER_FUNCTION_FREE:
/* 領域の解放*/
handle = (struct userhandle_tag *)*Handle;
{
char *result; /* 結果が格納された領域のポインタ */
result = (char*)Data[0];
defunc_free( handle, result );
}
break;
default:
return C_UFNC_ERR_UNKNOWN_CALLCODE;
}
return C_UFNC_NORMAL_END;
}
/* 環境開設処理 */
struct userhandle_tag * defunc_open(
void
)
{
struct userhandle_tag *wk_handle;
/* ハンドルの獲得 */
wk_handle = (struct userhandle_tag *) calloc(1, sizeof(struct userhandle_tag ));
if( wk_handle == NULL ) {
return NULL;
}
/* 作業領域の獲得 */
wk_handle->sz_buffer = 1024;
wk_handle->buffer = (char*)malloc( wk_handle->sz_buffer );
if( wk_handle->buffer == NULL ) {
free( wk_handle );
return NULL;
}
/* 獲得したハンドルを返す */
return wk_handle;
}
/* 環境閉鎖処理 */
void defunc_close(
struct userhandle_tag *handle
)
{
if( handle != NULL ) {
if( handle->buffer != NULL ) {
free( handle->buffer );
handle->buffer = NULL;
}
free( handle );
handle = NULL;
}
return ;
}
/* 変換実行 */
int defunc_exec(
struct userhandle_tag *handle,
int
num_arg,
char **arg_list,
char **result
)
{
/* 入力文字列のポインタ */
const char *instr;
/* 入力文字列の長さ */
int len_instr;
/* 出力文字列 */
char *outstr;
/* 出力文字列の長さ */
int len_outstr;
int i;
outstr = NULL;
if( num_arg != 1 ) {
return C_UFNC_ERR_TOO_FEW_OR_TOO_MANY_ARGUMENTS;
}
/* 引数の情報 */
instr = arg_list[0];
len_instr = strlen( instr );
/* ASCII文字なので変換後の長さは入力の長さと同じ */
len_outstr = len_instr;
/*
* 変換結果用のバッファの獲得
* ・ハンドル内の作業領域に変換結果を持つ
*/
if( handle->sz_buffer < len_outstr + 1 ) {
/* サイズが足りないので拡張する */
char *tmp_ptr;
int tmp_sz;
tmp_sz = len_outstr + 1;
tmp_ptr = (char*)realloc( handle->buffer, tmp_sz );
if( tmp_ptr == NULL ) {
return C_UFNC_ERR_INSUFFICIENT_MEMORY;
}
handle->buffer = tmp_ptr;
handle->sz_buffer = tmp_sz;
}
outstr = handle->buffer;
/* 変換 */
for( i=0; i<len_instr; i++ ) {
outstr[i] = toupper( instr[i] );
}
outstr[i] = '\0';
/* 返却データをセット */
*result = outstr;
return C_UFNC_NORMAL_END;
}
/* 領域解放 */
void defunc_free(
struct userhandle_tag *handle,
char *result
)
{
/* 変換結果の領域はハンドルにある作業領域なので解放しない */
if( result != NULL ) {
result[0] = '\0';
}
return;
} |