/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

	【機能概要】	: 共有メモリアクセスSR【本体】
					  Java言語、C++言語等から本SRを呼び出して、共有メモリに設定された
					  データ値を検索・取得する
					  GG_SHM0011_logic（検索処理）とGG_SHM0011_getData（データ取得処理）
					  の２つで構成されている

	【作成日】		: 2021.04.23

	【呼出形式1】	: GG_SHM0011_logic (
						  int prmNum						# 入力パラメータ数を入力
						, char in[][GG_SHM0001_MaxPrmLen]	# 各パラメータを入力（パラメータ例は以下）
															# テーブルID / 検索ID / key1 / value1 / key2 / value2 ･･･
					  )
	【戻り値1】		: int									# 検索結果バイト長

	【呼出形式2】	: GG_SHM0011_getData (
						  char *arrOut						# 返却データ格納領域を指定（各行は\n区切り）
															# １行目:項目名（\t区切り）、２行目以降:データ値（\t区切り）
					  )
	【戻り値2】		: void									# なし

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */


#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <errno.h>
#include <math.h>

#include "GG_SHMCOM.h"

/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

	引数構造の変遷
	
	※ 業務クラス⇒(1)⇒ShmStaticTableクラス⇒(2)⇒GG_SHM0001       ⇒(3)⇒GG_SHM0011_logic
											⇒(4)⇒GG_SHM0001getData⇒(5)⇒GG_SHM0011_getData

		(1) 業務ＡＰからShmStaticTableクラスに下記の情報が渡される。
				・String TableName		テーブル名称(*1)
				・String Key			アクセスキー（アクセス方法）名称(*2)
				・HashMap<String , String> in	検索カラム名(*3)＆ 検索パラメータ値(*4)
				
				※）アクセスパターンファイル（例）
				＋－－－－－－－－－－－－－－－－－－－－－－－－－－＋
				｜<TableAccess>
				｜	<Table id="M_MEISHO"(*1) name="M_MEISHO">
				｜		<Search id="001"(*2)>
				｜			<Define>
				｜				<Sentence where="CD_SBT = ?(*4)"/>
				｜				<iData column="CD_SBT"(*3)/>
				｜			</Define>
				｜		</Search>
				｜	</Table>
				｜</TableAccess>
				＋－－－－－－－－－－－－－－－－－－－－－－－－－－＋
			
		(2) ShmStaticTableクラスは、GG_SHM0001（Javaラッパー）呼び出し時には、上記パラメータ
			を「一つのjbyteArray領域」に格納する。また、各領域の区切り文字に「\n」を使用する

			・「jbyteArray in」の構造
				(TableName)\n(Key)\n(検索カラム名1)\n(検索パラメータ値1)\n(検索カラム名2)\n(検索パラメータ値2)\n・・・

		(3) GG_SHM0001からGG_SHM0011_logic（本プログラム内部ルーチン）呼び出し時には、プログラ
			ムの扱い易さから、上記パラメータを領域名「Prm」（char配列）に設定
				Prm[1]・・(TableName)
				Prm[2]・・(Key)
				Prm[3]・・(検索カラム名1)
				Prm[4]・・(検索パラメータ値1）
				Prm[5]以降は、Prm[3]/Prm[4]の繰り返し

		(4) ShmStaticTableクラスは、(2)呼び出しの結果で検索結果データ長が返却される。
			そのデータ長分のバイト領域をJavaで生成して、GG_SHM0001getDataを行うと、バイト
			領域に検索結果データが返却される。

		(5) GG_SHM0001getDataからGG_SHM0011_getData（本プログラム内部ルーチン）呼び出し時には、
			(4)で生成したバイト領域のポインタを指定すると、GG_SHM0011_logicで格納した検索結果
			を返却する。

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

０．共有メモリ全体配置

	＋－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－＋
	｜　　　　　　　　　　　　１．共有メモリ管理部　　　　　　　　　　　　　　　　　　　｜
	｜　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　｜
	｜　＋－－＋　＋－－－－－－－－－－－－＋　　　　　　　　　　　　　　　　　　　　　｜
	｜　｜1.1 ｜　｜1.2 識別管理面情報　　　｜　　　　　　　　　　　　　　　　　　　　　｜
	｜　＋－－＋　＋－－－－－－－－－－－－＋　　　　　　　　　　　　　　　　　　　　　｜
	｜　＋－－－－－－－－－－－－－－－－－＋　　　　　　　　　　　　　　　　　　　　　｜
	｜　｜1.3 共有ﾒﾓﾘ識別管理部 　　　　　　｜　　　　　　　　　　　　　　　　　　　　　｜
	｜　＋－－－－－－－－－－－－－－－－－＋　　　　　　　　　　　　　　　　　　　　　｜
	｜　＋－－－－－－－－－－－－－－－－－＋　＋－－－－－－－－－－－－－－－－－＋　｜
	｜　｜1.4 ﾃｰﾌﾞﾙ/共有ﾒﾓﾘｸﾞﾙｰﾌﾟ(1面)　　　｜　｜1.4 ﾃｰﾌﾞﾙ/共有ﾒﾓﾘｸﾞﾙｰﾌﾟ(2面)　　　｜　｜
	｜　＋－－－－－－－－－－－－－－－－－＋　＋－－－－－－－－－－－－－－－－－＋　｜
	｜　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　｜
	＋－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－＋
	＋－－－－－－－－－－－－－－－－－－－＋　＋－－－－－－－－－－－－－－－－－－－＋
	｜　　２．共有ﾒﾓﾘｸﾞﾙｰﾌﾟ(1面)　　　　　　｜　｜　　２．共有ﾒﾓﾘｸﾞﾙｰﾌﾟ(2面)　　　　　　｜
	｜　　　　　　　　　　　　　　　　　　　｜　｜　　　　　　　　　　　　　　　　　　　｜
	｜　＋－－－－－－－－－－－－－－－＋　｜　｜　＋－－－－－－－－－－－－－－－＋　｜
	｜　｜2.1 共有ﾒﾓﾘ･ﾃﾞｰﾀ管理部　　　　｜　｜　｜　｜2.1 共有ﾒﾓﾘ･ﾃﾞｰﾀ管理部　　　　｜　｜
	｜　＋－－－－－－－－－－－－－－－＋　｜　｜　＋－－－－－－－－－－－－－－－＋　｜
	｜　＋－－－－－－－－－－－－－－－＋　｜　｜　＋－－－－－－－－－－－－－－－＋　｜
	｜　｜2.2 　｜2.3 　｜2.4 　｜2.5 　｜　｜　｜　｜2.2 　｜2.3 　｜2.4 　｜2.5 　｜　｜
	｜　＋－－－－－－－－－－－－－－－＋　｜　｜　＋－－－－－－－－－－－－－－－＋　｜
	｜　＋－－－－－－－－－－－－－－－＋　｜　｜　＋－－－－－－－－－－－－－－－＋　｜
	｜　｜2.2 　｜2.3 　｜2.4 　｜2.5 　｜　｜　｜　｜2.2 　｜2.3 　｜2.4 　｜2.5 　｜　｜
	｜　＋－－－－－－－－－－－－－－－＋　｜　｜　＋－－－－－－－－－－－－－－－＋　｜
	｜　＋－－－－－－－－－－－－－－－＋　｜　｜　＋－－－－－－－－－－－－－－－＋　｜
	｜　｜2.2 　｜2.3 　｜2.4 　｜2.5 　｜　｜　｜　｜2.2 　｜2.3 　｜2.4 　｜2.5 　｜　｜
	｜　＋－－－－－－－－－－－－－－－＋　｜　｜　＋－－－－－－－－－－－－－－－＋　｜
	｜　　　　　　　　　：　　　　　　　　　｜　｜　　　　　　　　　：　　　　　　　　　｜
	｜　　　　　　　　　：　　　　　　　　　｜　｜　　　　　　　　　：　　　　　　　　　｜
	｜　　　　　　　　　：　　　　　　　　　｜　｜　　　　　　　　　：　　　　　　　　　｜
	＋－－－－－－－－－－－－－－－－－－－＋　＋－－－－－－－－－－－－－－－－－－－＋
	＋－－－－－－－－－－－－－－－－－－－＋　＋－－－－－－－－－－－－－－－－－－－＋
	｜　　２．共有ﾒﾓﾘｸﾞﾙｰﾌﾟ(1面)　　　　　　｜　｜　　２．共有ﾒﾓﾘｸﾞﾙｰﾌﾟ(2面)　　　　　　｜
	＋－－－－－－－－－－－－－－－－－－－＋　＋－－－－－－－－－－－－－－－－－－－＋
	＋－－－－－－－－－－－－－－－－－－－＋　＋－－－－－－－－－－－－－－－－－－－＋
	｜　　２．共有ﾒﾓﾘｸﾞﾙｰﾌﾟ(1面)　　　　　　｜　｜　　２．共有ﾒﾓﾘｸﾞﾙｰﾌﾟ(2面)　　　　　　｜
	＋－－－－－－－－－－－－－－－－－－－＋　＋－－－－－－－－－－－－－－－－－－－＋
	＋－－－－－－－－－－－－－－－－－－－＋　＋－－－－－－－－－－－－－－－－－－－＋
	｜　　２．共有ﾒﾓﾘｸﾞﾙｰﾌﾟ(1面)　　　　　　｜　｜　　２．共有ﾒﾓﾘｸﾞﾙｰﾌﾟ(2面)　　　　　　｜
	＋－－－－－－－－－－－－－－－－－－－＋　＋－－－－－－－－－－－－－－－－－－－＋

１．共有メモリ管理部
	管理部のＩＤおよびサイズは、GG_SHMMEMLD.shl のGG_SHM1001_MEMORYID/GG_SHM1001_MEMORYSZ
	で決定する。
	共有メモリ管理部は単一の共有メモリＩＤの中で、ログレベル(1面)、識別管理面情報
	（1面）と、共有メモリ識別管理（2面）を格納する。

１．１ ログレベル（long 8 byte）
		GG_SHM0011（共有メモリアクセスAPI）、GG_SHM1000（共有メモリ展開）等、Ｃ言語プロ
		グラムのログ出力レベルを格納する。商用時のログレベルは、０

１．２ 識別管理面情報
		共有メモリ識別管理の使用面（1 or 2）および先頭からの相対位置を格納する。

		ShmFlg		共有メモリ使用面			long		8 byte
		TblNum_A	テーブル件数（1面）			long		8 byte
		TblNum_B	テーブル件数（2面）			long		8 byte

１．３ 共有メモリ識別管理
		共有メモリ識別管理の使用面（1 or 2）およびメモリ番号等を格納する。

		s_ShmDef	共有メモリ管理領域	構造体 × 件数
		ShmName		共有メモリ名称				char		32 byte
		ShmFlg		使用面格納フラグ(1または2)	long		8 byte
		ShmID_A		共有メモリ番号（1面）		key_t(long)	8 byte
		ShmID_B		共有メモリ番号（2面）		key_t(long)	8 byte
		ShmLength	共有メモリ領域サイズ		long		8 byte

１．４ テーブル／共有メモリグループ管理
		テーブルが属する共有メモリグループ名称を管理する領域。
		共有メモリアクセスの高速化のために生成。使用面およびレコード件数は、
		「１．２　識別管理面情報」で管理。
		
		t_TblShmDef	テーブル／グループ管理		構造体 × 件数
		TblId		テーブル名称				char		48 byte
		ShmName		共有メモリグループ名称		char		32 byte

２．共有メモリグループ情報
	本領域は、ShmMng.defで定義された共有メモリ管理部情報に従って領域確保を行う。
	共有メモリ名称１つに対して、下記構造の領域が２つの面で構成される。

２．１ 共有メモリデータ・アクセス管理部
		テーブルＩＤ毎のデータ・項目情報・アクセスパターンを管理する領域
		テーブルに対する属性およびメモリ展開後の格納位置・サイズが格納されている。

		TblDefNum	テーブル属性情報件数		long		8 byte
		TblDef		テーブル属性情報	構造体 × 件数
		TblNo		テーブル番号				char		8 byte
		TblId		テーブルＩＤ				char		48 byte
		AcType		アクセスタイプ（未使用）	char		24 byte
		TextName	データファイル名称			char		256 byte
		XmlFileName	アクセス定義ファイル名称	char		256 byte
		TblName		テーブル名称（未使用）		char		48 byte
		TblDataPos	テーブルデータ相対位置		long		8 byte
		TblDataLen	テーブルデータサイズ		long		8 byte
		TblColPos	テーブルヘッダ情報相対位置	long		8 byte
		TblColNum	テーブルヘッダ情報件数		long		8 byte
		TblPtnPos	アクセスパターン相対位置	long		8 byte
		TblPtnNum	アクセスパターン件数		long		8 byte

２．２ テーブルヘッダ情報部
		データファイルの先頭行に格納されたテーブル項目情報から、項目名称および項目長
		を管理する領域。項目長は、テーブルデータ部に格納されたデータの最大長を設定。
		また、共有メモリ上の格納場所・レコード件数は、「共有メモリデータ・アクセス管
		理部」で管理されている。
		
		ColumnName	項目名称					char		256 byte
		ColumnSize	項目長						long		8 byte

２．３ テーブルデータ部
		テーブルＩＤ毎のデータを格納する領域
		テーブルデータは、項目：TAB区切り、行：改行区切り、の可変長データを固定長デー
		タでメモリ管理する。
		また、共有メモリ上の格納場所・レコード件数は、「共有メモリデータ・アクセス管
		理部」で管理されている。

２．４ アクセスパターン部
		アクセス定義ファイルに格納されたアクセスパターン毎に定義情報を管理する。
		共有メモリ上では、アクセス定義ファイルを解析し、'\0'区切りで下記の順番に情報
		管理を行う。colを除く各項目は、全て可変長データ。
		また、共有メモリ上の格納場所・レコード件数は、「共有メモリデータ・アクセス管
		理部」で管理されている。
		インデックスがないアクセスパターンは、AcPt[3] インデックス領域開始位置には
		all_0が設定される。
		
		col			AcPt（パターン）項目数		int			4 byte
		AcPt[0]		テーブル名称				char		可変
		AcPt[1]		アクセスパターン名称		char		可変
		AcPt[2]		条件文（where句部分）		char		可変
		AcPt[3]		インデックス領域開始位置	char		12 byte
		AcPt[4]		インデックスレコード長		char		12 byte
		AcPt[5]		インデックスレコード件数	char		12 byte
		AcPt[6]		検索カラム名称１			char		可変
		AcPt[7]以降は、AcPt[6]同様に検索カラム名称を格納

２．５ インデックス領域部
		インデックスデータ（項目名/データ値）を格納する。データフォーマットは、
		「２．３ テーブルデータ部」と同じであり、行の格納順番は、キー値によって
		昇順に並べ直しされた状態。
		インデックスを生成する条件は、以下の通り。
			・アクセスパターン名称が「Index_」から始まる
			・検索条件が一つ、またはandで連結されているもの
			・検索条件が「=」かつ「文字列比較」のもの
		例）アクセスパターン名称が「Index_sample01」であり、検索条件が
		　　「項目A = ? and 項目B@NUM = ? and 項目C >= ? and 項目D = ?」の場合
		　　項目Aと項目Dによるインデックスが生成される

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

static  int		initFlg = 0    ;				// 0 : 未初期化 , 1 : 初期化処理中 , 2 : 初期化済み */
static  char	**c_SHMBaseArray_A ;			// 共有メモリグループ情報（1面）管理ポインタ配列（2.1参照）
static  char	**c_SHMBaseArray_B ;			// 共有メモリグループ情報（2面）管理ポインタ配列（2.1参照）
static	ST_ShmDef	*s_ShmDefBase ;				// 共有メモリ識別管理先頭ポインタ（1.3参照）
static	ST_ThreadMng *s_Thrd ;					// 検索結果データ返却一時保存管理領域
static	int		ThrdNum ;						// 同時走行スレッド数（100から自動拡張）
static	char	*c_ShmMngPtr ;					// 共有メモリ管理部（1.1参照）

CLSSharedMemory shmAcPtMng;
CLSSharedMemory shmAcPtPtr_A[ GG_SHM1001_SHMIDNUM ];
CLSSharedMemory shmAcPtPtr_B[ GG_SHM1001_SHMIDNUM ];

#ifdef _NONSTOP
#define SYS_gettid 2
int syscall(int id);							// NONSTOPサーバ用スレッドID取得処理（宣言）
#endif
int isNumber( char *str ) ;						// 数値チェック処理（宣言）
int to_long_double ( char *in_str , long double *out_ld ) ;		// 数値変換 & チェック

/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	共有メモリデータ結果返却処理
	GG_SHM0011_logicで検索したデータを本処理で返却する。
	GG_SHM0011_logicの検索結果を特定するためにスレッドIDを使用して、一時保存した
	データの返却を行い、返却後はfree解放と管理テーブルの初期化を行う。
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

void GG_SHM0011_getData ( char *arrOut ) {

	char    szLogFileTmpPath [ MAX_PATH ] ;			// ログファイル名フォーマット
	char    g_szLogFilePath  [ MAX_PATH ] ;			// ログファイル名
	char    szAccessDate [ 30 ] ;					// YYYY-MM-DD HH:MM:SS.mmmmmm
	int		ThreadId = (int)syscall(SYS_gettid) ;	// スレッドID取得

	// ログ出力場所の決定
	getEnvString ( szLogFileTmpPath , "GG_LogFileName"
		, GG_SHM0011_LOGPATH , sizeof(szLogFileTmpPath) );
	getLocalTimeString ( g_szLogFilePath , sizeof(g_szLogFilePath) , szLogFileTmpPath ) ;

	int rc = startLock(0) ;							// 排他制御（mutex:0）
	if ( rc != 0 ) {
		// 排他制御開始エラー
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 0
			, "(%05d) **** ( %s ) **** GG_SHM0011 排他制御開始エラー rc=%d"
			, ThreadId , szAccessDate , rc ) ;
	}

	for ( int i = 0 ; i < ThrdNum ; i++ ) {
		if ( s_Thrd[i].tid == syscall(SYS_gettid) ) {
			if ( arrOut[0] != '\0' ) {
				strcpy ( (char *)arrOut , s_Thrd[i].arrOut ) ;
			} else {
//				printf("検索データ無により、メモリ削除\n") ;
			}
			s_Thrd[i].tid = 0 ;
			free ( s_Thrd[i].arrOut ) ;
			s_Thrd[i].arrOut = NULL ;
			break ;
		}
	}

	rc = endLock(0) ;							// 排他制御（mutex:0）
	if ( rc != 0 ) {
		// 排他制御終了エラー
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 0
			, "(%05d) **** ( %s ) **** GG_SHM0011 排他制御終了エラー rc=%d"
			, ThreadId , szAccessDate , rc ) ;
	}
}

/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	共有メモリデータ検索処理
	共有メモリデータの検索論理を実装。
	業務アプリケーションによる検索指示とパラメータ（テーブルID・検索ID・検索条件等）
	に従い、検索データを一時領域に格納して、検索データ長を返却する。
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

int GG_SHM0011_logic( int prmNum, char Prm[][ GG_SHM0001_MaxPrmLen ] )
{
	char    szLogFileTmpPath [ MAX_PATH ] ;			// ログファイル名フォーマット
	char    g_szLogFilePath  [ MAX_PATH ] ;			// ログファイル名
	char    szAccessDate [ 30 ] ;					// YYYY-MM-DD HH:MM:SS.mmmmmm
	char    *c_SHMBase ;							// テーブルヘッダ情報部先頭ポインタ（2.2参照）
	char    *c_SHMemory ;							// 共有メモリ検索ポインタ
	ST_TblDef	*t_TblDef ;							// 共有メモリグループ管理情報（2.1参照）
	ST_ShmDef	*s_ShmDef ;							// 共有メモリ識別管理（1.3参照）

	int		ThreadId = (int)syscall(SYS_gettid) ;	// スレッドID取得

	// ログ出力場所の決定
	getEnvString ( szLogFileTmpPath , "GG_LogFileName"
		, GG_SHM0011_LOGPATH , sizeof(szLogFileTmpPath) );

	getLocalTimeString ( g_szLogFilePath , sizeof(g_szLogFilePath) , szLogFileTmpPath ) ;

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
				全スレッドで最も早く動いたスレッドが 「initFlg=0」
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	if ( initFlg == 0 ) {
		// 初期化フラグを「初期化中」に変更
		initFlg = 1 ;

		// 開始メッセージ出力
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 1
			, "(%05d) **** ( %s ) **** GG_SHM0011 共有メモリ初期化開始 **** START ****"
			, ThreadId , szAccessDate ) ;

		/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
								共有メモリポインタ領域初期化
		_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

		c_SHMBaseArray_A = (char **) malloc ( GG_SHM1001_SHMIDNUM * sizeof(char *) ) ;
		c_SHMBaseArray_B = (char **) malloc ( GG_SHM1001_SHMIDNUM * sizeof(char *) ) ;
		for ( int i = 0 ; i < GG_SHM1001_SHMIDNUM ; i ++ ) {
			c_SHMBaseArray_A[i] = (char *)NULL ;
			c_SHMBaseArray_B[i] = (char *)NULL ;
		}

		/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
							検索データ一時保存管理領域の初期化
		_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

		ThrdNum = GG_SHM0001_MaxThread ;
		s_Thrd = (struct ThreadMngType *) malloc ( sizeof(ST_ThreadMng) * ThrdNum ) ;
		for ( int i = 0 ; i < ThrdNum ; i ++ ) {
			s_Thrd[i].tid = 0 ;
		}

		int rc = initLock(3) ;							// 排他制御（mutex:３つ初期化）
		if ( rc != 0 ) {
			// 排他制御開始エラー
			getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
			GG_MsgOut ( g_szLogFilePath , 0
				, "(%05d) **** ( %s ) **** GG_SHM0011 排他制御初期化エラー rc=%d"
				, ThreadId , szAccessDate , rc ) ;
		}

		/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
								共有メモリポインタ取得 ( 管理部 )
		_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
	
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;

		key_t keyShmMainMem = getEnvLong("GG_SHM1001_MEMORYID",GG_SHM1001_MEMORYID);
	
		c_ShmMngPtr = (char *)shmAcPtMng.OpenSheredMemory( keyShmMainMem );
		if (c_ShmMngPtr == NULL) { 
			GG_MsgOut ( g_szLogFilePath , 0 , "(%05d) **** ( %s ) **** GG_SHM0011 共有メモリ取得エラー **** ID = ( %d )"
				, ThreadId , szAccessDate, keyShmMainMem ) ;
			initFlg = 3 ;
			return (-10);
		}

		// 先頭は、ログレベル(long型)の設定に使用
		s_ShmDef = (ShmDefType *)( c_ShmMngPtr + sizeof(long) ) ;
		s_ShmDefBase = s_ShmDef ;

		// 共有メモリ初期化終了メッセージ出力
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 1
			, "(%05d) **** ( %s ) **** GG_SHM0011 共有メモリ初期化終了 ****  END  ****"
			, ThreadId , szAccessDate ) ;

		// 初期化フラグを「初期化済」に変更
		initFlg = 2 ;

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
				最も早いスレッドが初期化処理中の場合、 「initFlg=1」
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	} else if ( initFlg == 1 ) {
		for (;;) {

#ifndef WIN32
			usleep ( 1000 ) ;
#else
			Sleep ( 1000 ) ;
#endif
			if ( initFlg == 2 ) {
				s_ShmDef = s_ShmDefBase ;
				break ;
			} else
			if ( initFlg == 3 ) {
				return (-11);
			}
		}

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
				初期化が終わっていれば、 「initFlg=2」
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	} else if ( initFlg == 2 ) {
		s_ShmDef = s_ShmDefBase ;
	
	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
				前回初期化がNGの場合ば、 「initFlg=3」
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
	
	} else if ( initFlg == 3 ) {
		// 初期化フラグを「初期化中」に変更
		initFlg = 1 ;
		/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
								共有メモリポインタ取得 ( 管理部 )
		_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
	
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;

		key_t keyShmMainMem = getEnvLong("GG_SHM1001_MEMORYID",GG_SHM1001_MEMORYID);
	
		c_ShmMngPtr = (char *)shmAcPtMng.OpenSheredMemory( keyShmMainMem );
		if (c_ShmMngPtr == NULL) { 
			GG_MsgOut ( g_szLogFilePath , 0 , "(%05d) **** ( %s ) **** GG_SHM0011 共有メモリ取得エラー **** ID = ( %d )"
				, ThreadId , szAccessDate, keyShmMainMem ) ;
			initFlg = 3 ;
			return (-10);
		}

		// 先頭は、ログレベル(long型)の設定に使用
		s_ShmDef = (ShmDefType *)( c_ShmMngPtr + sizeof(long) ) ;
		s_ShmDefBase = s_ShmDef ;

		// 共有メモリ初期化終了メッセージ出力
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 1
			, "(%05d) **** ( %s ) **** GG_SHM0011 共有メモリ初期化終了 ****  END  ****"
			, ThreadId , szAccessDate ) ;

		// 初期化フラグを「初期化済」に変更
		initFlg = 2 ;
	}

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
				ログレベル値を共有メモリからGG_MsgOutに設定
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	int rc = startLock(1) ;							// 排他制御（mutex:1）
	if ( rc != 0 ) {
		// 排他制御開始エラー
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 0
			, "(%05d) **** ( %s ) **** GG_SHM0011 排他制御開始エラー rc=%d"
			, ThreadId , szAccessDate , rc ) ;
	}

	// 共有メモリのログレベルをログ出力関数に設定
	long LogLevel ;
	memcpy ( (void *)&LogLevel , (void *)c_ShmMngPtr , sizeof(long) ) ;
	GG_MsgOut_SetTraceLevel ( LogLevel ) ;

	rc = endLock(1) ;								// 排他制御（mutex:1）
	if ( rc != 0 ) {
		// 排他制御終了エラー
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 0
			, "(%05d) **** ( %s ) **** GG_SHM0011 排他制御終了エラー rc=%d"
			, ThreadId , szAccessDate , rc ) ;
	}

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		共有メモリ管理領域を検索し、テーブル名称から共有メモリID（ShmName）を取得
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	long l_TblShmNum ;
	ST_TblShmDef *s_TblShmDef ;					// テーブル／共有メモリグループ管理ポインタ（1.4参照）
	char ShmName[32] ;
	ST_TblShmMng *s_TblShmMng = (ST_TblShmMng *)( s_ShmDefBase + GG_SHM1001_SHMIDNUM + 1 ) ;

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		検索面（1面or2面）の判定
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	if ( s_TblShmMng->ShmFlg == 1 ) {
		l_TblShmNum = s_TblShmMng->TblNum_A ;
		s_TblShmDef = (ST_TblShmDef *)( (char*)s_TblShmMng + sizeof(ST_TblShmMng) ) ;
	} else{
		l_TblShmNum = s_TblShmMng->TblNum_B ;
		s_TblShmDef = (ST_TblShmDef *)( (char*)s_TblShmMng + sizeof(ST_TblShmMng) + ( sizeof(ST_TblShmDef) * 4096 ) ) ;
	}

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		テーブルIDの検索（目的:テーブルID→共有メモリGの特定）
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	int x ;
	for ( x = 0 ; x < l_TblShmNum ; x++ ) {
		if ( strcmp ( s_TblShmDef[x].TblId , Prm[1] ) == 0 ) {
			strcpy ( ShmName , s_TblShmDef[x].ShmName ) ;
			break ;
		}
	}

	if ( x == l_TblShmNum ) {
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 0
			, "(%05d) **** ( %s ) **** TblId = [%s] 不正1!!"
			, ThreadId , szAccessDate , Prm[1] ) ;
		return (-12);
	}

	// 共有メモリ管理テーブル検索開始
	getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
	GG_MsgOut ( g_szLogFilePath , 4
		, "(%05d) **** ( %s ) **** GG_SHM0011 共有メモリ管理テーブル検索 **** START ****"
		, ThreadId , szAccessDate ) ;

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		共有メモリ管理領域を検索し、共有メモリIDから検索面のポインタ(c_SHMBase）を取得      
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	for ( x = 0 ; s_ShmDef->ShmName[0] != '\0' ; x++ , s_ShmDef ++ ) {
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 4
			, "(%05d) **** ( %s ) **** GG_SHM0011 共有メモリ管理テーブル検索 s_ShmDef[%d].ShmName=[%s] ShmName=[%s]"
			, ThreadId , szAccessDate , x , s_ShmDef->ShmName , ShmName ) ;
		if ( strcmp ( s_ShmDef->ShmName , ShmName ) == 0 ) {

			int rc = startLock(2) ;							// 排他制御（mutex:2）
			if ( rc != 0 ) {
				// 排他制御開始エラー
				getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
				GG_MsgOut ( g_szLogFilePath , 0
					, "(%05d) **** ( %s ) **** GG_SHM0011 排他制御開始エラー rc=%d"
					, ThreadId , szAccessDate , rc ) ;
			}

			getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
			GG_MsgOut ( g_szLogFilePath , 4
				, "(%05d) **** ( %s ) **** GG_SHM0011 共有メモリ管理テーブル検索 c_SHMBaseArray[%d]=[%x]"
				, ThreadId , szAccessDate , x , c_SHMBaseArray_A[x] ) ;

			if ( c_SHMBaseArray_A[x] == NULL ) {
				c_SHMBaseArray_A[x] = (char *)shmAcPtPtr_A[x].OpenSheredMemory( s_ShmDef->ShmID_A );
				c_SHMBaseArray_B[x] = (char *)shmAcPtPtr_B[x].OpenSheredMemory( s_ShmDef->ShmID_B );
				getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
				GG_MsgOut ( g_szLogFilePath , 4
					, "(%05d) **** ( %s ) **** GG_SHM0011 共有メモリグループアドレス取得 **** s_ShmDef[%d].ShmName=[%s]"
					, ThreadId , szAccessDate , x , s_ShmDef->ShmName ) ;
			}

			if ( c_SHMBaseArray_A[x] == NULL || c_SHMBaseArray_B[x] == NULL ) {
				getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
				GG_MsgOut ( g_szLogFilePath ,0,"(%05d) **** ( %s ) **** GG_SHM0011 共有メモリ取得エラー [%s]****"
					, ThreadId , szAccessDate , ShmName ) ;
				return (-10);
			}

			/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
				共有メモリフラグ（1/2面）の判定により、検索領域の決定
				テーブルIDが「GG_SHM0001_AllDtBack」は、非検索面を検索するため、下記の
				ようにc_SHMBaseにポインタ設定を行う。（通常は検索面を使用）
			_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

			if ( strcmp ( Prm[2] , GG_SHM0001_AllDtBack ) != 0 ) {
				if ( s_ShmDef->ShmFlg == 1 ) {
					c_SHMBase = c_SHMBaseArray_A[x] ;
				} else if ( s_ShmDef->ShmFlg == 2 ) {
					c_SHMBase = c_SHMBaseArray_B[x] ;
				}
			} else {
				if ( s_ShmDef->ShmFlg == 1 ) {
					c_SHMBase = c_SHMBaseArray_B[x] ;
				} else if ( s_ShmDef->ShmFlg == 2 ) {
					c_SHMBase = c_SHMBaseArray_A[x] ;
				}
			}

			rc = endLock(2) ;							// 排他制御（mutex:2）
			if ( rc != 0 ) {
				// 排他制御終了エラー
				getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
				GG_MsgOut ( g_szLogFilePath , 0
					, "(%05d) **** ( %s ) **** GG_SHM0011 排他制御終了エラー rc=%d"
					, ThreadId , szAccessDate , rc ) ;
			}

			getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
			GG_MsgOut ( g_szLogFilePath , 4
				, "(%05d) **** ( %s ) **** GG_SHM0011 メモリグループ(ShmName)=%s 面フラグ(s_ShmDef->ShmFlg)=%d"
				, ThreadId , szAccessDate , ShmName , s_ShmDef->ShmFlg ) ;

			break ;
		}
	}

	// 指定されたテーブルIDの共有メモリグループ名称が見つからない場合（定義ファイル記述ミス）
	if ( s_ShmDef->ShmName[0] == '\0' ) {
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 0 , "(%05d) **** ( %s ) **** GG_SHM0011 共有メモリ論理エラー [%s] ****"
			, ThreadId , szAccessDate , ShmName ) ;
		return (-13);
	}

	// 共有メモリ管理テーブル検索終了
	getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
	GG_MsgOut ( g_szLogFilePath , 4
		, "(%05d) **** ( %s ) **** GG_SHM0011 共有メモリ管理テーブル検索 ****  END  ****"
		, ThreadId , szAccessDate ) ;

	long    TblDefNum ;
	ST_TblDef   t_TblInfo ;
	c_SHMemory = c_SHMBase ;

	// 開始メッセージ出力
	getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
	GG_MsgOut ( g_szLogFilePath , 4
		, "(%05d) **** ( %s ) **** GG_SHM0011 テーブルデータ取得 **** START ****"
		, ThreadId , szAccessDate ) ;

	char *TableData , *TableDataBase ;

	rc = startLock(0) ;							// 排他制御（mutex:0）
	if ( rc != 0 ) {
		// 排他制御開始エラー
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 0
			, "(%05d) **** ( %s ) **** GG_SHM0011 排他制御開始エラー rc=%d"
			, ThreadId , szAccessDate , rc ) ;
	}

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		検索結果データ返却一時保存管理領域（s_Thrd）の空き領域を検索
		空き領域が見つかった場合は、データ返却領域をmallocして、空き領域にスレッドID
		とデータポインタを設定
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	int ThrdCnt = -1 ;
	for ( int i = 0 ; i < ThrdNum ; i++ ) {
		if ( s_Thrd[i].tid == 0 ) {
			s_Thrd[i].tid = syscall(SYS_gettid) ;
			// 業務AP返却用のワーク領域を生成
			s_Thrd[i].arrOut = (char *) malloc ( GG_SHM0001_MaxRetDataLen ) ;
			TableData = s_Thrd[i].arrOut ;
			TableDataBase = s_Thrd[i].arrOut ;
			getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
			GG_MsgOut ( g_szLogFilePath , 4
				, "(%05d) **** ( %s ) **** GG_SHM0011 ThreadId[%d]=%d arrOut(PTR)=%x"
				, ThreadId , szAccessDate , i , (int)s_Thrd[i].tid , s_Thrd[i].arrOut ) ;
			ThrdCnt = i ;
			break ;
		}
	}
	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		s_Thrdの空き領域がなかった場合
		s_Thrd領域を拡張（+100ずつ）して、同時並行可能スレッド数を自動拡張する
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	if ( ThrdCnt == -1 ) {
		ST_ThreadMng *s_ThrdWork
			= (struct ThreadMngType *) realloc ( s_Thrd , sizeof(ST_ThreadMng) * ( ThrdNum + GG_SHM0001_MaxThread ) ) ;
		s_Thrd = s_ThrdWork ;
		int i = ThrdNum ;
		for ( i = ThrdNum ; i < ThrdNum + GG_SHM0001_MaxThread ; i ++ ) {
			s_Thrd[i].tid = 0 ;
		}
		i = ThrdNum ;
		s_Thrd[i].tid = syscall(SYS_gettid) ;
		s_Thrd[i].arrOut = (char *) malloc ( GG_SHM0001_MaxRetDataLen ) ;
		TableData = s_Thrd[i].arrOut ;
		TableDataBase = s_Thrd[i].arrOut ;
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 4
			, "(%05d) **** ( %s ) **** GG_SHM0011 ThreadId[%d]=%d arrOut(PTR)=%x"
			, ThreadId , szAccessDate , i , (int)s_Thrd[i].tid , s_Thrd[i].arrOut ) ;
		ThrdNum = ThrdNum + GG_SHM0001_MaxThread ;
	}

	rc = endLock(0) ;							// 排他制御（mutex:0）
	if ( rc != 0 ) {
		// 排他制御終了エラー
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 0
			, "(%05d) **** ( %s ) **** GG_SHM0011 排他制御終了エラー rc=%d"
			, ThreadId , szAccessDate , rc ) ;
	}

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		共有データ・アクセス管理部サーチ処理
		業務ＡＰが指定したテーブル名称から、共有メモリ上の共有データ・アクセス
		管理部をサーチし、マッチした情報をt_TblInfo(ローカル領域)に設定
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	memset ( t_TblInfo.TblNo , 0x00 , sizeof(t_TblInfo.TblNo) ) ;
	memcpy ( (char *)&TblDefNum , c_SHMemory , sizeof(TblDefNum) ) ;
	t_TblDef = (struct TblDefType *)(c_SHMemory + sizeof(TblDefNum) ) ;

	int TblDefPos ;
	for ( int i = 0 ; i < TblDefNum ; i++ ) {
		if ( strcmp ( t_TblDef[i].TblId , Prm[1] ) == 0 ) {
			memcpy ( (char *)&t_TblInfo , (char *)&t_TblDef[i] , sizeof(t_TblInfo) ) ;
			getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
			// ログ出力：テーブルNo／テーブルID／アクセスタイプ／データファイル名
			GG_MsgOut ( g_szLogFilePath , 4
				, "(%05d) **** ( %s ) **** TblNo = %s TblId = %s AcType = %s TextName = %s"
				, ThreadId , szAccessDate , t_TblInfo.TblNo , t_TblInfo.TblId , t_TblInfo.AcType
				, t_TblInfo.TextName
				) ;
			// ログ出力：アクセスパターンファイル名／テーブル名称
			GG_MsgOut ( g_szLogFilePath , 4
				, "(%05d) **** ( %s ) **** XmlFileName = %s TblName =%s"
				, ThreadId , szAccessDate , t_TblInfo.XmlFileName , t_TblInfo.TblName
				) ;
			// ログ出力：データポインタ開始位置／共有メモリデータ長
			GG_MsgOut ( g_szLogFilePath , 4
				, "(%05d) **** ( %s ) **** TblDataPos = %d TblDataLen = %d"
				, ThreadId , szAccessDate , t_TblInfo.TblDataPos , t_TblInfo.TblDataLen
				) ;
			// ログ出力：項目名称開始位置／項目数
			GG_MsgOut ( g_szLogFilePath , 4
				, "(%05d) **** ( %s ) **** TblColPos = %d TblColNum = %d"
				, ThreadId , szAccessDate , t_TblInfo.TblColPos , t_TblInfo.TblColNum
				) ;
			// ログ出力：アクセスパターン開始位置／パターン数
			GG_MsgOut ( g_szLogFilePath , 4
				, "(%05d) **** ( %s ) **** TblPtnPos = %d TblPtnNum = %d"
				, ThreadId , szAccessDate , t_TblInfo.TblPtnPos , t_TblInfo.TblPtnNum
				) ;
			TblDefPos = i ;
			break ;
		}
	}

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		業務APが指定したアクセスパターンがない場合
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
	if ( strcmp ( t_TblInfo.TblNo , "" ) == 0 ) {
//		printf ( "P1 = [ %s ] 不正\n" , Prm[1] ) ;
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 0
			, "(%05d) **** ( %s ) **** TblId = [%s] 不正2!!"
			, ThreadId , szAccessDate , Prm[1]
		) ;
		return ( -1 ) ;
	}

	c_SHMemory = c_SHMBase + t_TblInfo.TblPtnPos ;

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		アクセスパターンのローカル展開
		業務ＡＰが設定した「TableName」、「Key」から、共有メモリ上のアクセス定義を
		検索し、合致した検索条件を「AcPt」(char配列)上に設定
			AcPt[0]・・テーブル名称
			AcPt[1]・・アクセスパターン名称
			AcPt[2]・・条件文（where句部分）
			AcPt[3]・・インデックス情報開始位置
			AcPt[4]・・インデックスレコード長
			AcPt[5]・・インデックスレコード件数
			AcPt[6]・・検索カラム名称１
			AcPt[7]以降は、AcPt[6]同様に検索カラム名称を格納
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	int row ;
	char AcPt [ GG_SHM0001_MaxPrmNum ][ GG_SHM0001_MaxCondLen ] ;

	if ( strcmp ( Prm[2] , GG_SHM0001_AllData )   != 0 &&
		 strcmp ( Prm[2] , GG_SHM0001_AllDtBack ) != 0 ) {
		for ( row = 0 ; row < t_TblInfo.TblPtnNum ; row++ ) {
			int colnum ;
			memcpy ( (char *)&colnum , c_SHMemory , sizeof(colnum) ) ;
			c_SHMemory = c_SHMemory + sizeof(colnum) ;
			int col ;
			for ( col = 0 ; col < colnum ; col++ ) {
				strcpy ( AcPt[col] , c_SHMemory ) ;
				AcPt[col+1][0] = '\0' ;
				c_SHMemory = c_SHMemory + strlen(AcPt[col]) + 1 ;
			}
			if ( strcmp ( AcPt[1] , Prm[2] ) == 0 ) {
				for ( col = 0 ; col < colnum ; col++ ) {
					// アクセスパターン情報のログ出力
					getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
					GG_MsgOut ( g_szLogFilePath , 4
						, "(%05d) **** ( %s ) **** AcPt[%d] = [%s]"
						, ThreadId , szAccessDate , col , AcPt[col]
					) ;
				}
				break ;
			}
		}
	}

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		データ全件検索／逆面データ全件検索のアクセスパターン指定
		業務ＡＰが「Key」に「AllDataOutput」を指定した場合、検索条件がアクセスパターン
		上に存在しなくても、全件データの返却を行うようにする
		また、「AllDataOutput-back」を指定した場合、共有メモリＡ面使用中にはＢ面、Ｂ面
		使用中にはＡ面の全件データを返却する
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	if ( strcmp ( Prm[2] , GG_SHM0001_AllData ) == 0 ) {
		strcpy ( AcPt[0] , Prm[0] ) ;
		strcpy ( AcPt[1] , GG_SHM0001_AllData ) ;
		AcPt[2][0] = '\0' ;
		AcPt[3][0] = '\0' ;
	} else if ( strcmp ( Prm[2] , GG_SHM0001_AllDtBack ) == 0 ) {
		strcpy ( AcPt[0] , Prm[0] ) ;
		strcpy ( AcPt[1] , GG_SHM0001_AllDtBack ) ;
		AcPt[2][0] = '\0' ;
		AcPt[3][0] = '\0' ;
	} else if ( row == t_TblInfo.TblPtnNum ) {
//		printf ( "P2 = [ %s ] 不正\n" , Prm[2] ) ;
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 0
			, "(%05d) **** ( %s ) **** AccessPtn = [%s] 不正!!"
			, ThreadId , szAccessDate , Prm[2]
		) ;
		return ( -2 ) ;
	}

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		共有メモリの検索条件文（AcPt[2]）の解析・分解と、ローカル展開（下記に分解）
			Left[n]		・・検索カラム名称を設定
			Hikaku[n]	・・=, !=, <, >, <=, >= のいずれかを設定
			Right[n]	・・検索パラメータ値（?または固定値）を設定
			Ketugo[n]	・・and, or のいずれかを設定
			nは、検索条件の内容により可変（最大19の条件設定が可能）
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	char Left		[GG_SHM0001_MaxCond][GG_SHM0001_MaxLeftLen] ;
	int  Left_Nid	[GG_SHM0001_MaxCond] ;
	char Hikaku		[GG_SHM0001_MaxCond][5] ;
	char Right		[GG_SHM0001_MaxCond][GG_SHM0001_MaxRightLen] ;
	long double		Right_Num	[GG_SHM0001_MaxCond] ;
	char Ketugo		[GG_SHM0001_MaxCond][5] ;
	int  Index_Pos	[GG_SHM0001_MaxCond] ;

	Ketugo[0][0] = '\0' ;

	if ( strcmp ( AcPt[1] , GG_SHM0001_AllData ) != 0 &&
		 strcmp ( AcPt[1] , GG_SHM0001_AllDtBack ) != 0 ) {
		for ( int i=0 ,j=0 ,k=0; i <= strlen(AcPt[2]) ; i++ ) {
			int p = k / 4 ;
			int q = k % 4 ;
			if ( AcPt[2][i] == ' ' || i == strlen(AcPt[2]) ) {
				if ( q==0 ) {
					memcpy ( Left[p] , AcPt[2]+j , i-j ) ;
					Left[p][i-j] = '\0' ;
					Left[p+1][0] = '\0' ;
					// @NUM対応
					char *Left_Num_Pos = strchr ( Left[p] , '@' ) ;
					if ( Left_Num_Pos != NULL ) {
						// 左項目名から@NUMを削除
						*Left_Num_Pos = '\0' ;
						Left_Nid[p] = 1 ;
					} else {
						Left_Nid[p] = 0 ;
					}
				} else if ( q==1 ) {
					memcpy ( Hikaku[p] , AcPt[2]+j , i-j ) ;
					Hikaku[p][i-j] = '\0' ;
					Hikaku[p+1][0] = '\0' ;
				} else if ( q==2 ) {
					memcpy ( Right[p] , AcPt[2]+j , i-j ) ;
					Right[p][i-j] = '\0' ;
					Right[p+1][0] = '\0' ;
				} else if ( q==3 ) {
					memcpy ( Ketugo[p] , AcPt[2]+j , i-j ) ;
					Ketugo[p][i-j] = '\0' ;
					Ketugo[p+1][0] = '\0' ;
				}
				j = i + 1 ;
				k++ ;
			}
		}
	} else {
		Left[0][0] = '\0' ;
		Hikaku[0][0] = '\0' ;
		Right[0][0] = '\0' ;
	}
	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		検索条件文（AcPt[2]）の分解結果のログ出力
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	for ( int i=0 ; Left[i][0] != '\0' ; i++ ) {
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 4
			, "(%05d) **** ( %s ) **** Left[%s] Hikaku[%s] Right[%s] Ketugo[%s]"
			, ThreadId , szAccessDate ,Left[i] ,Hikaku[i] ,Right[i] ,Ketugo[i]
			) ;
	}

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		検索パラメータ置換処理
		業務ＡＰが設定した「in」（HashMap：検索カラム名と検索パラメータ値）の検索
		カラム名（Prm[3]、3,5,7・・）と共有メモリ上の検索カラム名称（AcPt[6]、6,7,8・・）
		を比較する。合致した場合、共有メモリのパラメータ順（AcPt[6,7,8・・]）に従い、
		Right[n]の「?」をPrm[3,5,7・・]のデータに置換
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	for ( int i = 0 ; AcPt[ i + PARM_STARTPOS ][0] != '\0' ; i++ ) {
		int j ;
		for ( j = 0 ; prmNum >= j*2+4 ; j++ ) {
			if ( strcmp ( AcPt[ i + PARM_STARTPOS ] , Prm[j*2+3] ) == 0 ) {
				int k ;
				for ( k = 0 ; Right[k][0] != '\0' ; k++ ) {
					if ( strcmp ( Right[k] , "?" ) == 0 ) {
						strcpy ( Right[k] , Prm[j*2+4] ) ;
						// 数値比較：入力パラメータの数値変換
						if ( Left_Nid[k] == 1 ) {
							if ( to_long_double ( Right[k] , &Right_Num[k] ) < 0 ) {
								// エラー処理
								// 検索条件に「@NUM」が指定されたにも関わらず、業務APから当該項目に数字以外の
								// 値が設定された場合
								getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
								GG_MsgOut ( g_szLogFilePath , 0
									, "(%05d) **** ( %s ) **** [ %s ] = [ %s ] 数字比較項目に数値以外が設定された"
									, ThreadId , szAccessDate , Prm[j*2+3] , Prm[j*2+4]
								) ;
								return (-3) ;
							}
							// ログ出力（数値の確からしさ）
							getLocalTimeString ( szAccessDate , sizeof(szAccessDate), "%Y/%m/%d %H:%M:%S.%U" ) ;
							GG_MsgOut ( g_szLogFilePath , 9
								, "(%05d) **** ( %s ) **** Right_Num[%d] = %Lf"
								, ThreadId , szAccessDate , k , Right_Num[k]
							) ;
						}
						break ;
					}
				}
				
				// エラー処理
				// 条件文の「?」の数 < 業務APの検索カラム名称の数（またはアクセスパターンのカラム数）
				// が不一致だった場合
				if ( Right[k][0] == '\0' ) {
					for ( j = 3 ; j <= prmNum ; j++ ) {
						getLocalTimeString ( szAccessDate , sizeof(szAccessDate)
								, "%Y/%m/%d %H:%M:%S.%U" ) ;
						GG_MsgOut ( g_szLogFilePath , 4
							, "(%05d) **** ( %s ) **** Prm[%d] = [%s]"
							, ThreadId , szAccessDate ,j , Prm[j*2+3]
						) ;
					}
					getLocalTimeString ( szAccessDate , sizeof(szAccessDate)
							, "%Y/%m/%d %H:%M:%S.%U" ) ;
					GG_MsgOut ( g_szLogFilePath , 0
						, "(%05d) **** ( %s ) **** 検索パラメータが共有メモリ検索項目にありません2!!"
						, ThreadId , szAccessDate ) ;
					return ( -4 ) ;
				}
				break ;
			}
		}

		// エラー処理
		// 業務APの検索カラムが、共有メモリの検索カラムになかった場合
		if ( prmNum < j*2+4 &&
			 strcmp ( AcPt[1] , GG_SHM0001_AllData ) != 0 &&
			 strcmp ( AcPt[1] , GG_SHM0001_AllDtBack ) != 0 ) {
			// printf("j=%d\n",j) ;
			getLocalTimeString ( szAccessDate , sizeof(szAccessDate) , "%Y/%m/%d %H:%M:%S.%U" ) ;
			for ( j = 0 ; j*2+4 <= prmNum ; j++ ) {
				getLocalTimeString ( szAccessDate , sizeof(szAccessDate)
					, "%Y/%m/%d %H:%M:%S.%U" ) ;
				GG_MsgOut ( g_szLogFilePath , 4
					, "(%05d) **** ( %s ) **** Prm[%d] = [%s]"
					, ThreadId , szAccessDate ,j*2+3 , Prm[j*2+3]
				) ;
			}
			GG_MsgOut ( g_szLogFilePath , 0
				, "(%05d) **** ( %s ) **** 検索パラメータが共有メモリ検索項目にありません!!"
				, ThreadId , szAccessDate ) ;
			return ( -4 ) ;
		}
	}

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		検索条件文（AcPt[2]）の分解結果に、「?」置換結果を加えてログ出力
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	for ( int i=0 ; Left[i][0] != '\0' ; i++ ) {
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate) , "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 4
			, "(%05d) **** ( %s ) **** Left[%s] Hikaku[%s] Right[%s] Ketugo[%s]"
			, ThreadId , szAccessDate ,Left[i] ,Hikaku[i] ,Right[i] ,Ketugo[i]
		) ;
	}

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		ヘッダデータ返却処理
		データ返却領域の先頭に、テーブルのヘッダデータを設定する。
		ヘッダデータは、Column名1(TAB)Column名2(TAB)・・というように設定し、
		最後に(改行)を設定する。
		また、検索条件文で比較対象となったデータ項目は、行毎の開始位置とデータ長
		を Leftpos[n]/Leftlen[n] に設定する。
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	ST_ColumnDef    *t_ColumnDef ;
	long TblDataLen = 0 ;
	int  Leftpos	[GG_SHM0001_MaxCond] ;
	int  Leftlen	[GG_SHM0001_MaxCond] ;

	t_ColumnDef = (struct ColumnDefType *)(c_SHMBase + t_TblInfo.TblColPos) ;

	for ( int j = 0 ;  Left[j][0] != '\0' ; j ++ ) {
		TblDataLen = 0 ;
		for ( int i = 0 ; i < t_TblInfo.TblColNum ; i ++ ) {
			if ( strcmp ( Left[j] , t_ColumnDef[i].ColumnName ) == 0 ) {
				Leftpos[j] = TblDataLen ;
				Leftlen[j] = t_ColumnDef[i].ColumnSize ;
				break ;
			}
			TblDataLen = TblDataLen + t_ColumnDef[i].ColumnSize ;
		}
	}
	TblDataLen = 0 ;
	for ( int i = 0 ; i < t_TblInfo.TblColNum ; i ++ ) {
		strcpy ( TableData , t_ColumnDef[i].ColumnName ) ;
		TableData = TableData + strlen(t_ColumnDef[i].ColumnName) ;
		TableData [0] = '\t' ;
		TableData ++ ;
		TblDataLen = TblDataLen + t_ColumnDef[i].ColumnSize ;
	}
	TableData -- ;
	TableData [0] = '\n' ;
	TableData ++ ;

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		データ検索・返却処理
		検索条件と業務ＡＰが設定した値(バインド変数)にしたがって共有メモリデータの
		検索を行う。
		検索データはヘッダデータ同様、データ値1(TAB)データ値2(TAB)・・というように
		設定し、行の最後に(改行）を設定する。
		・Full-Scan検索
		・全件検索（裏面全件検索）
		・Index検索
		の3パターンの検索方法ごとに処理を実装する。
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	c_SHMemory = c_SHMBase + t_TblInfo.TblDataPos ;
	long k = 0 ;
	int  TblBufSize = GG_SHM0001_MaxRetDataLen ;

	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	 	Full-Scan検索、および全件検索の場合
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
		
	if ( strcmp ( AcPt[1] , GG_SHM0001_AllData ) == 0 ||
		 strcmp ( AcPt[1] , GG_SHM0001_AllDtBack ) == 0 ||
		 strcmp ( AcPt[3] , PARM_FULLSCAN ) == 0 ) {
		for ( int i = 0 ; i < t_TblInfo.TblDataLen ; ) {
			/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
				通常のデータ検索の場合 （全件、逆面全面検索以外）
				データ返却領域に検索条件にマッチしたデータを格納する。
				共有メモリデータは、各カラムとも固定長で管理されているため、業務ＡＰから
				業務ＡＰから受け取った検索パラメータ値を共有メモリデータのカラム長にスペ
				ースパディングして比較を行う。(sprintfを使用)
				比較結合識別子（Ketugo）は、Ketugo[0]に従って比較の繰り返しを行う。
				比較結合識別子が「or」の場合、比較条件が一つでもマッチしたら返却領域に設定
				を行う。「and」の場合、全ての比較条件がマッチするまで、比較を行う。
				Ketugo[j]に設定されていなければ、「j-1」の比較でマッチング終了。
				検索対象データは、共有メモリ上の固定長データのカラムの区切り文字として、
				TAB文字を追加設定して、設定する。
			_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

			int match = 1 ;						// 0 : データmatch 、 1 : データunmatch

			if ( strcmp ( AcPt[1] , GG_SHM0001_AllData ) != 0 &&
				 strcmp ( AcPt[1] , GG_SHM0001_AllDtBack ) != 0 ) {
				for ( int j = 0 ; Left[j][0] != '\0' ; j ++ ) {
					int comLeftLen ;
					// パディング値（0x1f）の削除
					for ( comLeftLen=Leftlen[j]-1 ; comLeftLen>=0 ; comLeftLen-- ) {
						if ( (unsigned char)(c_SHMemory+i+Leftpos[j]+comLeftLen)[0] != (unsigned char)SP_REP ) {
							break ;
						}
					}
					comLeftLen++ ;
					long hkk = 0 ;

					/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
					 	文字列比較の場合 / Left_Nid[j] == 0
					_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
		
					if ( Left_Nid[j] == 0 ) {
						// 業務ＡＰのパラメータ文字数が共有メモリデータの文字数より大きい場合
						if ( strlen(Right[j]) > comLeftLen ) {
							// 業務ＡＰのパラメータ文字をスペースパディング
							int RightLen = strlen(Right[j])-1 ;
							for (  ; RightLen >= comLeftLen ; RightLen-- ) {
								if ( Right[j][RightLen] != ' ' ) break ;
							}
							RightLen++ ;
							Right[j][RightLen] = '\0' ;
							// 共有メモリデータをローカル領域に設定
							char *shmChar = (char *) malloc ( comLeftLen + 1 ) ;
							strncpy ( shmChar , c_SHMemory + i + Leftpos[j] , comLeftLen ) ;
							shmChar [ comLeftLen ] = '\0' ;
							// 業務ＡＰパラメータと共有メモリデータの比較
							hkk = (long)strcmp ( shmChar , Right[j] ) ;
							free ( shmChar ) ;
						} else
						// 業務ＡＰのパラメータ文字数が共有メモリデータの文字数より小さい場合
						if ( strlen(Right[j]) < comLeftLen ) {
							// 共有メモリデータをローカル領域に設定
							char *shmChar = (char *) malloc ( comLeftLen + 1 ) ;
							strncpy ( shmChar , c_SHMemory + i + Leftpos[j] , comLeftLen ) ;
							shmChar [ comLeftLen ] = '\0' ;
							// 共有メモリデータの文字をスペースパディング
							comLeftLen-- ;
							for (  ; comLeftLen >= strlen(Right[j]) ; comLeftLen-- ) {
								if ( shmChar[comLeftLen] != ' ' ) break ;
							}
							comLeftLen++ ;
							shmChar[comLeftLen] = '\0' ;
							// 業務ＡＰパラメータと共有メモリデータの比較
							hkk = (long)strcmp ( shmChar , Right[j] ) ;
							free ( shmChar ) ;
						// 業務ＡＰのパラメータ文字数が共有メモリデータの文字数が同じ場合
						} else {
							// 業務ＡＰパラメータと共有メモリデータの比較
							hkk = (long)memcmp ( c_SHMemory + i + Leftpos[j] , Right[j] , comLeftLen ) ;
						}

					/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
					 	数値比較の場合 / Left_Nid[j] == 1
					_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
					} else {
						// 共有メモリデータをローカル領域に設定
						char *shmChar = (char *) malloc ( comLeftLen + 1 ) ;
						strncpy ( shmChar , c_SHMemory + i + Leftpos[j] , comLeftLen ) ;
						shmChar [ comLeftLen ] = '\0' ;
						// 共有メモリデータ値を「long double型」に変換
						// 変換仕様は、標準関数strtoldに従う
						long double Left_Num ;
						int rc = to_long_double ( shmChar , &Left_Num ) ;
						// 比較結果をhkk（long型）に設定
						if ( Left_Num == Right_Num[j] ) {
							hkk = 0 ;
						} else if ( Left_Num > Right_Num[j] ) {
							hkk = 1 ;
						} else if ( Left_Num < Right_Num[j] ) {
							hkk = -1 ;
						}
						free ( shmChar ) ;
					}
					/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
					 	アクセスパターンの検索方法と比較結果が一致した場合
					_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
					if ( ( strcmp ( Hikaku[j] , "="  ) == 0 && hkk == 0 ) ||
						 ( strcmp ( Hikaku[j] , "<"  ) == 0 && hkk  < 0 ) ||
						 ( strcmp ( Hikaku[j] , "<=" ) == 0 && hkk <= 0 ) ||
						 ( strcmp ( Hikaku[j] , ">"  ) == 0 && hkk  > 0 ) ||
						 ( strcmp ( Hikaku[j] , ">=" ) == 0 && hkk >= 0 ) ||
						 ( strcmp ( Hikaku[j] , "!=" ) == 0 && hkk != 0 ) ){
						// 検索方法の結合子が「or」または検索が完了した場合（検索対象データとして確定）
						if ( strcmp ( Ketugo[0] , "or" ) == 0 || Ketugo[j][0] == '\0' ) {
							match = 0 ;
							break ;
						} else if ( strcmp ( Ketugo[0] , "and" ) == 0 ) {
							continue ;
						} else {
//							printf ( "比較演算子不正!! [%s]\n" , Ketugo[j] ) ;
							getLocalTimeString ( szAccessDate , sizeof(szAccessDate)
								, "%Y/%m/%d %H:%M:%S.%U" ) ;
							GG_MsgOut ( g_szLogFilePath , 0
								, "(%05d) **** ( %s ) **** 比較演算子不正!! Ketugo[%s]"
								, ThreadId , szAccessDate ,Ketugo[j]
							) ;
							return ( -5 ) ;
						}
					// 比較方法と比較結果が不一致の場合
					} else {
						// 比較方法の結合子が「or」で、検索が完了していない場合は、次のデータ比較を継続
						if ( strcmp ( Ketugo[0] , "or" ) == 0 && Ketugo[j][0] != '\0' ) continue ;
						// 上記以外は、当該データは検索対象外に決定
						match = 1 ;
						break ;
					}
				}
			} else
			// 全件、または逆面全面検索の場合、条件に関わらず返却領域にデータ設定
			if ( strcmp ( AcPt[1] , GG_SHM0001_AllData ) == 0 ||
						strcmp ( AcPt[1] , GG_SHM0001_AllDtBack ) == 0 ) {
				match = 0 ;
			}
			if ( match == 0 ) {
				// 共有メモリデータを返却領域にコピー
				int ColSzWrok = 0 ;
				for ( int h = 0 ; h < t_TblInfo.TblColNum ; h ++ ) {
					memcpy ( TableData , c_SHMemory + i + ColSzWrok , t_ColumnDef[h].ColumnSize ) ;
					TableData [ t_ColumnDef[h].ColumnSize ] = '\t' ;
					TableData = TableData + t_ColumnDef[h].ColumnSize + 1 ;
					ColSzWrok = ColSzWrok + t_ColumnDef[h].ColumnSize ;
				}
				TableData -- ;
				TableData [0] = '\n' ;
				TableData [1] = '\0' ;
				TableData = TableData + 1 ;
				k ++ ;
				/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
					返却データのサイズが、TableDataBase で確保した返却領域の1/2を越えた場合、
					返却データのサイズを2倍に拡張（malloc→memcpy→freeにより実施）
				_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
				if ( TblBufSize / 2 < (size_t)TableData - (size_t)TableDataBase ) {
					TblBufSize = TblBufSize * 2 ;
					char *TableDataTmp = (char *) malloc ( TblBufSize ) ;
					if ( TableDataTmp != NULL ) {
						memcpy ( TableDataTmp , TableDataBase , (size_t)TableData - (size_t)TableDataBase ) ;
						TableData = TableDataTmp + ( (size_t)TableData-(size_t)TableDataBase ) ;
						free ( TableDataBase ) ;
						TableDataBase = TableDataTmp ;
						startLock(0) ;								// 排他制御（mutex:0）
						for ( int m = 0 ; m < ThrdNum ; m++ ) {
							if ( s_Thrd[m].tid == syscall(SYS_gettid) ) {
								s_Thrd[m].arrOut = TableDataBase ;
								break ;
							}
						}
						endLock(0) ;								// 排他制御（mutex:0）
					} else {
						getLocalTimeString ( szAccessDate , sizeof(szAccessDate)
							, "%Y/%m/%d %H:%M:%S.%U" ) ;
						GG_MsgOut ( g_szLogFilePath , 0
							, "(%05d) **** ( %s ) **** realloc エラー発生!! DATA[%-100s]"
							, ThreadId , szAccessDate ,TableDataBase
						) ;
						return ( -6 ) ;
					}
				}
			}
			i = i + TblDataLen ;
		}
	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	 	Index検索の場合
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
	} else {
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate) , "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 9
			, "(%05d) **** ( %s ) **** Index 検索開始"
			, ThreadId , szAccessDate
		) ;
		int  IndexLeftpos	[GG_SHM0001_MaxCond] ;
		// インデックス項目と比較データ位置の抽出
		// インデックス項目は、比較方法が「=」でかつ、文字列比較の場合が該当
		for ( int j = 0 , p = 0 ,q = 0 ; Left[j][0] != '\0' ; j ++ ) {
			if ( strcmp ( Hikaku[j] , "=" ) == 0 ) {
				char *Left_Num_Pos = strchr ( Left[j] , '@' ) ;
				if ( Left_Num_Pos == NULL ) {
					Index_Pos[p] = j ;
					Index_Pos[p+1] = -1 ;
					IndexLeftpos[p] = q ;
					getLocalTimeString ( szAccessDate , sizeof(szAccessDate) , "%Y/%m/%d %H:%M:%S.%U" ) ;
					GG_MsgOut ( g_szLogFilePath , 9
						, "(%05d) **** ( %s ) **** Left[%d]=%s : (%d,%d)"
						, ThreadId , szAccessDate , j , Left[j] , Index_Pos[p] , IndexLeftpos[p]
					) ;
					p ++ ;
					q += t_ColumnDef[j].ColumnSize ;
				}
			}
		}
		long stPos = atol ( AcPt[3] ) ;						// インデックス開始位置（共有メモリ相対位置）
		long recLn = atol ( AcPt[4] ) ;						// インデックスレコード長
		long rowNm = atol ( AcPt[5] ) ;						// インデックス件数
		long st = 0 ;										// インデックス検索レコード開始位置
		long ed = rowNm - 1 ;								// インデックス検索レコード終了位置
		long search = stPos + ( st + ed ) / 2 * recLn ;		// 検索行（バイナリサーチ）
		long stMatch = -1 ;									// マッチング最上位行
		long edMatch = -1 ;									// マッチング最下位行
		long hkk = 0 ;										// 比較結果
		for ( int j = 0 , p = 0 ;; ) {
			j = Index_Pos[p] ;								// インデックス比較項目相対番号
			// パディング値（0x1f）の削除
			int comLeftLen ;
			for ( comLeftLen=Leftlen[j]-1 ; comLeftLen>=0 ; comLeftLen-- ) {
				if ( (unsigned char)(c_SHMBase + search + IndexLeftpos[p] + comLeftLen)[0] != (unsigned char)SP_REP ) {
					break ;
				}
			}
		 	comLeftLen ++ ;
			
			// 業務ＡＰのパラメータ文字数が共有メモリデータの文字数より大きい場合
			if ( strlen(Right[j]) > comLeftLen ) {
				// 業務ＡＰのパラメータ文字をスペースパディング
				int RightLen = strlen(Right[j])-1 ;
				for (  ; RightLen >= comLeftLen ; RightLen-- ) {
					if ( Right[j][RightLen] != ' ' ) break ;
				}
				RightLen++ ;
				Right[j][RightLen] = '\0' ;
				// 共有メモリデータをローカル領域に設定
				char *shmChar = (char *) malloc ( comLeftLen + 1 ) ;
				strncpy ( shmChar , c_SHMBase + search + IndexLeftpos[p] , comLeftLen ) ;
				shmChar [ comLeftLen ] = '\0' ;
				// 業務ＡＰパラメータと共有メモリデータの比較
				hkk = (long)strcmp ( shmChar , Right[j] ) ;
				/* ログ出力ロジック */
				if ( LogLevel >= 9 ) {
					getLocalTimeString ( szAccessDate , sizeof(szAccessDate) , "%Y/%m/%d %H:%M:%S.%U" ) ;
					GG_MsgOut ( g_szLogFilePath , 9
						, "(%05d) **** ( %s ) **** Index比較 行番号=%d 列番号=%d パラメータ=[%s] メモリ=[%s]"
						, ThreadId , szAccessDate ,search , j , Right[j] , shmChar
					) ;
					GG_MsgOut ( g_szLogFilePath , 9
						, "(%05d) **** ( %s ) **** stPos=%d st=%d ed=%d recLn=%d"
						, ThreadId , szAccessDate , stPos , st , ed , recLn
					) ;
				}
				free ( shmChar ) ;
			// 業務ＡＰのパラメータ文字数が共有メモリデータの文字数より小さい場合
			} else if ( strlen(Right[j]) < comLeftLen ) {
				// 共有メモリデータをローカル領域に設定
				char *shmChar = (char *) malloc ( comLeftLen + 1 ) ;
				strncpy ( shmChar , c_SHMBase + search + IndexLeftpos[p] , comLeftLen ) ;
				shmChar [ comLeftLen ] = '\0' ;
				// 共有メモリデータの文字をスペースパディング
				comLeftLen-- ;
				for (  ; comLeftLen >= strlen(Right[j]) ; comLeftLen-- ) {
					if ( shmChar[comLeftLen] != ' ' ) break ;
				}
				comLeftLen++ ;
				shmChar[comLeftLen] = '\0' ;
				// 業務ＡＰパラメータと共有メモリデータの比較
				hkk = (long)strcmp ( shmChar , Right[j] ) ;
				/* ログ出力ロジック */
				if ( LogLevel >= 9 ) {
					getLocalTimeString ( szAccessDate , sizeof(szAccessDate) , "%Y/%m/%d %H:%M:%S.%U" ) ;
					GG_MsgOut ( g_szLogFilePath , 9
						, "(%05d) **** ( %s ) **** Index比較 行番号=%d 列番号=%d パラメータ=[%s] メモリ=[%s]"
						, ThreadId , szAccessDate ,search , j , Right[j] , shmChar
					) ;
					GG_MsgOut ( g_szLogFilePath , 9
						, "(%05d) **** ( %s ) **** stPos=%d st=%d ed=%d recLn=%d"
						, ThreadId , szAccessDate , stPos , st , ed , recLn
					) ;
				}
				free ( shmChar ) ;
			} else {
				// 業務ＡＰパラメータと共有メモリデータの比較
				hkk = (long)memcmp ( c_SHMBase + search + IndexLeftpos[p] , Right[j] , comLeftLen ) ;
				/* ログ出力ロジック */
				if ( LogLevel >= 9 ) {
					char *shmChar = (char *) malloc ( comLeftLen + 1 ) ;
					strncpy ( shmChar , c_SHMBase + search + IndexLeftpos[p] , comLeftLen ) ;
					shmChar[comLeftLen] = '\0' ;
					getLocalTimeString ( szAccessDate , sizeof(szAccessDate) , "%Y/%m/%d %H:%M:%S.%U" ) ;
					GG_MsgOut ( g_szLogFilePath , 9
						, "(%05d) **** ( %s ) **** Index比較 行番号=%d 列番号=%d パラメータ=[%s] メモリ=[%s]"
						, ThreadId , szAccessDate ,search , j , Right[j] , shmChar
					) ;
					GG_MsgOut ( g_szLogFilePath , 9
						, "(%05d) **** ( %s ) **** stPos=%d st=%d ed=%d recLn=%d"
						, ThreadId , szAccessDate , stPos , st , ed , recLn
					) ;
					free ( shmChar ) ;
				}
			}
			/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
			 	バイナリサーチロジック1
				1. 共有メモリデータ > 業務ＡＰのパラメータ
					1.1 検索範囲が1行になったら、break
					1.2 マッチング最上位行が決まっていなければ、検索範囲最下位行を[比較行-1]に設定
					1.3 マッチング最上位行が決まっていれば、検索範囲最下位行を[比較行-1]に設定
			_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
			if ( hkk > 0 ) {
				if ( st == ed ) break ;
				if ( stMatch == -1 ) {
					ed = ( st + ed ) / 2 - 1 ;
					search = stPos + ( st + ed ) / 2 * recLn ;
				} else {
					ed = (st+ed)/2 + (st+ed)%2 - 1 ;
					search = stPos + ( (st+ed)/2 + (st+ed)%2 ) * recLn ;
				}
				p = 0 ;
				continue ;
			} else
			/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
			 	バイナリサーチロジック2
				2. 共有メモリデータ < 業務ＡＰのパラメータ
					2.1 検索範囲が1行になったら、break
					2.2 マッチング最上位行が決まっていなければ、検索範囲最上位行を[比較行+1]に設定
					2.3 マッチング最上位行が決まっていれば、検索範囲最上位行を[比較行+1]に設定
			_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
			if ( hkk < 0 ) {
				if ( st == ed ) break ;
				if ( stMatch == -1 ) {
					st = ( st + ed ) / 2 + 1 ;
					search = stPos + ( st + ed ) / 2 * recLn ;
				} else {
					st = (st+ed)/2 + (st+ed)%2 + 1 ;
					search = stPos + ( (st+ed)/2 + (st+ed)%2 ) * recLn ;
				}
				p = 0 ;
				continue ;
			} else
			/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
			 	バイナリサーチロジック3
				3. 共有メモリデータ = 業務ＡＰのパラメータ
					3.1 全Index項目の比較が完了したら
						3.1.1 検索行の絞り込みが未完で、マッチング最上位行が未決定の場合
							最上位行を再検索
						3.1.2 検索行の絞り込みが完了で、マッチング最上位行が未決定の場合
							マッチング最上位行を決定して、最下位行の検索を実施
						3.1.3 検索行の絞り込みが未完で、マッチング最上位行が決定済の場合
							最下位行を再検索
						3.1.4 検索行の絞り込みが完了で、マッチング最上位行が決定済の場合
							マッチング最下位行を決定して、break
					3.2 全Index項目の比較が完了いなければ、次項目の比較を実施
			_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
			if ( hkk == 0 ) {
				if ( Index_Pos[p+1] == -1 ) {
					if ( st != ed && stMatch == -1 ) {
						ed = ( st + ed ) / 2 ;
						search = stPos + ( st + ed ) / 2 * recLn ;
					} else
					if ( st == ed && stMatch == -1 ) {
						stMatch = st ;
						ed = rowNm - 1 ;
						search = stPos + ( (st+ed)/2 + (st+ed)%2 ) * recLn ;
					} else
					if ( st != ed && stMatch != -1 ) {
						st = ( st + ed ) / 2 + ( st + ed ) % 2 ;
						search = stPos + ( (st+ed)/2 + (st+ed)%2 ) * recLn ;
					} else
					if ( st == ed && stMatch != -1 ) {
						edMatch = st ;
						break ;
					}
					p = 0 ;
				} else {
					p ++ ;
				}
			}
		}
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate) , "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 9
			, "(%05d) **** ( %s ) **** 開始行=%d 終了行=%d 検索対象行数=%d"
			, ThreadId , szAccessDate ,stMatch,edMatch,edMatch-stMatch+1
		) ;
		// インデックス検索でマッチングデータが発生した場合
		if ( hkk == 0 ) {
			// 検索開始行から終了行をFull-Scan検索
			for ( int p = stMatch ; p <= edMatch ; p++ ) {
				// インデックス検索行を決定
				search = stPos + p * recLn ;
				// 共有メモリ上の検索位置を決定。インデックス各行の右12桁に共有メモリ相対位置が設定されている
				char cTblRecPos[13] ;
				strncpy ( cTblRecPos , c_SHMBase + search + recLn - strlen(PARM_FULLSCAN) , strlen(PARM_FULLSCAN) ) ;
				long lTblRecPos = atol ( cTblRecPos ) ;
				char *w_SHMemory = c_SHMemory + lTblRecPos ;

				int match = 0 ;						// 0 : データmatch 、 1 : データunmatch

				// このfor内に入ったら、Index以外の比較項目があったということ
				for ( int j = 0 ; Left[j][0] != '\0' ; j ++ ) {

					char *Left_Num_Pos = strchr ( Left[j] , '@' ) ;
					if ( strcmp ( Hikaku[j] , "="  ) == 0 && Left_Num_Pos == NULL ) continue ;

					match = 1 ;						// Index以外の比較項目があれば、初期状態は「データunmatch」

					// パディング値（0x1f）の削除
					int comLeftLen ;
					for ( comLeftLen=Leftlen[j]-1 ; comLeftLen>=0 ; comLeftLen-- ) {
						if ( (unsigned char)(w_SHMemory+Leftpos[j]+comLeftLen)[0] != (unsigned char)SP_REP ) {
							break ;
						}
					}
					comLeftLen++ ;

					/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
					 	文字比較の場合 / Left_Nid[j] == 0
					_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
					if ( Left_Nid[j] == 0 ) {
						// 業務ＡＰのパラメータ文字数が共有メモリデータの文字数より大きい場合
						if ( strlen(Right[j]) > comLeftLen ) {
							// 業務ＡＰのパラメータ文字をスペースパディング
							int RightLen = strlen(Right[j])-1 ;
							for (  ; RightLen >= comLeftLen ; RightLen-- ) {
								if ( Right[j][RightLen] != ' ' ) break ;
							}
							RightLen++ ;
							Right[j][RightLen] = '\0' ;
							// 共有メモリデータをローカル領域に設定
							char *shmChar = (char *) malloc ( comLeftLen + 1 ) ;
							strncpy ( shmChar , w_SHMemory + Leftpos[j] , comLeftLen ) ;
							shmChar [ comLeftLen ] = '\0' ;
							// 業務ＡＰパラメータと共有メモリデータの比較
							hkk = (long)strcmp ( shmChar , Right[j] ) ;
							free ( shmChar ) ;
						} else
						// 業務ＡＰのパラメータ文字数が共有メモリデータの文字数より小さい場合
						if ( strlen(Right[j]) < comLeftLen ) {
							// 共有メモリデータをローカル領域に設定
							char *shmChar = (char *) malloc ( comLeftLen + 1 ) ;
							strncpy ( shmChar , w_SHMemory + Leftpos[j] , comLeftLen ) ;
							shmChar [ comLeftLen ] = '\0' ;
							// 共有メモリデータの文字をスペースパディング
							comLeftLen-- ;
							for (  ; comLeftLen >= strlen(Right[j]) ; comLeftLen-- ) {
								if ( shmChar[comLeftLen] != ' ' ) break ;
							}
							comLeftLen++ ;
							shmChar[comLeftLen] = '\0' ;
							// 業務ＡＰパラメータと共有メモリデータの比較
							hkk = (long)strcmp ( shmChar , Right[j] ) ;
							free ( shmChar ) ;
						// 業務ＡＰのパラメータ文字数が共有メモリデータの文字数が同じ場合
						} else {
							// 業務ＡＰパラメータと共有メモリデータの比較
							hkk = (long)memcmp ( w_SHMemory + Leftpos[j] , Right[j] , comLeftLen ) ;
						}
					/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
					 	数値比較の場合 / Left_Nid[j] == 1
					_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
					} else {
						// 共有メモリデータをローカル領域に設定
						char *shmChar = (char *) malloc ( comLeftLen + 1 ) ;
						strncpy ( shmChar , w_SHMemory + Leftpos[j] , comLeftLen ) ;
						shmChar [ comLeftLen ] = '\0' ;
						// 共有メモリデータ値を「long double型」に変換
						// 変換仕様は、標準関数strtoldに従う
						long double Left_Num ;
						int rc = to_long_double ( shmChar , &Left_Num ) ;
						// 比較結果をhkk（long型）に設定
						if ( Left_Num == Right_Num[j] ) {
							hkk = 0 ;
						} else if ( Left_Num > Right_Num[j] ) {
							hkk = 1 ;
						} else if ( Left_Num < Right_Num[j] ) {
							hkk = -1 ;
						}
						free ( shmChar ) ;
					}
					/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
					 	アクセスパターンの検索方法と比較結果が一致した場合
					_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
					if ( ( strcmp ( Hikaku[j] , "="  ) == 0 && hkk == 0 ) ||
						 ( strcmp ( Hikaku[j] , "<"  ) == 0 && hkk  < 0 ) ||
						 ( strcmp ( Hikaku[j] , "<=" ) == 0 && hkk <= 0 ) ||
						 ( strcmp ( Hikaku[j] , ">"  ) == 0 && hkk  > 0 ) ||
						 ( strcmp ( Hikaku[j] , ">=" ) == 0 && hkk >= 0 ) ||
						 ( strcmp ( Hikaku[j] , "!=" ) == 0 && hkk != 0 ) ){
						// 検索が完了した場合（検索対象データとして確定）（「or」のケースはない）
						if ( strcmp ( Ketugo[0] , "or" ) == 0 || Ketugo[j][0] == '\0' ) {
							match = 0 ;
							break ;
						} else
						// 比較が未完了の場合（Ketugo[j][0] != '\0'）は、データ比較を処理継続
						if ( strcmp ( Ketugo[0] , "and" ) == 0 ) {
							match = 0 ;
							continue ;
						// 論理エラーここに入る場合はデータ破壊の可能性あり
						} else {
//							printf ( "比較演算子不正!! [%s]\n" , Ketugo[j] ) ;
							getLocalTimeString ( szAccessDate , sizeof(szAccessDate)
								, "%Y/%m/%d %H:%M:%S.%U" ) ;
							GG_MsgOut ( g_szLogFilePath , 0
								, "(%05d) **** ( %s ) **** 比較演算子不正!! Ketugo[%s]"
								, ThreadId , szAccessDate ,Ketugo[j]
							) ;
							return ( -5 ) ;
						}
					// 比較方法と比較結果が不一致の場合
					} else {
						// 比較方法の結合子が「or」で、検索が完了していない場合は、次のデータ比較を継続
						if ( strcmp ( Ketugo[0] , "or" ) == 0 && Ketugo[j][0] != '\0' ) continue ;
						// 上記以外は、当該データは検索対象外に決定
						match = 1 ;
						break ;
					}
				}
				if ( match == 0 ) {
					int ColSzWrok = 0 ;
					// 共有メモリデータを返却領域にコピー
					for ( int h = 0 ; h < t_TblInfo.TblColNum ; h ++ ) {
						memcpy ( TableData , w_SHMemory + ColSzWrok , t_ColumnDef[h].ColumnSize ) ;
						TableData [ t_ColumnDef[h].ColumnSize ] = '\t' ;
						TableData = TableData + t_ColumnDef[h].ColumnSize + 1 ;
						ColSzWrok = ColSzWrok + t_ColumnDef[h].ColumnSize ;
					}
					TableData -- ;
					TableData [0] = '\n' ;
					TableData [1] = '\0' ;
					TableData = TableData + 1 ;
					k ++ ;
					/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
						返却データのサイズが、TableDataBase で確保した返却領域の1/2を越えた場合、
						返却データのサイズを2倍に拡張（malloc→memcpy→freeにより実施）
					_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
					// 返却データのサイズを2倍に拡張
					if ( TblBufSize / 2 < (size_t)TableData - (size_t)TableDataBase ) {
						TblBufSize = TblBufSize * 2 ;
						char *TableDataTmp = (char *) malloc ( TblBufSize ) ;
						if ( TableDataTmp != NULL ) {
							memcpy ( TableDataTmp , TableDataBase , (size_t)TableData - (size_t)TableDataBase ) ;
							TableData = TableDataTmp + ( (size_t)TableData-(size_t)TableDataBase ) ;
							free ( TableDataBase ) ;
							TableDataBase = TableDataTmp ;
							startLock(0) ;								// 排他制御（mutex:0）
							for ( int m = 0 ; m < ThrdNum ; m++ ) {
								if ( s_Thrd[m].tid == syscall(SYS_gettid) ) {
									s_Thrd[m].arrOut = TableDataBase ;
									break ;
								}
							}
							endLock(0) ;								// 排他制御（mutex:0）
						} else {
							getLocalTimeString ( szAccessDate , sizeof(szAccessDate)
								, "%Y/%m/%d %H:%M:%S.%U" ) ;
							GG_MsgOut ( g_szLogFilePath , 0
								, "(%05d) **** ( %s ) **** realloc エラー発生!! DATA[%-100s]"
								, ThreadId , szAccessDate ,TableDataBase
							) ;
							return ( -6 ) ;
						}
					}
				}
			}
		}
		getLocalTimeString ( szAccessDate , sizeof(szAccessDate) , "%Y/%m/%d %H:%M:%S.%U" ) ;
		GG_MsgOut ( g_szLogFilePath , 9
			, "(%05d) **** ( %s ) **** Index 検索終了"
			, ThreadId , szAccessDate
		) ;
	}
		
	/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		ShmStaticTable クラスに return
		データ返却領域にデータが１件以上設定された場合は、ShmStaticTable クラスに返却
		データ長を返却。
		注）ShmStaticTable クラスは、本return値分のbyte配列を用意して、データ取得用の
			関数（GG_SHM0011getdata）を呼び出す。
		データ返却領域にデータが設定されない場合は、0 を設定してreturn
	_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

	getLocalTimeString ( szAccessDate , sizeof(szAccessDate) , "%Y/%m/%d %H:%M:%S.%U" ) ;
	if ( k > 0 ) {
		//	ログ出力：0x1fコードを削除してログ出力（ログが見えなくなるため）
		if ( LogLevel > 0 ) {
			char *logBuff = (char *) malloc ( strlen(TableDataBase) + 1 ) ;
			char *p ;
			strcpy ( logBuff , TableDataBase ) ;
			while ( ( p = strchr (logBuff , SP_REP) ) != NULL ) {
				*p = ' ' ;
			}
			GG_MsgOut ( g_szLogFilePath , 1
				, "(%05d) **** ( %s ) **** [%04d] 件\n%s"
				, ThreadId , szAccessDate , k , logBuff
			) ;
			free ( (char *) logBuff ) ;
		}
		// 検索データの返却
		return ( strlen(TableDataBase) ) ;
	} else {
		char logOutPrm [ 1024 ] ;
		logOutPrm [ 0 ] = '\0' ;
		for ( int i=1 ; i<=prmNum ; i++ ) {
			strcat ( logOutPrm , "[" ) ;
			strcat ( logOutPrm , Prm [ i ] ) ;
			strcat ( logOutPrm , "] " ) ;
		}
		// ログ出力：該当データはありません
		GG_MsgOut ( g_szLogFilePath , 1
			, "(%05d) **** ( %s ) **** 該当データはありません !!"
			, ThreadId , szAccessDate
		) ;
		GG_MsgOut ( g_szLogFilePath , 1
			, "(%05d) **** ( %s ) **** inData=%s"
			, ThreadId , szAccessDate , logOutPrm
		) ;
		// 検索データはなし
		return ( 0 ) ;
	}
}

/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	文字データ→long double型に変換
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
int to_long_double ( char *in_str , long double *out_ld )
{
	char *err ;
	*out_ld = strtold ( in_str , &err ) ;
	if ( *err == '\0' ) {
		return (0) ;
	} else {
		return (-1);
	}
}

/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	文字データが数値で構成されているかチェック
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
int isNumber( char *str )
{
	int ret = 1;
	char ch ;
	int len = strlen( str );
	
	for ( int i = 0 ; i < len ; i ++ ) {
		ch = str [ i ];
		if ( i == 0 && len > 1 && (ch == '+' || ch == '-') ) {
			// 先頭の1文字目が符号でかつ符号のみの文字列でない場合
			continue;
		}
		if ( isdigit( (unsigned char)ch ) == 0 ) {
			ret = 0;
			break;
		}
	}
	return ( ret ) ;
}

#ifdef _NONSTOP
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
	NonStop用syscall
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
int syscall(int id)
{
	pthread_t	tid;
	tid = pthread_self();

	// tidの内容
	// tid.field1=134263616
	// tid.field2=4   ←  スレッドからアクセスされた場合、field2が増加する。
	// tid.field3=4
	
	return (tid).field2;
}
#endif
