/* vim: set tabstop=4 paste nocindent noautoindent ff=unix: */

/**
汎用ツールプログラム  tools.c

						'05 10/10

ヘッダ
	#include "tools.h"
 */

#include "tools.h"



int   DebugMode 	= OFF;
int   KanjiCode 	= EUC;
int	  UnitTestMode 	= OFF;

int   HostEndian 	= UNKNOWN_ENDIAN;


char  LocalIPNum[4] = {0x7f, 0x00, 0x00, 0x01};






///////////////////////////////////////////////////////////////////////////////////////////
// 

// case of C++, isNull() is inline

#ifndef CPLUSPLUS

int  isNull(void* p)
{
	if (p==NULL) return TRUE;

#ifdef WIN32
	if (p==WIN32_NULL) return TRUE;
#endif
#ifdef WIN64
	if (p==WIN64_NULL) return TRUE;
#endif
	return FALSE;
}

#endif






///////////////////////////////////////////////////////////////////////////////////////////
// 

/**
int is_little_endian()
int is_big_endian()

	エンディアンの動的チェック

*/
int is_little_endian(void)
{
	unsigned char x[] = {0x01, 0x00};

	if (HostEndian==LITTLE_ENDIAN) return TRUE;

	else if (HostEndian==BIG_ENDIAN) return FALSE;

	else {
		if (*((unsigned short*)x)==1) {
			HostEndian = LITTLE_ENDIAN;
			return TRUE;
		}
		else {
			HostEndian = BIG_ENDIAN;
			return FALSE;
		}
	}
}




int is_big_endian(void)
{
	unsigned char x[] = {0x00, 0x01};

	if (HostEndian==BIG_ENDIAN) return TRUE;

	else if (HostEndian==LITTLE_ENDIAN) return FALSE;

	else {
		if (*((unsigned short*)x)==1) {
			HostEndian = BIG_ENDIAN;
			return TRUE;
		}
		else {
			HostEndian = LITTLE_ENDIAN;
			return FALSE;
		}
	}
}



void  check_endian(void)
{
	if (HostEndian==UNKNOWN_ENDIAN) is_little_endian();
} 



//
//
//
double double_from_little_endian(void* ptr)
{
	double ret = *((double*)ptr);
	
	if (HostEndian==UNKNOWN_ENDIAN) check_endian();
	if (HostEndian==BIG_ENDIAN) reverse_str((uByte*)(&ret), 8);
	return ret;
}



float float_from_little_endian(void* ptr)
{
	float ret = *((float*)ptr);

	if (HostEndian==UNKNOWN_ENDIAN) check_endian();
	if (HostEndian==BIG_ENDIAN) reverse_str((uByte*)(&ret), 4);
	return ret;
}



int  int_from_little_endian(void* ptr)
{
	int ret = *((int*)ptr);

	if (HostEndian==UNKNOWN_ENDIAN) check_endian();
	if (HostEndian==BIG_ENDIAN) reverse_str((uByte*)(&ret), 4);
	return ret;
}


short short_from_little_endian(void* ptr)
{
	short ret = *((short*)ptr);

	if (HostEndian==UNKNOWN_ENDIAN) check_endian();
	if (HostEndian==BIG_ENDIAN) reverse_str((uByte*)(&ret), 2);
	return ret;
}



double double_from_big_endian(void* ptr)
{
	double ret = *((double*)ptr);

	if (HostEndian==UNKNOWN_ENDIAN) check_endian();
	if (HostEndian==LITTLE_ENDIAN) reverse_str((uByte*)(&ret), 8);
	return ret;
}



float float_from_big_endian(void* ptr)
{
	float ret = *((float*)ptr);

	if (HostEndian==UNKNOWN_ENDIAN) check_endian();
	if (HostEndian==LITTLE_ENDIAN) reverse_str((uByte*)(&ret), 4);
	return ret;
}



int  int_from_big_endian(void* ptr)
{
	int ret = *((int*)ptr);

	if (HostEndian==UNKNOWN_ENDIAN) check_endian();
	if (HostEndian==LITTLE_ENDIAN) reverse_str((uByte*)(&ret), 4);
	return ret;
}


short short_from_big_endian(void* ptr)
{
	short ret = *((short*)ptr);

	if (HostEndian==UNKNOWN_ENDIAN) check_endian();
	if (HostEndian==LITTLE_ENDIAN) reverse_str((uByte*)(&ret), 2);
	return ret;
}




///////////////////////////////////////////////////////////////////////////////////////////
// Time

char  _Local_Time[32];

char*  get_local_time(void)
{
    struct tm* pt;
    time_t tm;

    tm = time(NULL);
    pt = localtime(&tm);

	snprintf(_Local_Time, 20, "%04d:%02d:%02d %02d:%02d:%02d", pt->tm_year+1900, pt->tm_mon+1, pt->tm_mday, pt->tm_hour, pt->tm_min, pt->tm_sec);

	return _Local_Time;
}





///////////////////////////////////////////////////////////////////////////////////////////
/**
char*  get_line(char* str, int n)

	機能：strのバッファ内の n行目を取り出す．改行コードは削除される．
		  n は 1から数える．取り出した行を char型変数のバッファに格納
		  して返す．
		  返されたデータは free()する必要がある．

	引数：str -- 操作対象文の字列型データ(含む改行)
		  n   -- 行の指定．

	戻り値：指定された n行目の文字列．改行は含まない．
*/
char*  get_line(char* buf, int n)
{
	int i, j, pos, cnt;
	char* ret=NULL;

	if (buf==NULL) return NULL;

	for(i=0,j=0; j<n-1; j++) {
		while (buf[i]!=LF && buf[i]!=CR && buf[i]!='\0') i++;
		while (buf[i]==LF || buf[i]==CR) i++;
	}
	if (buf[i]=='\0') return  NULL;

	pos = i;
	while (buf[i]!=LF && buf[i]!=CR && buf[i]!='\0') i++;
	cnt = i - pos;

	if (cnt>=0) {  
		ret = (char*)malloc(cnt+1);
		if (ret==NULL) return NULL;

		for(i=0; i<cnt; i++) ret[i] = buf[pos+i];
		ret[cnt] = '\0';
	}
	return  ret;
}






/**
char*  awk(char* str, char cc, int n)

	機能：ccを区切り記号として, strのバッファ内の n番目の項目を返す．
		  n は 1から数える．
		  返されたデータは free()する必要がある．

	引数：str -- 操作対象文字列．
		  cc  -- 区切り文字．
		  n   -- 項目の指定．

	戻り値：指定された n番目の項目の文字列．

*/
char*  awk(char* buf, char cc, int n)
{
	int i, j, pos, cnt;
	char*  item = NULL;

	if (buf==NULL) return NULL;

	for(i=0,j=0; j<n-1; j++) {
		while (buf[i]!='\0' && buf[i]!=cc) i++;
		if (buf[i]==cc) i++;
	}
	if (buf[i]=='\0')  return NULL;

	pos = i;
	while (buf[i]!='\0' && buf[i]!=cc) i++;
	cnt = i - pos;

	item = (char*)malloc(cnt+1);
	if (item==NULL) return NULL;

	for (i=0; i<cnt; i++) item[i] = buf[pos+i];
	item[cnt] = '\0';

	return item;
}





/**
char*  cawk(char* str, char cc, int n)

	機能：ccを区切り記号として, strのバッファ内の n番目の項目を返す．
		  n は 1から数える．連続する cc(区切り)は一つの区切りとみなす．
		  返されたデータは free()する必要がある．

	引数：str -- 操作対象文字列．
		  cc  -- 区切り文字．
		  n   -- 項目の指定．

	戻り値：指定された n番目の項目の文字列．
*/
char*  cawk(char* buf, char cc, int n)
{
	int i, j, pos, cnt;
	char*  item = NULL;

	if (buf==NULL) return NULL;

	for(i=0,j=0; j<n-1; j++) {
		while (buf[i]!='\0' && buf[i]!=cc) i++;
		while (buf[i]!='\0' && buf[i]==cc) i++;
	}
	if (buf[i]=='\0') return NULL;

	pos = i;
	while (buf[i]!='\0' && buf[i]!=cc) i++;
	cnt = i - pos;

	item = (char*)malloc(cnt+1);
	if (item==NULL) return NULL;

	for (i=0; i<cnt; i++) item[i] = buf[pos+i];
	item[cnt] = '\0';

	return item;
}




/**
void   int_swap(int* p, int* s)

	機能：int型変数 pと s の内容を入れ替える．

	引数：*p, *s  -- 入れ替える整数 ．

	戻り値：なし．
*/
/*
void   int_swap(int* p, int* s)
{
	int swap;

	swap = *p;
	*p   = *s;
	*s   = swap;
}
*/




/**
int  bincmp(unsigned char* b1, unsigned char* b2, int n) 

	機能： バイナリデータ s1と s2 nByte比較する．

	戻り値： 一致する場合は 0，一致しない場合は 1 を返す．
			 strncmp()の戻り値の定義とは若干異なるので注意すること．
*/
int  bincmp(unsigned char* b1, unsigned char* b2, int n) 
{
	int i;

	if (b1==NULL || b2==NULL) return 1;

	for (i=0; i<n; i++) {
		if (b1[i]!=b2[i]) return 1;
	}

	return 0;
}






/**
int  strnrvscmp(const char* s1, const char* s2, int n) 

	機能： 文字列 s1と s2を後ろから n文字比較する．

	戻り値： 一致する場合は 0，一致しない場合は 1 を返す．
			 strncmp()の戻り値の定義とは異なるので注意すること．
*/
int  strnrvscmp(const char* s1, const char* s2, int n) 
{
	int j1, j2;
	
	if (s1==NULL || s2==NULL) return 1;

	j1 = (int)strlen(s1) - 1;
	j2 = (int)strlen(s2) - 1;

	while (n>0 && j1>=0 && j2>=0) {
		if (s1[j1--] != s2[j2--]) return 1;
		n--;
	}

	if (n==0) return 0;
	else	  return 1;
}




/**
int  strncaservscmp(const char* s1, const char* s2, int n) 

	機能： 文字列 s1と s2を後ろから n文字比較する．

	戻り値： 一致する場合は 0，一致しない場合は 1 を返す．
			 strncmp()の戻り値の定義とは異なるので注意すること．
*/
int  strncaservscmp(const char* s1, const char* s2, int n) 
{
	int j1, j2;
	
	if (s1==NULL || s2==NULL) return 1;

	j1 = (int)strlen(s1) - 1;
	j2 = (int)strlen(s2) - 1;

	while (n>0 && j1>=0 && j2>=0) {
		if (toupper(s1[j1--]) != toupper(s2[j2--])) return 1;
		n--;
	}

	if (n==0) return 0;
	else	  return 1;
}





/**
char*  strstrcase(const char* buf, const char* nd)

	機能：文字列 bufの中に文字列 ndがあるかどうかをチェックする．大文字小文字を区別しない．	
　　　　　大文字小文字を区別しない点を除けば，strstr() と同じ．
		  つまり strcasestr() と同じ．標準で strcasestr()が存在しない場合に使用．

*/
char*  strstrcase(const char* buf, const char* nd)
{
	char* pp;
	char* pb;
	char* pn;

	if (buf==NULL || nd==NULL) return NULL;

	pb = (char*)malloc(strlen(buf)+1);
	if (pb==NULL) return NULL;
	memcpy(pb, buf, (int)strlen(buf)+1);

	pn = (char*)malloc(strlen(nd)+1);
	if (pn==NULL) {
		free(pb);
		return NULL;
	}
	memcpy(pn, nd, (int)strlen(nd)+1);

	upper_string(pb);
	upper_string(pn);

	pp = strstr(pb, pn);
	if (pp!=NULL) {
		pp = (pp - pb) + (char*)buf;
	}
	free(pb);
	free(pn);

	return pp;
}





/**
int  ex_strncmp(const char* dat, const char* key, int len) 

	機能: 拡張文字比較

	引数: dat  -- 比べる文字列１．
		  key  -- 比べる文字列２．
		  len  -- 1以上: 一致させる長さ．
					  0: 完全一致．
					 -1: dat の長さに合わせる．
					 -2: key の長さに合わせる．
   
	戻り値: 一致した場合 TRUE．一致しなかった場合 FALSE．
*/
int  ex_strncmp(const char* dat, const char* key, int len) 
{
	if (dat==NULL || key==NULL) return FALSE;

	if (len==0) {
		if (!strcmp(dat, key)) return TRUE;
	}
	else if (len>0) {
		if (!strncmp(dat, key, len)) return TRUE;
	}
	else if (len<0) {
		int sz;
		if (len==-1) sz = (int)strlen(dat);
		else		 sz = (int)strlen(key);
		if (!strncmp(dat, key, sz)) return TRUE;
	}
	
	return FALSE;
}




/**
int  ex_strncasecmp(const char* dat, const char* key, int len) 

	機能: 拡張文字比較．ケース無視．

	引数: dat  -- 比べる文字列１．
		  key  -- 比べる文字列２．
		  len  -- 1以上: 一致させる長さ．
					  0: 完全一致．
					 -1: dat の長さに合わせる．
					 -2: key の長さに合わせる．
   
	戻り値: 一致した場合 TRUE．一致しなかった場合 FALSE．
*/
int  ex_strncasecmp(const char* dat, const char* key, int len) 
{
	if (dat==NULL || key==NULL) return FALSE;

	if (len==0) {
		if (!strcasecmp(dat, key)) return TRUE;
	}
	else if (len>0) {
		if (!strncasecmp(dat, key, len)) return TRUE;
	}
	else if (len<0) {
		int sz;
		if (len==-1) sz = (int)strlen(dat);
		else		 sz = (int)strlen(key);
		if (!strncasecmp(dat, key, sz)) return TRUE;
	}
	
	return FALSE;
}






/**
int  ex_strnrvscmp(const char* dat, const char* key, int len) 

	機能: 拡張文字比較

	引数: dat  -- 比べる文字列１．
		  key  -- 比べる文字列２．
		  len  -- 1以上: 一致させる長さ．
					  0: 完全一致．
					 -1: dat の長さに合わせる．
					 -2: key の長さに合わせる．
   
	戻り値: 一致した場合 TRUE．一致しなかった場合 FALSE．
*/
int  ex_strnrvscmp(const char* dat, const char* key, int len) 
{
	if (dat==NULL || key==NULL) return FALSE;

	if (len==0) {
		if (!strcmp(dat, key)) return TRUE;
	}
	else if (len>0) {
		if (!strnrvscmp(dat, key, len)) return TRUE;
	}
	else if (len<0) {
		int sz;
		if (len==-1) sz = (int)strlen(dat);
		else		 sz = (int)strlen(key);
		if (!strnrvscmp(dat, key, sz)) return TRUE;
	}
	
	return FALSE;
}




/**
int  ex_strncaervscmp(const char* dat, const char* key, int len) 

	機能: 拡張文字比較．ケース無視．

	引数: dat  -- 比べる文字列１．
		  key  -- 比べる文字列２．
		  len  -- 1以上: 一致させる長さ．
					  0: 完全一致．
					 -1: dat の長さに合わせる．
					 -2: key の長さに合わせる．
   
	戻り値: 一致した場合 TRUE．一致しなかった場合 FALSE．
*/
int  ex_strncaservscmp(const char* dat, const char* key, int len) 
{
	if (dat==NULL || key==NULL) return FALSE;

	if (len==0) {
		if (!strcasecmp(dat, key)) return TRUE;
	}
	else if (len>0) {
		if (!strncaservscmp(dat, key, len)) return TRUE;
	}
	else if (len<0) {
		int sz;
		if (len==-1) sz = (int)strlen(dat);
		else		 sz = (int)strlen(key);
		if (!strncaservscmp(dat, key, sz)) return TRUE;
	}
	
	return FALSE;
}









/**
char*  chomp(char* buf)

	機能：最初の改行コード以降を無視する．

	引数：buf -- 改行を無効にする文字列．
 */
char*  chomp(char* buf)
{
	int i, len;
	
	if (buf==NULL) return NULL;

	len = (int)strlen(buf);
	for (i=0; i<len; i++) {
		if (buf[i]==LF || buf[i]==CR) {
			buf[i] = '\0';
			return buf;
		}
	}
	return buf;
}





/**
char*  skip_char(char* pm, const char* check)

	機能：pmの指す文字列中で，check[]に格納された文字まで
		　ポインタをスキップさせる．
		  ただし，" ' 内に該当文字があっても無視する．

	引数：pm    -- 文字列の先頭ポインタ
		  check -- スキップする文字を格納した文字列．

	戻り値：check[]の中で最初に見つかった文字へのポインタ．
*/
char*  skip_char(char* pm, const char* check)
{
	int  n, sqf=0, dqf=0;

	n = (int)strlen(check);

	while (*pm!='\0') {
		if		(!sqf && *pm=='"')  dqf = 1 - dqf;
		else if (!dqf && *pm=='\'') sqf = 1 - sqf;

		else if (!sqf && !dqf) {
			int i;
			for (i=0; i<n; i++) {
				if (*pm==check[i]) return pm;
			}
		}
		pm++;
	}

	return NULL;
}







/**
char*  pack_head_tail_char(char* mesg, char cc)

	機能：文字列の先頭のcc(複数)，終わりのcc(複数)，TAB, CR, LF を削除
		  返されたデータは free()する必要がある．

	戻り値：変換後の文字列
*/
char*  pack_head_tail_char(char* mesg, char cc)
{
	int   sz;
	char* ps;
	char* pe;
	char* pp;

	if (mesg==NULL) return NULL;

	ps = mesg;
	while(*ps==cc || *ps==TAB || *ps==LF || *ps==CR) ps++;
	pe = ps;
	while(*pe!='\0') pe++;
	pe--;
	while(*pe==cc || *pe==TAB || *pe==LF || *pe==CR) pe--;

	sz = (int)(pe - ps) + 1;
	pp = (char*)malloc((size_t)(sz + 1));
	memcpy(pp, ps, sz);
	pp[sz] = '\0';

	return pp;		
}







/**
char*  pack_char(char* mesg, char cc)

	機能：文字列中及び，先頭のcc(複数)，終わりのcc(複数)，CR, LF を削除
		  タブは空白に変換．
		  メッセージ中の連続する cc は 1個に変換
		  返されたデータは free()する必要がある．

		  CR, LF も削除（無視）されるので注意．

	戻り値：変換後の文字列
*/
char*  pack_char(char* mesg, char cc)
{
	int i, j;
	int sf = OFF;	// 連続 cc 用のフラグ
	int ff = ON; 	// 先頭の cc を無視するためのフラグ
	char* pp;

	if (mesg==NULL) return NULL;

	pp = (char*)malloc(strlen(mesg)+1);
	if (pp==NULL) return NULL;

	i = j = 0;
	while(mesg[i]!='\0') {
		if (mesg[i]==TAB) mesg[i] = ' ';
		if (mesg[i]!=CR && mesg[i]!=LF) {		// CR LF を読み飛ばす．
			if (mesg[i]==cc) {
				if (sf==OFF) {
					sf = ON;
					if (ff==ON) ff = OFF;
					else  pp[j++] = mesg[i];
				}
			}
			else {
				sf = ff = OFF;
				pp[j++] = mesg[i];
			}
		}
		i++;
	}
	pp[j] = '\0';

	// 末尾の cc を削除
	i = (int)strlen(pp) - 1;
	while(i>=0) {
		if (pp[i]==cc) i--; 
		else  break;
	}
	pp[i+1] = '\0';

	return pp;
}





/**
char*  change_esc(char* mesg)

	機能：文字列中の CR, LF を \r, \n に変換する
		  返されたデータは free()する必要がある．

*/
char*  change_esc(char* mesg)
{
	int i, j;
	char* pp;

	if (mesg==NULL) return NULL;

	pp = (char*)malloc((strlen(mesg)+1)*2);
	if (pp==NULL) return NULL;

	i = j = 0;
	while(mesg[i]!='\0') {
		if (mesg[i]==CR) {
			pp[j++] = '\\';
			pp[j++] = 'r';
		}
		else if (mesg[i]==LF) {
			pp[j++] = '\\';
			pp[j++] = 'n';
		}
		else {
			pp[j++] = mesg[i];
		}
		i++;
	}
	pp[j] = '\0';
	
	return pp;
}







/**
char*  cut_str(char* buf, int ls, int le)

	機能：buf[ls] 〜 buf[le] を切り出してメモリに格納して返す．
		  返されたデータは free()する必要がある．

*/
char*  cut_str(char* buf, int ls, int le)
{
	int   i, len;
	char* ret;

	if (buf==NULL) return NULL;

	ls  = Max(ls, 0);
	le  = Min(le, (int)strlen((const char*)buf)); 
	len = le - ls + 1;
	if (len<=0) return NULL;

	ret = (char*)malloc(len+1);
	if (ret==NULL) return NULL;
	memset(ret, 0, len+1);

	for (i=0; i<len; i++) ret[i] = buf[i+ls];

	return ret;
}



				

/**
char*  dup_str(char* buf)

	機能：文字列 bufの複製を作り出す．
		  返されたデータは free()する必要がある．

*/
char*  dup_str(char* buf)
{
	int   len;
	char* ret;

	if (buf==NULL) return NULL;

	len = (int)strlen(buf);
	ret = (char*)malloc(len+1);
	if (ret==NULL) return NULL;
	memset(ret, 0, len+1);
	memcpy(ret, buf, len);

	return ret;
}




static char _ToSTR[LDATA];


/**
char*  ltostr(long int n)

	機能：long int n を文字列にして返す．free()する必要はない．

*/
char*  ltostr(long int n)
{
	memset(_ToSTR, 0, LDATA);
	snprintf(_ToSTR, LDATA-1, "%ld", n);
	return _ToSTR;
}



/**
char*  ultostr(unsigned long int n)

	機能：unsigned long int n を文字列にして返す．free()する必要はない．

*/
char*  ultostr(unsigned long int n)
{
	memset(_ToSTR, 0, LDATA);
	snprintf(_ToSTR, LDATA-1, "%ld", n);
	return _ToSTR;
}



/**
char*  ftostr(float n)

	機能：float n を文字列にして返す．free()する必要はない．

*/
char*  ftostr(float n)
{
	memset(_ToSTR, 0, LDATA);
	snprintf(_ToSTR, LDATA-1, "%f", n);
	return _ToSTR;
}




/**
int hexstr2i(const char* str)

	機能：16進数の文字列を整数に変換する．
		  空白は無視する．
		  空白以外の16進数でない文字が出現したら，そこで変換を止める

*/
int hexstr2i(const char* str)
{
	int i, ret = 0;
	if (str==NULL) return ret;

	int len = (int)strlen(str);

	for (i=0; i<len; i++) {
		if (str[i]>='0' && str[i]<='9') {
			ret = ret*16;
			ret += (int)(str[i] - '0');
		}
		else if (str[i]>='A' && str[i]<='F') {
			ret = ret*16;
			ret += (int)(str[i] - 'A') + 10;
		}
		else if (str[i]>='a' && str[i]<='f') {
			ret = ret*16;
			ret += (int)(str[i] - 'a') + 10;
		}
		else if (str[i]!=' ') {
			break;
		}
	}

	return ret;
}







/* ************************************************************************* */

#ifndef WIN32
/**
void  init_rand(void)

	機能：/dev/urandom から乱数の系列を初期化する
　　　　　/dev/urandom が読めない場合は，呼び出された時の時間(秒数)によって
		  乱数の系列を初期化する．

 */
void  init_rand(void)
{
	FILE* fp;
	unsigned int seed;

	fp = fopen("/dev/urandom", "rb");
	if (fp==NULL) {
		srand(time(NULL));
		return;
	}
	fread(&seed, sizeof(unsigned int), 1, fp);
	fclose(fp);

	srand(seed);
}

#endif




/**
char*  randstr(int n)

	機能：ランダムに A-Za-z0-9 までの文字を n文字生成する．
		  返されたデータは free()する必要がある．

	引数：n -- 出力する文字数．

	戻り値：ランダムに生成された n文字の文字列．
*/
char*  randstr(int n)
{
	char   base[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
	char*  pass;
	int	i, sz;

	if (n<=0) return NULL;
	pass = (char*)malloc(n+1);
	if (pass==NULL) return pass;

	sz = (int)strlen(base);
	for (i=0; i<n; i++) pass[i] = base[rand()%sz];
	pass[n] = '\0';

	return pass;
}





/**
unsigned char*  randbit(int n)

	機能：ランダムに n bitのバイナリを生成する．
		  返されたデータは free()する必要がある．

	引数：n -- 出力する bit数．

	戻り値：ランダムに生成された n bitのデータ．
 */
unsigned char*  randbit(int n)
{
	int   i, sz;
	unsigned char* bin;

	sz = (n+7)/8;
	bin = (unsigned char*)malloc(sz);
	if (bin==NULL) return NULL;

	memset(bin, 0, sz);
	for (i=0; i<n; i++) setBit(bin, i, rand()%2);

	return bin;	
}






/* ************************************************************************* */

/**
void  swap_byte(void* p, int s, int c)
	機能：上位バイトと下位バイトを逆順にする．
		  pが指す長さ sのデータを cバイトづつ逆順にする．

	引数：p -- データへのポインタ．
		  s -- データの長さ．バイト単位．
		  c -- 逆順にするデータの長さ．バイト単位．
*/
void  swap_byte(void* p, int s, int c)
{
	int	i;
	uByte* u = (uByte*)p;
	for (i=0; i<s; i+=c) reverse_str(&u[i], c);
}



	
/**
short  swaps(short p)

	16bit pの上下8bitを入れ替える．
    ntohs(), htons()の代替関数 for Smopuim SW

*/
short  swaps(short p)
{
	short  r;
    uByte* t;
	uByte* f;
     
	t = (uByte*)&r;
	f = (uByte*)&p;
	t[0] = f[1];
	t[1] = f[0];

	return r;
}




/**
int swapl(int p)

	32bit pを8bitづつ逆順にする
    ntohl(), htonl()の代替関数 for Smopuim SW

*/
int swapl(int p)
{
	int    r;
    uByte* t;
	uByte* f;
     
	t = (uByte*)&r;
	f = (uByte*)&p;
	t[0] = f[3];
	t[1] = f[2];
	t[2] = f[1];
	t[3] = f[0];

	return r;
}




/**
void  reverse_str(uByte* p, int s)
	機能：バイト列を逆順にする．

	引数：p -- バイトデータへのポインタ．
		  s -- バイトデータの長さ．
*/
void  reverse_str(uByte* p, int s)
{
	int	i;
	uByte  c;
	 
	if (s<=0) s = (int)strlen((const char*)p);

	for (i=0; i<s/2; i++) {
		c		= p[s-1-i];
		p[s-1-i] = p[i];
		p[i]	 = c;
	}
}   






/* ************************************************************************* */

/**
int  file_from_to(char* src, char* dst, char* mode)

	機能：modeに従って,ファイル srcを dstにコピーする．

	引数：src  -- コピー元(ソース)ファイル名
		  dst  -- コピー先(ディスティネーション)ファイル名
		  mode -- コピー先ファイルのオープンモード．fopenに同じ．"rwa"

	戻り値：  1  正常終了
             -1  作業用メモリが足りない．
			 -2  ソースファイルが存在しない．(シンボリックリンクも×)
			 -3  ソースファイルのオープン失敗
			 -4  ディスティネーションファイルのオープン失敗
 */
int  file_from_to(char* src, char* dst, char* mode)
{
	long int  sz;
	unsigned char* buf;
	FILE*  fp;

	sz = file_size(src);
	if (sz<0) return -2;
	buf = (unsigned char*)malloc(sz);
	if (buf==NULL) return -1;

	fp = fopen(src, "rb");
	if (fp==NULL) {
		free(buf);
		return -3;
	}
	fread(buf, sz, 1, fp);
	fclose(fp);

	fp = fopen(dst, mode);
	if (fp==NULL) {
		free(buf);
		return -4;
	}
	fwrite(buf, sz, 1, fp);
	fclose(fp);

	free(buf);
	return sz;
}





/**
int  fp_from_to(FILE* src, FILE* dst, long int sz)

	機能：ファイル srcを dstにコピーする．

	引数：src  -- コピー元(ソース)のファイルポインタ
		  dst  -- コピー先(ディスティネーション)のファイルポインタ
		  sz   --  コピー元(ソース)のサイズ

	戻り値：  1  正常終了
	         -1  作業用メモリが足りない．
	         -2  ファイルサイズの指定がおかしい．
			 -3  ソースファイルのオープン失敗．
			 -4  ディスティネーションファイルのオープン失敗．
 */
int  fp_from_to(FILE* src, FILE* dst, long int sz)
{
	unsigned char* buf;
	if (sz<=0)     return -2;
	if (src==NULL) return -3;
	if (dst==NULL) return -4;

	buf = (unsigned char*)malloc(sz);
	if (buf==NULL) return -1;

	fread(buf, sz, 1, src);
	sz = (int)fwrite(buf, sz, 1, dst);

	free(buf);
	return sz;
}





/**
char* get_file_name(char* str)

	フルパスからファイル名へのポインタを取り出す．

*/
char* get_file_name(char* str)
{
	int   sz, len;
	char* fnm;

	if (str==NULL) return NULL;

#ifdef WIN32
	char  cc = '\\';
#else
	char  cc = '/';
#endif

	len = (int)strlen(str);
	sz  = 0;
	while (sz<len && str[len-1-sz]!=cc) sz++;
	fnm = str + len - sz; 

	return fnm;
}

	



/**
unsigned long int   file_size(char* fn)											  

	機能：通常のファイルの大きさを返す．シンボリックリンクなどは 0．

	引数：ファイル名

	戻り値：ファイルのサイズ
 */
unsigned long int   file_size(char* fn)											  
{									  
	struct stat stbuf;											   
																   
	stat(fn, &stbuf);

#ifdef WIN32
	return stbuf.st_size;
#else
	if (S_ISREG(stbuf.st_mode)) return stbuf.st_size;
	else						return 0;
#endif
}





/**
int  file_exist(char* fn)

	機能：指定したファイルが存在して読み込み可能であれば「真」をそうでなければ「偽」を返す．
		  ファイルを一度オープンして確認するので，時間が掛かる．
	　　　読み込み可能なファイルを確認するのであれば，file_size()の方が（たぶん）早い．

	引数：ファイル名

	戻り値：TRUE  ファイルが存在し,読みこみ可能．
			FALSE ファイルが存在しないか,または読みこみ不可能． 
 */
int  file_exist(char* fn)
{
	FILE* fp;

	if (fn==NULL) return FALSE;

	if ((fp=fopen(fn,"rb"))==NULL) {
		return FALSE;
	}
	fclose(fp);
	return TRUE;
}





/**
FILE*  file_chmod_open(char* fn, char* fm, mode_t mode)

	機能：指定したファイルが存在して読み込み可能であれば，属性をmode へ変更した後，
		  ファイルを fmモードでオープンしなおして，ファイルポインタを返す．
		  存在しなければ，ファイルを作成して属性を変更し，その後，ファイルを fmモード
		  でオープンしなおして，ファイルポインタを返す．
		  属性の指定方法については man 2 chmod を参照すること．

	引数：fn	-- ファイル名
		  fm	-- ファイルモード，"r","w","a".....
		  mode  -- 属性．see...  man 2 chmod

	戻り値：not NULL オープンしたファイルポインタ
			NULL     失敗． 
 */
FILE*  file_chmod_open(char* fn, char* fm, mode_t mode)
{
	FILE* fp;

	if (!file_exist(fn)) {
		if ((fp=fopen(fn,"wb"))==NULL) return NULL;
		fclose(fp);
	}

#ifndef WIN32
	fp = NULL;
	if (chmod(fn, mode)) return fp;
#endif

	fp = fopen(fn, fm);
	return fp;
}




/**
char*  temp_filename(char* dir, int flen)

	機能：/dev/urandom を利用して作業用ファイルのランダムなファイル名を得る．
		  /dev/urandom が読めない場合は randstr() を利用する．
		  返されたデータは free()する必要がある．

	引数：dir  -- 作業ファイルを作るディレクトリ
		  flen -- 生成するファイル名の長さ

	戻り値： 作業用ファイル名のフルパス
 */
char*  temp_filename(const char* dir, int flen)
{
	FILE* fp;
	int   i, dlen=0;
	char  nostr = '\0';
	char* fname;
	char* fnbin;
	char* fnb64;

	if (dir==NULL) dir = &nostr;
	dlen = (int)strlen(dir);
	if (flen<=0)   flen = 15;

	fname = (char*)malloc(dlen+flen+1);
	if (fname==NULL) return NULL;
	fnbin = (char*)malloc(flen);
	if (fnbin==NULL) {
		free(fname);
		return NULL;
	}

	fnb64 = NULL;
	fp = fopen("/dev/urandom", "rb");

	do {
		if (fp!=NULL) {
			fread(fnbin, flen, 1, fp);
			fnb64 = (char*)encode_base64((unsigned char*)fnbin, flen);
			if (fnb64!=NULL) fnb64[flen] = '\0';
		}
		if (fnb64==NULL) fnb64 = randstr(flen);

		for (i=0; i<flen; i++) {
			if (fnb64[i]=='/') fnb64[i] = 'x';
			if (fnb64[i]=='+') fnb64[i] = 'X';
		}

		memset (fname, 0, dlen+flen+1);
		strncpy(fname, dir, dlen);
		strncat(fname, fnb64, flen);
		free(fnb64);
	} while(file_exist(fname)); 

	if (fp!=NULL) fclose(fp);
	free(fnbin);
	return fname;
}




unsigned char*  read_file(char* fname, unsigned long int* size)
{
	if (size==NULL) return NULL;

	*size = file_size(fname);
	if (*size<=0) return NULL;

	unsigned char* buf = (unsigned char*)malloc(*size);
	if (buf==NULL) return NULL;

	FILE* fp  = fopen(fname, "rb");
	if (fp==NULL) {
		free(buf);
		return NULL;
	}

	fread(buf, *size, 1, fp);
	fclose(fp);

	return buf;
}




long int  write_file(char* fname, unsigned char* buf, unsigned long int size)
{
	if (size==0) return 0;

	FILE* fp  = fopen(fname, "wb");
	if (fp==NULL) return 0;

	fwrite(buf, size, 1, fp);
	fclose(fp);

	return size;
}




/**
char* double_bs(char* str) 

    機能：文字列中の \ を \\ に変えた文字列を返す
		  返されたデータは free()する必要がある．

    引数：文字列

    戻り値：変換された文字列．失敗した場合は NULL
 */
char* double_bs(char* str) 
{
	int  i, j;
	int  len, bsn=0;
	char* buf;

	len = (int)strlen(str);
	for (i=0; i<len; i++) if (str[i]=='\\') bsn++;
	buf = (char*)malloc(len+bsn+1);
	if (buf==NULL) return NULL;

	for (i=0,j=0; i<len; i++) {
		buf[j++] = str[i];
		if (str[i]=='\\') buf[j++] = '\\';
	}
	buf[j] = '\0';

	return buf;
}







/**
char*  numbering_name(char* fmt, int n)

	機能：フォーマット fmtに従って，nを含む文字列を作り出す．要 free
		  返されたデータは free()する必要がある．
*/
char*  numbering_name(char* fmt, int n)
{
    int    len;
    char   fname[LNAME], *fo;

	memset(fname, 0, LNAME);
	snprintf(fname, LNAME-1, fmt, n);
	len = (int)strlen(fname);

	fo = (char*)malloc(len + 1);
	if (fo==NULL) return NULL;

	memset(fo, 0, len+1);
    strncpy(fo, fname, len);
    return fo;
}






/* ************************************************************************* */

/**
void kanji_convert(unsigned char* mesg)

	機能：大域変数 KnjiCodeに従って漢字コードを変換する．

	引数：変換する文字列を持つ unsigned char*型データ．内容が書き換えられる．

	注：現在は KanjiCodeが SJISの場合のみ EUCを SJISに変換する．
 */
void kanji_convert(unsigned char* mesg)
{
	if (KanjiCode==SJIS) {
		kanji_convert_euc2sjis(mesg);
	}
}




/**
void kanji_convert_euc2sjis(unsigned char* mesg)

	機能：EUCをSJISに変換する．

	引数：変換する文字列を持つ unsigned char*型データ．内容が書き換えられる．
*/
void kanji_convert_euc2sjis(unsigned char* mesg)
{
	int i = 0;
	while(mesg[i]!='\0' && mesg[i+1]!='\0'){
		if (mesg[i]>=0xa1 && mesg[i]<=0xfe){ // EUC
			euc2sjis(&mesg[i], &mesg[i+1]);
			i = i + 2;
		} 
		else  i++;
	}
}




/**
void kanji_convert_sjis2euc(unsigned char* mesg)

	機能：SJISをEUCに変換する．

	引数：変換する文字列を持つ unsigned char*型データ．内容が書き換えられる．
*/
void kanji_convert_sjis2euc(unsigned char* mesg)
{
	int i = 0;
	while(mesg[i]!='\0' && mesg[i+1]!='\0'){
		// if文が変則的なのは，コンパイラで警告が出るため   (GCC) 3.3.2 20031218 
		if ((mesg[i]>=0x81 && mesg[i]<=0x9f) ||
			(mesg[i]>=0xe0 && mesg[i]<=0xfe) || mesg[i]==0xff) { // SJIS
			sjis2euc(&mesg[i], &mesg[i+1]);
			i = i + 2;
		} 
		else  i++;
	}
}



/**
void  euc2sjis(unsigned char *c1, unsigned char *c2)

	機能：漢字コード変換．EUC→SJIS
  
	引数：c1 -- 変換する文字の第一バイト．内容が書き換えられる．
		  c2 -- 変換する文字の第二バイト．内容が書き換えられる．
*/
void  euc2sjis(unsigned char *c1, unsigned char *c2)
{
	if (*c1%2==0) *c2 -= 0x02;
	else{
		*c2 -= 0x61;
		if (*c2>0x7e) (*c2)++;
	}

	if (*c1<0xdf) {
		(*c1)++;
		*c1 /= 2;
		*c1 += 0x30;
	}
	else {
		(*c1)++;
		*c1 /= 2;
		*c1 += 0x70;
	}
}





/**
void  sjis2euc(unsigned char *c1, unsigned char *c2)

	機能：漢字コード変換．SJIS→EUC
  
	引数：c1 -- 変換する文字の第一バイト．内容が書き換えられる．
		  c2 -- 変換する文字の第二バイト．内容が書き換えられる．
*/
void  sjis2euc(unsigned char *c1, unsigned char *c2)
{
	if (*c2<0x9f) {
		if (*c1 < 0xa0) {
			*c1 -= 0x81;
			*c1 *= 2;
			*c1 += 0xa1;
		}
			
		else {
			*c1 -= 0xe0;
			*c1 *= 2;
			*c1 += 0xdf;
		}
		if (*c2>0x7f) (*c2)--;
		*c2 += 0x61;
	}
	else {
		if (*c1<0xa0) {
			*c1 -= 0x81;
			*c1 *= 2;
			*c1 += 0xa2;
		}
		else {
			*c1 -= 0xe0;
			*c1 *= 2;
			*c1 += 0xe0;
		}
		*c2 += 2;
	 }
}






/**
void  upper_string(char* str)

	機能：str中の小文字を大文字に変換する
  
	引数：str -- 変換する文字列へのポインタ．内容が書き換えられる．

*/
void  upper_string(char* str)
{
	int  i;
	for (i=0; i<(int)strlen((const char*)str); i++) {
		if (str[i]>='a' && str[i]<='z') str[i] += 'A' - 'a';
	}
}







/**
unsigned char*  decode_base64(unsigned char* buf, int* sz)

	機能：buf を base64からデコードする．
		  変換は bufの先頭から順次行われる．A-Za-z0-9+/ 以外は無視する(例えば改行コード)．

		  入力バッファ部が 4byte(6bit*4)の場合, 出力バッファ部は 3byte
		  (8bit*3)となる．入力バッファ部のバイト数が 4の倍数でない場合
		  (不正なデータ), 足りない入力バッファ部には '='が挿入されてい
		  るものとみなす．

		  返されたデータは free()する必要がある．

	引数：buf -- base64からデコードする文字列．
		  sz  -- デコードされたデータの長さを格納する int へのポインタ

	戻り値：return -- base64からデコードされたデータ
			*sz -- デコードされたデータのサイズ

	例："QQ" をデコードすると 'A',0x00 となる．
*/
unsigned char*  decode_base64(unsigned char* buf, int* sz)
{
	int   i, j, cc=0, bas, lt;
	unsigned char* dcd;

	lt = 0;
	while (buf[lt]!='=' && lt<(int)strlen((const char*)buf)) {
		lt++;
		if (lt==(int)strlen((const char*)buf)) break;
	}
	*sz = lt/4*3 + (lt%4)*3/4;
	dcd = (unsigned char*)malloc(*sz);
	if (dcd==NULL) return dcd;
	memset(dcd, 0, *sz);

	for (i=0; i<lt; i++) {
		if	    (buf[i]>='A' && buf[i]<='Z') cc = buf[i] - 'A';
		else if (buf[i]>='a' && buf[i]<='z') cc = buf[i] - 'a' + 26;
		else if (buf[i]>='0' && buf[i]<='9') cc = buf[i] - '0' + 52;
		else if (buf[i]=='+')				 cc = 62;
		else if (buf[i]=='/')				 cc = 63;

		if (cc<64) {
			bas = 32;
			for (j=0; j<6; j++) {
				setBit(dcd, i*6+j, cc/bas);
				cc = cc%bas;
				bas = bas/2;
			}
		}
	}

	return dcd;
}






/**
unsigned char*  encode_base64(unsigned char* buf, int sz)

	機能：バイナリデータ bufを base64にエンコードする．

		  入力バッファ部が 3byte(8bit*3)の場合, 出力バッファ部は 4byte
		  (6bit*4)となる．入力バッファ部が 6bit境界でない場合, 6bit境界
		  まで 0が付加されたと見される．
		  出力バッファ部が 4byte境界でない場合, 4byte境界まで '='を付加
		  して出力する． また,出力バッファ部での 60byte毎の改行は行わない．
		  一般に n byte 入力された場合, base64の出力の文字数は (n+2)/3*4
		  byte となる．

		  返されたデータは free()する必要がある．

	引数：buf -- base64にエンコードするデータ．
		  sz  -- データの長さを示す．-1以下の場合は buf は文字列とみなす．

	戻り値：return -- base64にエンコードされた文字列

	例：'A',0x00,0x01 を文字列(sz=1)とみなして符号化すると "QQ==" となる．
		'A',0x00,0x01 の 3byteを符号化(sz=3)すると "QQAB" となる．
*/
unsigned char*  encode_base64(unsigned char* buf, int sz)
{
	unsigned char  base[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	unsigned char  bas;
	int   i, j, len;
	unsigned char*  ecd;
	
	if (buf==NULL) return NULL;
   	if (sz<0) len = (int)strlen((const char*)buf);
	else  	  len = sz;
	if (len==0) return NULL;

	sz  = (len + 2)/3*4;
	ecd = (unsigned char*)malloc(sz+1);
	if (ecd==NULL) return NULL;
	memset(ecd, 0, sz+1);

	for (i=0; i<sz; i++) {
		bas = 0x00;
		if (len*8 > i*6) {
			for (j=0; j<6; j++) {
				if (len*8 > i*6+j) setBit(&bas, j+2, getBit(buf, i*6+j));
				//else			   setBit(&bas, j+2, 0);
			}
			ecd[i] = base[(int)bas];
		}
		else {
			ecd[i] = '=';
		}
	}

	return ecd;
}





/**
unsigned char*  decode_urlenc(unsigned char* buf, int* sz)

	機能：buf を URLエンコードからデコードする．
		  返されたデータは free()する必要がある．

	引数：buf -- デコードする文字列．
		  *sz -- デコードされたデータの長さを格納する変数．

	戻り値：return -- デコードされたデータ
			*sz	-- デコードされたデータの長さ
*/
unsigned char*  decode_urlenc(unsigned char* buf, int* sz)
{
	int	i, j, len;
	unsigned char*  dec;

	if (buf==NULL) return NULL;
	len = (int)strlen((const char*)buf) + 1;
	dec = (unsigned char*)malloc(len);
	if (dec==NULL) return NULL;
	memset(dec, 0, len);

	i = j = 0;
	while (buf[i]!='\0') {
		if (buf[i]=='%') {
			if (buf[i+1]=='\0') return dec;
			if (buf[i+2]=='\0') return dec;
			dec[j++] = decode_hex(buf[i+1], buf[i+2]);
			i += 2;
		}
		else {
			if (buf[i]=='+') dec[j++] = ' ';
			else			 dec[j++] = buf[i];
		}
		i++;
	}

	*sz = j;
	return dec;
}
				





/**
unsigned char*  encode_urlenc(unsigned char* buf)

	機能：バイナリデータ bufを URLエンコードする．
		  エンコードしない文字については色々考え方があるが，最大公約数的に考えて
　　　　　このプログラムでは以下のようにする．
		  	エンコードしない文字  0-9, A-Z, a-z, -._

		  返されたデータは free()する必要がある．

	引数：buf -- エンコードするデータ．
		  sz  -- エンコードするデータの長さ．-1以下の場合は buf は文字列とみなす．

	戻り値：return -- エンコードされた文字列
*/
unsigned char*  encode_urlenc(unsigned char* buf, int sz)
{
	int	i, j, len;
	unsigned char*  enc;


	if (sz<0) sz = (int)strlen((const char*)buf);
	len = sz*3 + 1;
	enc = (unsigned char*)malloc(len);
	if (enc==NULL) return NULL;
	memset(enc, 0, len);

	for(i=0, j=0; i<sz; i++) {
		if (buf[i]==' ') {										// 半角スペース
			enc[j++] = '+';
		}
		else if ((buf[i]>=0x30 && buf[i]<=0x39) ||				// 0-9
				 (buf[i]>=0x41 && buf[i]<=0x5a) ||				// A-Z
				 (buf[i]>=0x61 && buf[i]<=0x7a) ||				// a-z
				  buf[i]=='-' || buf[i]=='.' || buf[i]=='_'){	// - . _
			enc[j++] = buf[i];
		}
		else {
			unsigned char* asc = encode_hex(buf[i]);
			if (asc==NULL) {
				free(enc);
				return NULL;
			}
			enc[j++] = '%';
			enc[j++] = asc[0];
			enc[j++] = asc[1];
			free(asc);
		}
	}

	return enc;
}	






/**
unsigned char*  decode_quoted_printable(unsigned char* buf, int* sz)

	機能：buf を quoted printableからデコードする．
		  返されたデータは free()する必要がある．

	引数：buf -- デコードする文字列．
		  *sz -- デコードされたデータの長さを格納する変数．

	戻り値：return -- デコードされたデータ
			*sz	-- デコードされたデータの長さ
*/
unsigned char*  decode_quoted_printable(unsigned char* buf, int* sz)
{
	int	i, j, len;
	unsigned char*  dec;

	len = (int)strlen((const char*)buf) + 1;
	dec = (unsigned char*)malloc(len);
	if (dec==NULL) return NULL;
	memset(dec, 0, len);

	i = j = 0;
	while (buf[i]!='\0') {
		if (buf[i]=='=') {
			if (buf[i+1]=='\0') return dec;
			if (buf[i+2]=='\0') return dec;
			dec[j++] = decode_hex(buf[i+1], buf[i+2]);
			i += 2;
		}
		else {
			if (buf[i]=='_') dec[j++] = ' ';			// RFC2047
			else			 dec[j++] = buf[i];
		}
		i++;
	}

	*sz = j;
	return dec;
}
				





/**
unsigned char*  encode_quoted_printable(unsigned char* buf, int sz)

	機能：バイナリデータ bufを quoted printable にエンコードする．
		  RFC2047 に従い，' ' は '_' にエンコードする．
		  	エンコードしない文字 '=', '_' 以外の 0x21-0x7e
		  	エンコードする文字   '=', '_', 0x00-0x20, 0x7f-0xff

		  返されたデータは free()する必要がある．

	引数：buf -- エンコードするデータ．
		  sz  -- エンコードするデータの長さ．-1以下の場合は buf は文字列とみなす．

	戻り値：return -- エンコードされた文字列
*/
unsigned char*  encode_quoted_printable(unsigned char* buf, int sz)
{
	int	i, j, len;
	unsigned char*  enc;

	if (sz<0) sz = (int)strlen((const char*)buf);
	len = sz*3 + 1;
	enc = (unsigned char*)malloc(len);
	if (enc==NULL) return NULL;
	memset(enc, 0, len);

	for (i=0, j=0; i<sz; i++) {
		if (buf[i]=='=') {		// 0x3d
			enc[j++] = '=';
			enc[j++] = '3';
			enc[j++] = 'D';
		}
		else if (buf[i]=='_') {		// 0x5f
			enc[j++] = '=';
			enc[j++] = '5';
			enc[j++] = 'F';
		}
		else if (buf[i]==' ') {		// 0x20  RFC2047
			enc[j++] = '_';
		}
		else if (buf[i]<=0x1f || buf[i]>=0x7f) {
			unsigned char* asc = encode_hex(buf[i]);
			if (asc==NULL) {
				free(enc);
				return NULL;
			}
			enc[j++] = '=';
			enc[j++] = asc[0];
			enc[j++] = asc[1];
			free(asc);
		}
		else {
			enc[j++] = buf[i];
		}
	}

	return enc;
}	






/**
unsigned char*  encode_hex(unsigned char cc)

	機能：キャラクタを１６進コードの文字列に変換する．
		  返されたデータは free()する必要がある．

	引数：変換するキャラクタ．

	戻り値：新しく確保された 3byteの領域
			[0] -- １６進コードの上位４Bit． 0-9,A-F
		  	[1] -- １６進コードの下位４Bit． 0-9,A-F
			[2] -- '\0'
			NULL の場合はメモリ不足．

	例：encode_hex(' ')  は "20" を返す．

*/
unsigned char*  encode_hex(unsigned char cc)
{
	unsigned char* ret;
	unsigned char  pp1, pp2;
	unsigned char  base[] = "0123456789ABCDEF";

	ret = (unsigned char*)malloc(3);
	if (ret==NULL) return NULL;

	pp1 = cc >> 4;
	pp2 = cc & 0x0f;

	ret[0] = base[pp1];
	ret[1] = base[pp2];
	ret[2] = '\0';

	return ret;
}




/**
unsigned char  decode_hex(unsigned char pp1, unsigned char pp2)

	機能：１６進コードをキャラクタに変換する．O-9,A-F以外が指定された場合は0とみなす．

	引数：pp1  -- １６進コードの上位４Bit． 0-9,A-F
		  pp2  -- １６進コードの下位４Bit． 0-9,A-F

	戻り値：指定されたASCIIコードのキャラクタ

	例：decode_hex('2', '0')  は ' ' を返す．

*/
unsigned char  decode_hex(unsigned char pp1, unsigned char pp2)
{
	unsigned char ret;

	if (pp1>=0x30 && pp1<=0x39) 	 pp1 -= 0x30;	// 0-9
	else if (pp1>=0x41 && pp1<=0x46) pp1 -= 0x37;	// A-F
	else if (pp1>=0x61 && pp1<=0x66) pp1 -= 0x57;	// a-f
	else 							 pp1 =  0x00;

	if (pp2>=0x30 && pp2<=0x39) 	 pp2 -= 0x30;	// 0-9
	else if (pp2>=0x41 && pp2<=0x46) pp2 -= 0x37;	// A-F
	else if (pp2>=0x41 && pp2<=0x46) pp2 -= 0x57;	// a-f
	else 							 pp1 =  0x00;

	ret = (pp1<<4) + pp2;
	return ret;
}





//////////////////////////////////////////////////////////////////////////////////////////////////////
//
//

/**
void  print_message(char* fmt, ...)

	機能：バッファリング無しのメッセージ出力（stderr）

	引数：fmt -- 出力フォーマット．その他は printf() に準拠．
*/
void  print_message(char* fmt, ...)
{
	char*  nfmt;
	int    len;

	va_list  args;
	va_start(args, fmt);

	len  = (int)strlen(fmt);	
	nfmt = (char*)malloc(len + 1);
	if (nfmt==NULL) return;

	strncpy(nfmt, fmt, len);
	nfmt[len] = '\0';

	vfprintf(stderr, nfmt, args); 
	fflush(stderr);
	free(nfmt);

	va_end(args);

	return;
}





/**
void  fprint_message(FILE *fp, char* fmt, ...)

	機能：バッファリング無しのメッセージ出力（stderr）

	引数：fmt -- 出力フォーマット．その他は printf() に準拠．
*/
void  fprint_message(FILE* fp, char* fmt, ...)
{
	char*  nfmt;
	int    len;

	va_list  args;
	va_start(args, fmt);

	len  = (int)strlen(fmt);	
	nfmt = (char*)malloc(len + 1);
	if (nfmt==NULL) return;

	strncpy(nfmt, fmt, len);
	nfmt[len] = '\0';

	vfprintf(fp, nfmt, args); 
	fflush(fp);
	free(nfmt);

	va_end(args);

	return;
}




/**
void  print_escape(char* fmt, char* mesg)

	機能：エスケープ文字を含むメッセージの出力．
	　	　現在は CR, LF のみ \r, \n に変換する．see change_esc()

*/
void  print_escape(char* fmt, char* mesg)
{
	char* pp;

	if (fmt==NULL || mesg==NULL) return;
	
	pp = change_esc(mesg);
	if (pp==NULL) return;

	print_message(fmt, pp);
	free(pp);
}




/**
void  fprint_escape(FILE* fp, char* fmt, char* mesg)

	機能：エスケープ文字を含むメッセージの出力．
	　	　現在は CR, LF のみ \r, \n に変換する．see change_esc()

*/
void  fprint_escape(FILE* fp, char* fmt, char* mesg)
{
	char* pp;

	if (fmt==NULL || mesg==NULL) return;
	
	pp = change_esc(mesg);
	if (pp==NULL) return;

	fprint_message(fp, fmt, pp);
	free(pp);
}




/**
void  fdump(FILE* fp, unsigned char* mesg, int n)

	機能：デバッグ用 16進出力
		  mesgの nバイトを16進表示する．n<0 の場合は 文字列とみなす．

	引数：fp   -- 出力するファイルへのポインタ．NULLの場合は stderr
		  mesg -- 表示するデータ．
		  n    -- 表示するバイト数

*/
void  fdump(FILE* fp, unsigned char* mesg, int n)
{
	int  i, j, mod, len;
	char ascii[16];

	if (fp==NULL) fp = stderr;

	if (mesg==NULL) {
		fprintf(fp, "(Dump Data is NULL)\n");
		return;
	}

    if (n<0) len = (int)strlen((const char*)mesg);
    else     len = n;

    memset(ascii, 0x2e, 16);
    for (i=0, j=0; i<len; i++) {
        fprintf(fp, "%02x ", mesg[i]);
        if (mesg[i]>=0x20 && mesg[i]<=0x7e) ascii[j] = mesg[i];
		j++;
        if (j==16) {
            fprintf(fp, "   ");
            for (j=0; j<16; j++) {
                fprintf(fp, "%c ", ascii[j]);
            }
            fprintf(fp, "\n");
            memset(ascii, 0x2e, 16);
            j = 0;
        }
    }
                
    mod = len%16;
    if (mod>0) {                           
        for (i=0; i<17-mod; i++) fprintf(fp, "   ");
        for (i=0; i<mod; i++)    fprintf(fp, "%c ", ascii[i]);
    }                    
    fprintf(fp, "\n");
}





/**
void  print_16x(FILE* fp, unsigned char* mesg, int n)

	機能：デバッグ用 16進出力．
		  mesgの nバイトの16進を一行，空白なしで表示する．n<0 の場合は 文字列とみなす．

	引数：fp   -- 出力するファイルへのポインタ．NULLの場合は stderr
		  mesg -- 表示するデータ．
		  n    -- 表示するバイト数

*/
void  print_16x(FILE* fp, unsigned char* mesg, int n)
{
	int  i, len;

	if (fp==NULL) fp = stderr;

    if (n<0) len = (int)strlen((const char*)mesg);
    else     len = n;

    for (i=0; i<len; i++) {
        fprintf(fp, "%02x", mesg[i]);
    }
    fprintf(fp, "\n");
}






/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  バイト型 リングバッファ
//

/**
ringbuffer*  new_ringbuffer()

	機能：空のリングバッファ型変数を作り出す．この操作では，まだバッファ部は作成されない．
		  返されたデータは free()する必要がある．

*/
ringbuffer*  new_ringbuffer()
{
	ringbuffer* rb;
	
	rb = (ringbuffer*)malloc(sizeof(ringbuffer));
	if (rb==NULL) return NULL;
	memset(rb, 0, sizeof(ringbuffer));

	return rb;
}




/**
void   del_ringbuffer(ringbuffer** rb)

	機能：new_ringbuffer()で作り出したリングバッファを削除する．

*/
void   del_ringbuffer(ringbuffer** rb)
{
	if (rb!=NULL && *rb!=NULL) {
		freeNull((*rb)->buf);
		free(*rb);
		*rb = NULL;
	}
}




/**
ringbuffer   init_ringbuffer()

	機能：初期化された ringbuffer変数を返す．

*/
ringbuffer   init_ringbuffer()
{
	ringbuffer  rb;

	memset(&rb, 0, sizeof(ringbuffer));
	//rb.bufsz = -1;

	return rb;
}




/**
ringbuffer   make_ringbuffer(int sz)

	機能：バッファ部が存在するリングバッファを作り出す．
		  バッファ部は free()する必要がある．

*/
ringbuffer   make_ringbuffer(int sz)
{
	ringbuffer  rb;

	memset(&rb, 0, sizeof(ringbuffer));
	
	if (sz>0) {
		rb.buf = (unsigned char*)malloc(sz);
		if (rb.buf==NULL) return rb;
		memset(rb.buf, 0, sz);
		rb.bufsz = sz;
	}

	return rb;
}




/**
void   free_ringbuffer(ringbuffer* rb)

	機能：リングバッファのバッファ部を開放する．

*/
void   free_ringbuffer(ringbuffer* rb)
{
	if (rb!=NULL) {
		freeNull(rb->buf);
		memset(rb, 0, sizeof(ringbuffer));
	}
}




/**
void   clear_ringbuffer(ringbuffer* rb)

	機能：リングバッファ rb のデータをクリア（初期化）する．

*/
void   clear_ringbuffer(ringbuffer* rb)
{
	if (rb!=NULL) {
		int sz = rb->bufsz;
		unsigned char* ptr = rb->buf;
		memset(rb->buf, 0, rb->bufsz);
		memset(rb, 0, sizeof(ringbuffer));
		rb->buf   = ptr;
		rb->bufsz = sz;
	}
}




/**
int   put_ringbuffer(ringbuffer* rb, unsigned char* pp, int sz)

	機能：リングバッファ rb へデータを szバイト格納する．

	引数：sb   メッセージストリームへのポインタ
		  pp   格納するデータへのポインタ．
		　sz   格納するデータのサイズ（Byte）

	戻り値：0以上：書き込んだバイト数．
			-1: 引数にNULLのデータがある．
			-2: バッファ（データ格納）部の領域がない．
			-3: バッファ（データ格納）部の大きさがたりない．データはputされなかった．
			rb->state: 0 バッファは正常状態．-1 バッファは異常な状態にある．
*/
int   put_ringbuffer(ringbuffer* rb, unsigned char* pp, int sz)
{
	if (rb==NULL) return -1;
	rb->state = 0;

	if (pp==NULL)      return -1;
	if (rb->buf==NULL) return -2;
	if (rb->datasz+sz>rb->bufsz) {
		rb->state = -1;
		return -3;
	}

	if (rb->epoint+sz<=rb->bufsz) {
		memcpy(&((rb->buf)[rb->epoint]), pp, sz);
		rb->epoint = rb->epoint + sz;
		if (rb->epoint==rb->bufsz) rb->epoint = 0;
	}
	else {
		memcpy(&(rb->buf[rb->epoint]), pp, rb->bufsz-rb->epoint);
		memcpy(rb->buf, &(pp[rb->bufsz-rb->epoint]), sz-(rb->bufsz-rb->epoint));
		rb->epoint = rb->epoint + sz - rb->bufsz; 
	}

	rb->datasz += sz;
	return sz;
}	





/**
unsigned char*   get_ringbuffer(ringbuffer* rb, int sz)

	機能：リングバッファ rb から szバイトのデータを取り出す．
		  返されたデータは free()する必要がある．

	引数：リングバッファへのポインタ

	戻り値：取り出したデータへのポインタ．使い終わったら free()する必要がある．
			NULL  データ取得失敗．現在有効なデータサイズはszより小さい．または単に失敗した．
			rb->state: 0 バッファは正常状態．-1 バッファは異常な状態にある．
*/
unsigned char*   get_ringbuffer(ringbuffer* rb, int sz)
{
	unsigned char* pp;

	if (rb==NULL) return NULL;
	rb->state = 0;
	if (rb->buf==NULL) return NULL;
	if (sz>rb->datasz) return NULL;

	pp = (unsigned char*)malloc(sz+1);
	if (pp==NULL) {
		rb->state = -1;
		return NULL;
	}
	memset(pp, 0, sz+1);

	if (rb->spoint+sz<=rb->bufsz) {
		memcpy(pp, &(rb->buf[rb->spoint]), sz);
		rb->spoint = rb->spoint + sz;
		if (rb->spoint==rb->bufsz) rb->spoint = 0;
	}
	else {
		memcpy(pp, &(rb->buf[rb->spoint]), rb->bufsz-rb->spoint);
		memcpy(&(pp[rb->bufsz-rb->spoint]), rb->buf, sz-(rb->bufsz-rb->spoint));
		rb->spoint = rb->spoint + sz - rb->bufsz; 
	}

	rb->datasz -= sz;
	return pp;
}	







///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// バイト型 メッセージストリームバッファ
//

/**
int   put_mstream(mstream* sb, unsigned char* mesg)

	機能：メッセージ（文字列）ストリーム sb へメッセージ（の一部）を格納する．
		　ここで，メッセージとは \r\n, \r または \n で区切られている文字列でのことである．

	引数：sb   メッセージストリームへのポインタ
		  mesg 格納するメッセージ，またはその一部

	戻り値：0以上：書き込んだバイト数（CRLFを含む）
			-1: 引数にNULLのデータがある．
			-2: バッファ（データ格納）部の領域がない．
			-3: バッファ（データ格納）部の大きさがたりない．
			sb->state: 0 ストリームは正常状態．-1 ストリームは異常な状態にある．
*/
int   put_mstream(mstream* sb, unsigned char* mesg)
{
	int  i, n, m, cc, np=0, len;

	if (sb==NULL)   return -1;
	sb->state = 0;
	if (mesg==NULL) return -1;
	if (sb->buf==NULL) return -2;

	len = (int)strlen((const char*)mesg);
	for (i=0, n=0, m=0; i<len; i++) {
		if (mesg[i]==LF || (mesg[i]==CR && mesg[i+1]!=LF)) {
			if (m==0) m = i;
			n++;
		}
	}
	if (sb->datano==0 && n>=1) np = (sb->epoint + m + 1) % sb->bufsz;

	cc = put_ringbuffer(sb, mesg, len);
	if (cc>=0) {
		if (sb->datano==0 && n>=1) sb->npoint = np;
		sb->datano += n;
	}

	if (cc<0) sb->state = -1;
	return cc;
}





/**
unsigned char*  get_mstream(mstream* sb)

	機能：メッセージ（文字列）ストリーム sb から次のメッセージを取り出す．
		  改行コードは削除される．
		　ここで，メッセージとは \r\n, \r または \n で区切られている文字列でのことである．

	引数：メッセージストリームへのポインタ

	戻り値：取り出したストリームデータへのポインタ．使い終わったら free()する必要がある．
			NULL  データ取得失敗．現在有効なメッセージデータは無い．または単に失敗した．
			sb->state: 0 ストリームは正常状態．-1 ストリームは異常な状態にある．非実装
*/
unsigned char*  get_mstream(mstream* sb)
{
	int  n, len;
	unsigned char* pp;

	if (sb==NULL) return NULL;
	sb->state = 0;
	if (sb->buf==NULL) return NULL;
	if (sb->datano==0) return NULL;

	len = sb->npoint - sb->spoint;
	if (len==0) return NULL;
	else if (len<0) len += sb->bufsz;

	pp = get_ringbuffer(sb, len);
	if (pp==NULL) {
		sb->state = -1;
		return NULL;
	}
	chomp((char*)pp);

	sb->datano += -1;
	sb->spoint = sb->npoint;

	if (sb->datano>=1) {
		int m;
		n = sb->spoint;
		while (n!=sb->epoint) {
			m = (n + 1) % sb->bufsz;
			if (sb->buf[n]==LF || (sb->buf[n]==CR && sb->buf[m]!=LF)) {
				sb->npoint = m;
				break;
			}
			n = m;
		}
	}

	return pp;
}





/**
unsigned char*  fgets_mstream(unsigned char* mesg, mstream* sb)
 
	機能：メッセージ mesg はメッセージストリームに一旦バッファリングされ，この関数により
		  一行ずつ読み出される．結果が返される時，行中の改行コードは削除され，行末には必ず \0 が入る．
		  メッセージストリームのバッファ部が確保されていない場合は，最初に呼び出された時点で
		　確保される．一旦この関数を使用して，受信データをバッファリングしたら，最後まで読み取りには
		  必ず同じストリームを使用してこの関数を呼び出さばければならない．そうで無い場合は受信データ
		  の整合性は保証されない．

	引数：	mesg	バッファに一旦格納されるメッセージ．NULLでも可．
			sb	    ストリームバッファ（リングバッファ型のストリームバッファ）
					バッファ部が確保さえていなければ，自動的に確保される．

	戻り値： return : 取り出した文字列へのポインタ
			 sb->state : <0 メッセージストリーム操作中は異常な状態にある．
				 		  1 メッセージストリーム中に有効なデータがない．return は NULL
*/
unsigned char*  fgets_mstream(unsigned char* mesg, mstream* sb)
{
	int state=0;
	unsigned char* pp;

	if (sb==NULL) return NULL;
	if (sb->buf==NULL) {
		*sb = make_mstream(RECVBUFSZ);
		if (sb->buf==NULL) return NULL;
	}

	if (mesg!=NULL) put_mstream(sb, mesg);
	if (sb->state<0) state = sb->state;

	if (sb->datano==0) {
		sb->state = 1;
		return NULL;
	}
	pp = get_mstream(sb);
	
	if (sb->state>=0 && state<0) sb->state = state;
	return pp;
}





///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 
//

/**
unsigned char*  uuid2guid(unsigned char* p)

	機能：バイナリの UUID を テキストのGUIDに変換する．要 free()

*/
unsigned char*  uuid2guid(unsigned char* p)
{
    unsigned char* guid;

	if (p==NULL) return NULL;

	guid = (unsigned char*)malloc(LGUID);	// 40 = 32+4+1(\0) + α
	if (guid==NULL) return NULL;

    snprintf((char*)guid, 37, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
                    p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);

    return guid;
}





/**
unsigned char*  guid2uuid(unsigned char* p)

	機能：テキストのGUID をバイナリのUUID に変換する．要 free()
		入力が GUIDの形式でない時は，処理結果は保証されない．

*/
unsigned char*  guid2uuid(unsigned char* p)
{
	int   i, j;
    unsigned char* uuid;

	if (p==NULL) return NULL;

	uuid = (unsigned char*)malloc(16);
	if (uuid==NULL) return NULL;

	i = j = 0;
	while (p[i]!='\0' && j<16) {
		if (p[i]!='-' && p[i+1]!='\0') {
			unsigned char hb, lb;

			if      (p[i]>='0' && p[i]<='9')     hb = p[i] - '0';
			else if (p[i]>='a' && p[i]<='f')     hb = p[i] - 'a' + 10;
			else if (p[i]>='A' && p[i]<='F')     hb = p[i] - 'A' + 10;
			else hb = '\0';

			if      (p[i+1]>='0' && p[i+1]<='9') lb = p[i+1] - '0';
			else if (p[i+1]>='a' && p[i+1]<='f') lb = p[i+1] - 'a' + 10;
			else if (p[i+1]>='A' && p[i+1]<='F') lb = p[i+1] - 'A' + 10;
			else lb = '\0';
			
			uuid[j] = (hb<<4) + lb;
			i++;
			j++;
		}
		i++;
	}

    return uuid;
}







///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// シグナル処理
//
#ifndef WIN32

#ifdef SIGCHLD

/**
void  set_sigterm_child(void (*handler)(int))

    機能：child プロセス終了時の処理を設定．

*/
void  set_sigterm_child(void (*handler)(int))
{    
	struct sigaction sa;

	if (handler!=NULL) sa.sa_handler = handler;
	else               sa.sa_handler = sigterm_child;

	sa.sa_flags = SA_NOCLDSTOP | SA_RESTART; 
    sigemptyset(&sa.sa_mask);
	sigaddset(&sa.sa_mask, SIGINT);
	sigaddset(&sa.sa_mask, SIGHUP);
	sigaddset(&sa.sa_mask, SIGTERM);
    sigaction(SIGCHLD, &sa, NULL);
}




/**
void  set_sigsegv_handler(void (*handler)(int))

    機能：セグメンテーションエラー時のハンドラを設定．
		  引数に NULLを指定した場合は，ハンドラ関数として trap_segmentation_falt() を使用．

*/
void  set_sigsegv_handler(void (*handler)(int))
{
	struct sigaction sa;

	if (handler!=NULL) sa.sa_handler = handler;
	else               sa.sa_handler = trap_segmentation_falt;
	
	sa.sa_flags = 0;
	sigemptyset(&sa.sa_mask);
	sigaction(SIGSEGV, &sa, NULL);
}





void  trap_segmentation_falt(int signal)
{
	print_message("****************************************************************\n");
	print_message("* Segmentation Falt in [%d] !!!!!\n", getpid());
	print_message("****************************************************************\n");

	exit(signal);
}




/**
void  ignore_sigterm_child()

    機能：child プロセスの終了を無視する．

*/
void  ignore_sigterm_child()
{    
	struct sigaction sa;

	sa.sa_handler = SIG_IGN;
	sa.sa_flags   = 0; 
    sigemptyset(&sa.sa_mask);
    sigaction(SIGCHLD, &sa, NULL);
}




/**
void  sigterm_child(int signal)

    機能：child プロセス終了時の処理

*/
void  sigterm_child(int signal)
{
    pid_t pid = 0;
    int ret;

	DEBUG_MESG("%d is waiting for children. signal = %d\n", getpid(), signal);

    do {	// チャイルドプロセスの終了を待つ	
        pid = waitpid(-1, &ret, WNOHANG);
    } while(pid>0);
}


#endif		// SIGCHLD

#endif		// NOT WIN32







///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// for Windows
//

#ifdef WIN32

/* see common.h

void  bzero(char* p, unsigned int n)
{
	for (unsigned int i=0; i<n; i++) *(p++) = 0x00;
}



void  bcopy(char* f, char* t, unsigned int n)
{
	for (unsigned int i=0; i<n; i++) *(t++) = *(f++);
}
*/

#endif   // WIN32
