// TsEncode.cpp: TS僄儞僐乕僪僋儔僗偺僀儞僾儕儊儞僥乕僔儑儞
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <mbstring.h>
#include "TsEncode.h"


//////////////////////////////////////////////////////////////////////
// CAribString 僋儔僗偺峔抸/徚柵
//////////////////////////////////////////////////////////////////////

static const bool abCharSizeTable[] =
{
	false,	// CODE_UNKNOWN					晄柧側僌儔僼傿僢僋僙僢僩(旕懳墳)
	true,	// CODE_KANJI					Kanji
	false,	// CODE_ALPHANUMERIC			Alphanumeric
	false,	// CODE_HIRAGANA				Hiragana
	false,	// CODE_KATAKANA				Katakana
	false,	// CODE_MOSAIC_A				Mosaic A
	false,	// CODE_MOSAIC_B				Mosaic B
	false,	// CODE_MOSAIC_C				Mosaic C
	false,	// CODE_MOSAIC_D				Mosaic D
	false,	// CODE_PROP_ALPHANUMERIC		Proportional Alphanumeric
	false,	// CODE_PROP_HIRAGANA			Proportional Hiragana
	false,	// CODE_PROP_KATAKANA			Proportional Katakana
	false,	// CODE_JIS_X0201_KATAKANA		JIS X 0201 Katakana
	true,	// CODE_JIS_KANJI_PLANE_1		JIS compatible Kanji Plane 1
	true,	// CODE_JIS_KANJI_PLANE_2		JIS compatible Kanji Plane 2
	true	// CODE_ADDITIONAL_SYMBOLS		Additional symbols
};

const DWORD CAribString::AribToString(TCHAR *lpszDst, const BYTE *pSrcData, const DWORD dwSrcLen)
{
	// ARIB STD-B24 Part1 仺 Shift-JIS / Unicode曄姺
	CAribString WorkObject;
	
	return WorkObject.AribToStringInternal(lpszDst, pSrcData, dwSrcLen);
}

const DWORD CAribString::AribToStringInternal(TCHAR *lpszDst, const BYTE *pSrcData, const DWORD dwSrcLen)
{
	if(!pSrcData || !dwSrcLen || !lpszDst)return 0UL;

	DWORD dwSrcPos = 0UL;
	DWORD dwDstLen = 0UL;

	// 忬懺弶婜愝掕
	m_byEscSeqCount = 0U;
	m_pSingleGL = NULL;

	m_CodeG[0] = CODE_KANJI;
	m_CodeG[1] = CODE_ALPHANUMERIC;
	m_CodeG[2] = CODE_HIRAGANA;
	m_CodeG[3] = CODE_KATAKANA;

	m_pLockingGL = &m_CodeG[0];
	m_pLockingGR = &m_CodeG[2];


	while(dwSrcPos < dwSrcLen){
		if(!m_byEscSeqCount){
			// GL/GR椞堟
			if((pSrcData[dwSrcPos] >= 0x21U) && (pSrcData[dwSrcPos] <= 0x7EU)){
				// GL椞堟
				const CODE_SET CurCodeSet = (m_pSingleGL)? *m_pSingleGL : *m_pLockingGL;
				m_pSingleGL = NULL;
				
				if(abCharSizeTable[CurCodeSet]){
					// 2僶僀僩僐乕僪
					if((dwSrcLen - dwSrcPos) < 2UL)break;
					
					dwDstLen += ProcessCharCode(&lpszDst[dwDstLen], ((WORD)pSrcData[dwSrcPos + 0] << 8) | (WORD)pSrcData[dwSrcPos + 1], CurCodeSet);
					dwSrcPos++;
					}
				else{
					// 1僶僀僩僐乕僪
					dwDstLen += ProcessCharCode(&lpszDst[dwDstLen], (WORD)pSrcData[dwSrcPos], CurCodeSet);
					}
				}
			else if((pSrcData[dwSrcPos] >= 0xA1U) && (pSrcData[dwSrcPos] <= 0xFEU)){
				// GR椞堟
				const CODE_SET CurCodeSet = *m_pLockingGR;
				
				if(abCharSizeTable[CurCodeSet]){
					// 2僶僀僩僐乕僪
					if((dwSrcLen - dwSrcPos) < 2UL)break;
					
					dwDstLen += ProcessCharCode(&lpszDst[dwDstLen], ((WORD)(pSrcData[dwSrcPos + 0] & 0x7FU) << 8) | (WORD)(pSrcData[dwSrcPos + 1] & 0x7FU), CurCodeSet);
					dwSrcPos++;
					}
				else{
					// 1僶僀僩僐乕僪
					dwDstLen += ProcessCharCode(&lpszDst[dwDstLen], (WORD)(pSrcData[dwSrcPos] & 0x7FU), CurCodeSet);
					}
				}
			else{
				// 惂屼僐乕僪
				switch(pSrcData[dwSrcPos]){
					case 0x0FU	: LockingShiftGL(0U);				break;	// LS0
					case 0x0EU	: LockingShiftGL(1U);				break;	// LS1
					case 0x19U	: SingleShiftGL(2U);				break;	// SS2
					case 0x1DU	: SingleShiftGL(3U);				break;	// SS3
					case 0x1BU	: m_byEscSeqCount = 1U;				break;	// ESC
					case 0x20U	:
					case 0xA0U	: lpszDst[dwDstLen++] = TEXT(' ');	break;	// SP
					default		: break;	// 旕懳墳
					}
				}
			}
		else{
			// 僄僗働乕僾僔乕働儞僗張棟
			ProcessEscapeSeq(pSrcData[dwSrcPos]);
			}
		
		dwSrcPos++;
		}

	// 廔抂暥帤
	lpszDst[dwDstLen] = TEXT('\0');

	return dwDstLen;
}

inline const DWORD CAribString::ProcessCharCode(TCHAR *lpszDst, const WORD wCode, const CODE_SET CodeSet)
{
	switch(CodeSet){
		case CODE_KANJI	:
		case CODE_JIS_KANJI_PLANE_1 :
		case CODE_JIS_KANJI_PLANE_2 :
			// 娍帤僐乕僪弌椡
			return PutKanjiChar(lpszDst, wCode);

		case CODE_ALPHANUMERIC :
		case CODE_PROP_ALPHANUMERIC :
			// 塸悢帤僐乕僪弌椡
			return PutAlphanumericChar(lpszDst, wCode);

		case CODE_HIRAGANA :
		case CODE_PROP_HIRAGANA :
			// 傂傜偑側僐乕僪弌椡
			return PutHiraganaChar(lpszDst, wCode);

		case CODE_PROP_KATAKANA :
		case CODE_KATAKANA :
			// 僇僞僇僫僐乕僪弌椡
			return PutKatakanaChar(lpszDst, wCode);

		case CODE_JIS_X0201_KATAKANA :
			// JIS僇僞僇僫僐乕僪弌椡
			return PutJisKatakanaChar(lpszDst, wCode);

		case CODE_ADDITIONAL_SYMBOLS :
			// 捛壛僔儞儃儖僐乕僪弌椡
			return PutSymbolsChar(lpszDst, wCode);

		default :
			return 0UL;
		}
}

inline const DWORD CAribString::PutKanjiChar(TCHAR *lpszDst, const WORD wCode)
{
	// JIS仺Shift-JIS娍帤僐乕僪曄姺
	const WORD wShiftJIS = ::_mbcjistojms(wCode);

#ifdef _UNICODE
	// Shift-JIS 仺 UNICODE
	const char szShiftJIS[3] = {(char)(wShiftJIS >> 8), (char)(wShiftJIS & 0x00FFU), '\0'};
	::MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, szShiftJIS, 2, lpszDst, 2);

	return 1UL;
#else
	// Shift-JIS 仺 Shift-JIS
	lpszDst[0] = (char)(wShiftJIS >> 8);
	lpszDst[1] = (char)(wShiftJIS & 0x00FFU);

	return 2UL;
#endif
}

inline const DWORD CAribString::PutAlphanumericChar(TCHAR *lpszDst, const WORD wCode)
{
	// 塸悢帤暥帤僐乕僪曄姺
	static const TCHAR *acAlphanumericTable = 
		TEXT("丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂")
		TEXT("丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂")
		TEXT("丂両乭仈亹亾仌乫乮乯仏亄丆亅丏乛")
		TEXT("侽侾俀俁係俆俇俈俉俋丗丟亙亖亜丠")
		TEXT("仐俙俛俠俢俤俥俧俫俬俰俲俴俵俶俷")
		TEXT("俹俻俼俽俿倀倁倂倃倄倅乵亸乶丱丵")
		TEXT("丂倎倐們倓倕倖倗倛倝倢倠倢倣値倧")
		TEXT("倫倯倰倱倲倳倴倵倶倷倸乷乥乸丳丂");

#ifdef _UNICODE
	lpszDst[0] = acAlphanumericTable[wCode];

	return 1UL;
#else
	lpszDst[0] = acAlphanumericTable[wCode * 2U + 0U];
	lpszDst[1] = acAlphanumericTable[wCode * 2U + 1U];

	return 2UL;
#endif
}

inline const DWORD CAribString::PutHiraganaChar(TCHAR *lpszDst, const WORD wCode)
{
	// 傂傜偑側暥帤僐乕僪曄姺
	static const TCHAR *acHiraganaTable = 
		TEXT("丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂")
		TEXT("丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂")
		TEXT("丂偀偁偂偄偅偆偉偊偋偍偐偑偒偓偔")
		TEXT("偖偗偘偙偛偝偞偟偠偡偢偣偤偦偧偨")
		TEXT("偩偪偫偭偮偯偰偱偲偳側偵偸偹偺偼")
		TEXT("偽傁傂傃傄傆傇傉傊傋傌傎傏傐傑傒")
		TEXT("傓傔傕傖傗傘備傚傛傜傝傞傟傠傡傢")
		TEXT("傤傦傪傫丂丂丂乀乁乕丅乽乿丄丒丂");
	
#ifdef _UNICODE
	lpszDst[0] = acHiraganaTable[wCode];

	return 1UL;
#else
	lpszDst[0] = acHiraganaTable[wCode * 2U + 0U];
	lpszDst[1] = acHiraganaTable[wCode * 2U + 1U];

	return 2UL;
#endif
}

inline const DWORD CAribString::PutKatakanaChar(TCHAR *lpszDst, const WORD wCode)
{
	// 僇僞僇僫塸悢帤暥帤僐乕僪曄姺
	static const TCHAR *acKatakanaTable = 
		TEXT("丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂")
		TEXT("丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂")
		TEXT("丂傽傾傿僀僁僂僃僄僅僆僇僈僉僊僋")
		TEXT("僌働僎僐僑僒僓僔僕僗僘僙僛僜僝僞")
		TEXT("僟僠僡僢僣僤僥僨僩僪僫僯僰僱僲僴")
		TEXT("僶僷僸價僺僼僽僾僿儀儁儂儃億儅儈")
		TEXT("儉儊儌儍儎儏儐儑儓儔儕儖儗儘儙儚")
		TEXT("儛儜儝儞償儠儢丷丼乕丅乽乿丄丒丂");
	
#ifdef _UNICODE
	lpszDst[0] = acKatakanaTable[wCode];

	return 1UL;
#else
	lpszDst[0] = acKatakanaTable[wCode * 2U + 0U];
	lpszDst[1] = acKatakanaTable[wCode * 2U + 1U];

	return 2UL;
#endif
}

inline const DWORD CAribString::PutJisKatakanaChar(TCHAR *lpszDst, const WORD wCode)
{
	// JIS僇僞僇僫暥帤僐乕僪曄姺
	static const TCHAR *acJisKatakanaTable = 
		TEXT("丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂")
		TEXT("丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂")
		TEXT("丂丅乽乿丄丒儝傽傿僁僃僅儍儏儑僢")
		TEXT("乕傾僀僂僄僆僇僉僋働僐僒僔僗僙僜")
		TEXT("僞僠僣僥僩僫僯僰僱僲僴僸僼僿儂儅")
		TEXT("儈儉儊儌儎儐儓儔儕儖儗儘儚儞丣並")
		TEXT("丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂")
		TEXT("丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂");
	
#ifdef _UNICODE
	lpszDst[0] = acJisKatakanaTable[wCode];

	return 1UL;
#else
	lpszDst[0] = acJisKatakanaTable[wCode * 2U + 0U];
	lpszDst[1] = acJisKatakanaTable[wCode * 2U + 1U];

	return 2UL;
#endif
}

inline const DWORD CAribString::PutSymbolsChar(TCHAR *lpszDst, const WORD wCode)
{
	// 捛壛僔儞儃儖暥帤僐乕僪曄姺(偲傝偁偊偢昁梫偦偆側傕偺偩偗)
	static const TCHAR *aszSymbolsTable1[] =
	{
		_T("[HV]"),		_T("[SD]"),		_T("[俹]"),		_T("[倂]"),		_T("[MV]"),		_T("[庤]"),		_T("[帤]"),		_T("[憃]"),			// 0x7A50 - 0x7A57	90/48 - 90/55
		_T("[僨]"),		_T("[俽]"),		_T("[擇]"),		_T("[懡]"),		_T("[夝]"),		_T("[SS]"),		_T("[俛]"),		_T("[俶]"),			// 0x7A58 - 0x7A5F	90/56 - 90/63
		_T("仭"),		_T("仠"),		_T("[揤]"),		_T("[岎]"),		_T("[塮]"),		_T("[柍]"),		_T("[椏]"),		_T("[擭楊惂尷]"),	// 0x7A60 - 0x7A67	90/64 - 90/71
		_T("[慜]"),		_T("[屻]"),		_T("[嵞]"),		_T("[怴]"),		_T("[弶]"),		_T("[廔]"),		_T("[惗]"),		_T("[斕]"),			// 0x7A68 - 0x7A6F	90/72 - 90/79
		_T("[惡]"),		_T("[悂]"),		_T("[PPV]"),	_T("(旈)"),		_T("傎偐")															// 0x7A70 - 0x7A74	90/80 - 90/84
	};

	static const TCHAR *aszSymbolsTable2[] =
	{
		_T("仺"),		_T("仼"),		_T("仾"),		_T("伀"),		_T("仠"),		_T("仜"),		_T("擭"),		_T("寧"),			// 0x7C21 - 0x7C28	92/01 - 92/08
		_T("擔"),		_T("墌"),		_T("噓"),		_T("棫曽倣"),	_T("噋"),		_T("暯曽噋"),	_T("棫曽噋"),	_T("侽."),			// 0x7C29 - 0x7C30	92/09 - 92/16
		_T("侾."),		_T("俀."),		_T("俁."),		_T("係."),		_T("俆."),		_T("俇."),		_T("俈."),		_T("俉."),			// 0x7C31 - 0x7C38	92/17 - 92/24
		_T("俋."),		_T("巵"),		_T("暃"),		_T("尦"),		_T("屘"),		_T("慜"),		_T("怴"),		_T("侽,"),			// 0x7C39 - 0x7C40	92/25 - 92/32
		_T("侾,"),		_T("俀,"),		_T("俁,"),		_T("係,"),		_T("俆,"),		_T("俇,"),		_T("俈,"),		_T("俉,"),			// 0x7C41 - 0x7C48	92/33 - 92/40
		_T("俋,"),		_T("(幮)"),		_T("(嵿)"),		_T("(桳)"),		_T("(姅)"),		_T("(戙)"),		_T("(栤)"),		_T("亜"),			// 0x7C49 - 0x7C50	92/41 - 92/48
		_T("亙"),		_T("亂"),		_T("亃"),		_T("仦"),		_T("^2"),		_T("^3"),		_T("(CD)"),		_T("(vn)"),			// 0x7C51 - 0x7C58	92/49 - 92/56
		_T("(ob)"),		_T("(cb)"),		_T("(ce"),		_T("mb)"),		_T("(hp)"),		_T("(br)"),		_T("(p)"),		_T("(s)"),			// 0x7C59 - 0x7C60	92/57 - 92/64
		_T("(ms)"),		_T("(t)"),		_T("(bs)"),		_T("(b)"),		_T("(tb)"),		_T("(tp)"),		_T("(ds)"),		_T("(ag)"),			// 0x7C61 - 0x7C68	92/65 - 92/72
		_T("(eg)"),		_T("(vo)"),		_T("(fl)"),		_T("(ke"),		_T("y)"),		_T("(sa"),		_T("x)"),		_T("(sy"),			// 0x7C69 - 0x7C70	92/73 - 92/80
		_T("n)"),		_T("(or"),		_T("g)"),		_T("(pe"),		_T("r)"),		_T("(R)"),		_T("(C)"),		_T("(獾)"),			// 0x7C71 - 0x7C78	92/81 - 92/88
		_T("DJ"),		_T("[墘]"),		_T("Fax")																							// 0x7C79 - 0x7C7B	92/89 - 92/91
	};

	static const TCHAR *aszSymbolsTable3[] =
	{
		_T("(寧)"),		_T("(壩)"),		_T("(悈)"),		_T("(栘)"),		_T("(嬥)"),		_T("(搚)"),		_T("(擔)"),		_T("(廽)"),			// 0x7D21 - 0x7D28	93/01 - 93/08
		_T("噸"),		_T("噹"),		_T("噺"),		_T("噡"),		_T("噦"),		_T("噭"),		_T("(仹)"),		_T("仜"),			// 0x7D29 - 0x7D30	93/09 - 93/16
		_T("乲杮乴"),	_T("乲嶰乴"),	_T("乲擇乴"),	_T("乲埨乴"),	_T("乲揰乴"),	_T("乲懪乴"),	_T("乲搻乴"),	_T("乲彑乴"),		// 0x7D31 - 0x7D38	93/17 - 93/24
		_T("乲攕乴"),	_T("乲俽乴"),	_T("乵搳乶"),	_T("乵曔乶"),	_T("乵堦乶"),	_T("乵擇乶"),	_T("乵嶰乶"),	_T("乵梀乶"),		// 0x7D39 - 0x7D40	93/25 - 93/32
		_T("乵嵍乶"),	_T("乵拞乶"),	_T("乵塃乶"),	_T("乵巜乶"),	_T("乵憱乶"),	_T("乵懪乶"),	_T("噂"),		_T("噑"),			// 0x7D41 - 0x7D48	93/33 - 93/40
		_T("Hz"),		_T("ha"),		_T("km"),		_T("暯曽km"),	_T("hPa"),		_T("丒"),		_T("丒"),		_T("1/2"),			// 0x7D49 - 0x7D50	93/41 - 93/48
		_T("0/3"),		_T("1/3"),		_T("2/3"),		_T("1/4"),		_T("3/4"),		_T("1/5"),		_T("2/5"),		_T("3/5"),			// 0x7D51 - 0x7D58	93/49 - 93/56
		_T("4/5"),		_T("1/6"),		_T("5/6"),		_T("1/7"),		_T("1/8"),		_T("1/9"),		_T("1/10"),		_T("惏傟"),			// 0x7D59 - 0x7D60	93/57 - 93/64
		_T("撥傝"),		_T("塉"),		_T("愥"),		_T("仮"),		_T("仯"),		_T("仱"),		_T("仴"),		_T("仧"),			// 0x7D61 - 0x7D68	93/65 - 93/72
		_T("丒"),		_T("丒"),		_T("丒"),		_T("仦"),		_T("仢"),		_T("!!"),		_T("!?"),		_T("撥/惏"),		// 0x7D69 - 0x7D70	93/73 - 93/80
		_T("塉"),		_T("塉"),		_T("愥"),		_T("戝愥"),		_T("棆"),		_T("棆塉"),		_T("丂"),		_T("丒"),			// 0x7D71 - 0x7D78	93/81 - 93/88
		_T("丒"),		_T("侓"),		_T("噭")																							// 0x7D79 - 0x7D7B	93/89 - 93/91
	};

	static const TCHAR *aszSymbolsTable4[] =
	{
		_T("嘥"),		_T("嘦"),		_T("嘨"),		_T("嘩"),		_T("嘪"),		_T("嘫"),		_T("嘮"),		_T("嘯"),			// 0x7E21 - 0x7E28	94/01 - 94/08
		_T("嘰"),		_T("嘳"),		_T("XI"),		_T("X嘦"),		_T("嘝"),		_T("嘠"),		_T("嘡"),		_T("嘢"),			// 0x7E29 - 0x7E30	94/09 - 94/16
		_T("(1)"),		_T("(2)"),		_T("(3)"),		_T("(4)"),		_T("(5)"),		_T("(6)"),		_T("(7)"),		_T("(8)"),			// 0x7E31 - 0x7E38	94/17 - 94/24
		_T("(9)"),		_T("(10)"),		_T("(11)"),		_T("(12)"),		_T("(21)"),		_T("(22)"),		_T("(23)"),		_T("(24)"),			// 0x7E39 - 0x7E40	94/25 - 94/32
		_T("(A)"),		_T("(B)"),		_T("(C)"),		_T("(D)"),		_T("(E)"),		_T("(F)"),		_T("(G)"),		_T("(H)"),			// 0x7E41 - 0x7E48	94/33 - 94/40
		_T("(I)"),		_T("(J)"),		_T("(K)"),		_T("(L)"),		_T("(M)"),		_T("(N)"),		_T("(O)"),		_T("(P)"),			// 0x7E49 - 0x7E50	94/41 - 94/48
		_T("(Q)"),		_T("(R)"),		_T("(S)"),		_T("(T)"),		_T("(U)"),		_T("(V)"),		_T("(W)"),		_T("(X)"),			// 0x7E51 - 0x7E58	94/49 - 94/56
		_T("(Y)"),		_T("(Z)"),		_T("(25)"),		_T("(26)"),		_T("(27)"),		_T("(28)"),		_T("(29)"),		_T("(30)"),			// 0x7E59 - 0x7E60	94/57 - 94/64
		_T("嘆"),		_T("嘇"),		_T("嘊"),		_T("嘋"),		_T("嘍"),		_T("嘐"),		_T("嘑"),		_T("嘒"),			// 0x7E61 - 0x7E68	94/65 - 94/72
		_T("嘓"),		_T("嘔"),		_T("嘕"),		_T("嘖"),		_T("嘗"),		_T("嘙"),		_T("嘚"),		_T("嘜"),			// 0x7E69 - 0x7E70	94/73 - 94/80
		_T("嘆"),		_T("嘇"),		_T("嘊"),		_T("嘋"),		_T("嘍"),		_T("嘐"),		_T("嘑"),		_T("嘒"),			// 0x7E71 - 0x7E78	94/81 - 94/88
		_T("嘓"),		_T("嘔"),		_T("嘕"),		_T("嘖"),		_T("(31)")															// 0x7E79 - 0x7E7D	94/89 - 94/93
	};

	// 僔儞儃儖傪曄姺偡傞
	if((wCode >= 0x7A50U) && (wCode <= 0x7A74U)){
		::lstrcpy(lpszDst, aszSymbolsTable1[wCode - 0x7A50U]);
		}
	else if((wCode >= 0x7C21U) && (wCode <= 0x7C7BU)){
		::lstrcpy(lpszDst, aszSymbolsTable2[wCode - 0x7C21U]);
		}
	else if((wCode >= 0x7D21U) && (wCode <= 0x7D7BU)){
		::lstrcpy(lpszDst, aszSymbolsTable3[wCode - 0x7D21U]);
		}
	else if((wCode >= 0x7E21U) && (wCode <= 0x7E7DU)){
		::lstrcpy(lpszDst, aszSymbolsTable4[wCode - 0x7E21U]);
		}
	else{
		::lstrcpy(lpszDst, TEXT("丒"));
		}

	return ::lstrlen(lpszDst);
}

inline void CAribString::ProcessEscapeSeq(const BYTE byCode)
{
	// 僄僗働乕僾僔乕働儞僗張棟
	switch(m_byEscSeqCount){
		// 1僶僀僩栚
		case 1U	:
			switch(byCode){
				// Invocation of code elements
				case 0x6EU	: LockingShiftGL(2U);	m_byEscSeqCount = 0U;	return;		// LS2
				case 0x6FU	: LockingShiftGL(3U);	m_byEscSeqCount = 0U;	return;		// LS3
				case 0x7EU	: LockingShiftGR(1U);	m_byEscSeqCount = 0U;	return;		// LS1R
				case 0x7DU	: LockingShiftGR(2U);	m_byEscSeqCount = 0U;	return;		// LS2R
				case 0x7CU	: LockingShiftGR(3U);	m_byEscSeqCount = 0U;	return;		// LS3R

				// Designation of graphic sets
				case 0x24U	:	
				case 0x28U	: m_byEscSeqIndex = 0U;		break;
				case 0x29U	: m_byEscSeqIndex = 1U;		break;
				case 0x2AU	: m_byEscSeqIndex = 2U;		break;
				case 0x2BU	: m_byEscSeqIndex = 3U;		break;
				default		: m_byEscSeqCount = 0U;		return;		// 僄儔乕
				}
			break;

		// 2僶僀僩栚
		case 2U	:
			if(DesignationGSET(m_byEscSeqIndex, byCode)){
				m_byEscSeqCount = 0U;
				return;
				}
			
			switch(byCode){
				case 0x20	: m_bIsEscSeqDrcs = true;	break;
				case 0x28	: m_bIsEscSeqDrcs = true;	m_byEscSeqIndex = 0U;	break;
				case 0x29	: m_bIsEscSeqDrcs = false;	m_byEscSeqIndex = 1U;	break;
				case 0x2A	: m_bIsEscSeqDrcs = false;	m_byEscSeqIndex = 2U;	break;
				case 0x2B	: m_bIsEscSeqDrcs = false;	m_byEscSeqIndex = 3U;	break;
				default		: m_byEscSeqCount = 0U;		return;		// 僄儔乕
				}
			break;

		// 3僶僀僩栚
		case 3U	:
			if(!m_bIsEscSeqDrcs){
				if(DesignationGSET(m_byEscSeqIndex, byCode)){
					m_byEscSeqCount = 0U;
					return;
					}
				}
			else{
				if(DesignationDRCS(m_byEscSeqIndex, byCode)){
					m_byEscSeqCount = 0U;
					return;
					}
				}

			if(byCode == 0x20U){
				m_bIsEscSeqDrcs = true;
				}
			else{
				// 僄儔乕
				m_byEscSeqCount = 0U;
				return;
				}
			break;

		// 4僶僀僩栚
		case 4U	:
			DesignationDRCS(m_byEscSeqIndex, byCode);
			m_byEscSeqCount = 0U;
			return;
		}

	m_byEscSeqCount++;
}

inline void CAribString::LockingShiftGL(const BYTE byIndexG)
{
	// LSx
	m_pLockingGL = &m_CodeG[byIndexG];
}

inline void CAribString::LockingShiftGR(const BYTE byIndexG)
{
	// LSxR
	m_pLockingGR = &m_CodeG[byIndexG];
}

inline void CAribString::SingleShiftGL(const BYTE byIndexG)
{
	// SSx
	m_pSingleGL  = &m_CodeG[byIndexG];
}

inline const bool CAribString::DesignationGSET(const BYTE byIndexG, const BYTE byCode)
{
	// G偺僌儔僼傿僢僋僙僢僩傪妱傝摉偰傞
	switch(byCode){
		case 0x42U	: m_CodeG[byIndexG] = CODE_KANJI;				return true;	// Kanji
		case 0x4AU	: m_CodeG[byIndexG] = CODE_ALPHANUMERIC;		return true;	// Alphanumeric
		case 0x30U	: m_CodeG[byIndexG] = CODE_HIRAGANA;			return true;	// Hiragana
		case 0x31U	: m_CodeG[byIndexG] = CODE_KATAKANA;			return true;	// Katakana
		case 0x32U	: m_CodeG[byIndexG] = CODE_MOSAIC_A;			return true;	// Mosaic A
		case 0x33U	: m_CodeG[byIndexG] = CODE_MOSAIC_B;			return true;	// Mosaic B
		case 0x34U	: m_CodeG[byIndexG] = CODE_MOSAIC_C;			return true;	// Mosaic C
		case 0x35U	: m_CodeG[byIndexG] = CODE_MOSAIC_D;			return true;	// Mosaic D
		case 0x36U	: m_CodeG[byIndexG] = CODE_PROP_ALPHANUMERIC;	return true;	// Proportional Alphanumeric
		case 0x37U	: m_CodeG[byIndexG] = CODE_PROP_HIRAGANA;		return true;	// Proportional Hiragana
		case 0x38U	: m_CodeG[byIndexG] = CODE_PROP_KATAKANA;		return true;	// Proportional Katakana
		case 0x49U	: m_CodeG[byIndexG] = CODE_JIS_X0201_KATAKANA;	return true;	// JIS X 0201 Katakana
		case 0x39U	: m_CodeG[byIndexG] = CODE_JIS_KANJI_PLANE_1;	return true;	// JIS compatible Kanji Plane 1
		case 0x3AU	: m_CodeG[byIndexG] = CODE_JIS_KANJI_PLANE_2;	return true;	// JIS compatible Kanji Plane 2
		case 0x3BU	: m_CodeG[byIndexG] = CODE_ADDITIONAL_SYMBOLS;	return true;	// Additional symbols
		default		: return false;		// 晄柧側僌儔僼傿僢僋僙僢僩
		}
}

inline const bool CAribString::DesignationDRCS(const BYTE byIndexG, const BYTE byCode)
{
	// DRCS偺僌儔僼傿僢僋僙僢僩傪妱傝摉偰傞
	switch(byCode){
		case 0x40U	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-0
		case 0x41U	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-1
		case 0x42U	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-2
		case 0x43U	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-3
		case 0x44U	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-4
		case 0x45U	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-5
		case 0x46U	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-6
		case 0x47U	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-7
		case 0x48U	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-8
		case 0x49U	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-9
		case 0x4AU	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-10
		case 0x4BU	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-11
		case 0x4CU	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-12
		case 0x4DU	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-13
		case 0x4EU	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-14
		case 0x4FU	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// DRCS-15
		case 0x70U	: m_CodeG[byIndexG] = CODE_UNKNOWN;				return true;	// Macro
		default		: return false;		// 晄柧側僌儔僼傿僢僋僙僢僩
		}
}
