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

	【機能概要】	: 共有メモリダンプコマンド
					  共有メモリIDとサイズを指定して、共有メモリに設定されている
					  データを画面上にダンプ出力する

	【作成日】		: 2021.04.23

	【呼出形式】	: GG_MEMDMP P1 P2 P3						# コマンドライン
							P1 : 共有メモリキー（10進）
							P2 : ダンプ出力オフセット値
							P3 : ダンプ出力サイズ

	【戻り値】		:  0 : 正常終了
					  -1 : 異常終了

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

#include "compatible_function.h"
#include "sharedmemory_cls.h"
int main(int argc, char* argv[]) {
	CLSSharedMemory shmAcPtMem;			// 使用面管理領域の共有メモリ

	char * cInputBuffer;				// 入力バッファ
	char * cOutputBuffer;				// 出力バッファ
	char * pcBuffer;					// strtok用ワークバッファ
	int i=0;							// 行カウンタ
	int iSize;							// 出力サイズ
	int offset;							// 出力開始オフセット

	// パラメータチェック
	if(argc < 2){
		printf("Usage : GG_MEMDMP [ 共有メモリキー(10進) ] [ オフセット ] [.サイズ.]\n");
		printf("        パラメータが足りません\n");
		exit (-1);
	}
	if(argc == 2){
		offset = 0;
		iSize = 1024;
	}
	if(argc == 3){
		offset = atoi(argv[2]);
		iSize = 1024;
	}
	if(argc == 4){
		offset = atoi(argv[2]);
		iSize = atoi(argv[3]);
	}
	if(argc > 4){
		printf("Usage : GG_MEMDMP [ 共有メモリキー(10進) ] [ オフセット ] [.サイズ.]\n");
		printf("        パラメータが多すぎます\n");
		exit (-1);
	}
	
	// 共有メモリのオープン
	cInputBuffer = (char *)shmAcPtMem.OpenSheredMemory(atoi(argv[1]));
	if(cInputBuffer == NULL){
		printf("*** 共有メモリ 取得失敗 ***\nKEY=%i\n",atoi(argv[1]));
		exit (-1);
	}

	// 出力バッファのメモリ領域確保
	cOutputBuffer = (char *) malloc(iSize*5+100000);

	// ヘッダ出力
	printf("*** 共有メモリ 出力 ***\nKEY=%i  SIZE=%i  OFFSET=%i\n",atoi(argv[1]),iSize,offset);
	
	// メモリダンプ出力
	memdmp(cInputBuffer+offset,iSize,cOutputBuffer,iSize*5);
	pcBuffer = strtok(cOutputBuffer,"\n");
	while(pcBuffer){
		printf("%08x:",cInputBuffer+i*16);
		printf("%s\n",pcBuffer);
		pcBuffer = strtok(NULL,"\n");
		i++;
	}

	// 終了処理
	free(cOutputBuffer);
	return 0;
}

int memdmp(void * inputMemory,int inputSize,char * outputBuffer,int outputBufferSize){
	unsigned char * pMemory = (unsigned char *)inputMemory;
	int iOutputLength=0;
	char wkChar[3];
	int i,j=0;
	while(inputSize>0){
		for(i=0;(i<16)&&(i<inputSize);i++){
			sprintf(outputBuffer+iOutputLength,"%02x",*(pMemory+i));
			iOutputLength+=2;
			if(i%4==3){
				strcat(outputBuffer+iOutputLength,"|");
			}
			else{
				strcat(outputBuffer+iOutputLength," ");
			}
			iOutputLength++;
		}
		for(;i<16;i++){
			strcat(outputBuffer+iOutputLength,"  ");
			iOutputLength+=2;
			if(i%4==3){
				strcat(outputBuffer+iOutputLength,"|");
			}
			else{
				strcat(outputBuffer+iOutputLength," ");
			}
			iOutputLength++;
		}
		strcat(outputBuffer+iOutputLength,"|");
		iOutputLength++;
		for(j=0;(j<16)&&(j<inputSize);j++){
			if(*(pMemory+j)<0x20){
				strcat(outputBuffer+iOutputLength," ");
				iOutputLength++;
			}
			else if((*(pMemory+j)>=0x20)&&(*(pMemory+j)<0x7f)){
				sprintf(outputBuffer+iOutputLength,"%c",*(pMemory+j));
				iOutputLength++;
			}
			else if((*(pMemory+j)>=0x7f)&&(*(pMemory+j)<0x81)){
				strcat(outputBuffer+iOutputLength," ");
				iOutputLength++;
			}
			else if((*(pMemory+j)>=0x81)&&(*(pMemory+j)<0xa0)){
				if((*(pMemory+j+1)>=0x40)&&(*(pMemory+j+1)<=0xfc)){
					strncpy(wkChar,(char *)(pMemory+j),2);
					strcat(outputBuffer+iOutputLength,wkChar);
					iOutputLength+=2;
					j++;
				}
				else{
					strcat(outputBuffer+iOutputLength," ");
					iOutputLength++;
				}
			}
			else if((*(pMemory+j)>=0xa0)&&(*(pMemory+j)<0xe0)){
				strcat(outputBuffer+iOutputLength," ");
				iOutputLength++;
			}
			else if((*(pMemory+j)>=0xe0)&&(*(pMemory+j)<0xfd)){
				if((*(pMemory+j+1)>=0x40)&&(*(pMemory+j+1)<=0xfc)){
					strncpy(wkChar,(char *)(pMemory+j),2);
					strcat(outputBuffer+iOutputLength,wkChar);
					iOutputLength+=2;
					j++;
				}
				else{
					strcat(outputBuffer+iOutputLength," ");
					iOutputLength++;
				}
			}
			else{
				strcat(outputBuffer+iOutputLength," ");
				iOutputLength++;
			}
		}
		pMemory+=16;
		inputSize-=16;
		//strcat(outputBuffer,"\n");
		outputBuffer[iOutputLength]=0x0a;
		iOutputLength+=strlen("\n");
	}
	return strlen(outputBuffer);
}
