//
// Character
//
static void FmtChar(StringBuffer   & oBuffer,
                    const CDT      & oCurrentArgument,
                    const UINT_32    iFmtFlags,
                    const INT_32     iWidth,
                    CHAR_8           chPadSymbol)
{
	const CDT::eValType oValType = oCurrentArgument.GetType();
	if (oValType == CDT::UNDEF && iWidth > 0)
	{
		oBuffer.Append(iWidth, chPadSymbol);
		return;
	}

	UCHAR_8 ucTMP = ' ';
	if (oValType == CDT::INT_VAL || oValType == CDT::REAL_VAL)
	{
		ucTMP = oCurrentArgument.GetInt();
	}
	else if (oValType == CDT::STRING_VAL)
	{
		const STLW::string sTMP = oCurrentArgument.GetString();
		if (sTMP.empty() && iWidth > 0)
		{
			oBuffer.Append(iWidth, chPadSymbol);
			return;
		}
		ucTMP = sTMP[0];
	}
	else if (oValType == CDT::POINTER_VAL) { ucTMP = 'P'; }
	else if (oValType == CDT::ARRAY_VAL)   { ucTMP = 'A'; }
	else if (oValType == CDT::HASH_VAL)    { ucTMP = 'H'; }

	if (iFmtFlags & F_LEFT_ALIGN)
	{
		oBuffer.Append(1, ucTMP);
		if (iWidth > 1) { oBuffer.Append(iWidth - 1, chPadSymbol); }
	}
	else
	{
		if (iWidth > 1) { oBuffer.Append(iWidth - 1, chPadSymbol); }
		oBuffer.Append(1, ucTMP);
	}
}
//
// Integer
//
static void FmtInt(StringBuffer        & oBuffer,
                   const CDT           & oCurrentArgument,
                   const UINT_32         iFmtFlags,
                   const eFmtLengths   & oFmtLengths,
                   CCHAR_P               szDigits,
                   const eFmtSpecifier & oFmtSpecifier,
                   const INT_32          iRadix,
                   INT_32                iWidth,
                   INT_32                iPrecision,
                   CHAR_8                chPadSymbol)
{
	if (iWidth < 0)     { iWidth = 0; }
	if (iPrecision < 0) { iPrecision = 0; }

	CHAR_8 szBuffer[C_INT_BUFFER_LEN + 1];
	szBuffer[C_INT_BUFFER_LEN] = 0;
	INT_32 iPos      = 0;
	bool bIsNegative = false;
	// Signed
	if (oFmtSpecifier == F_DECIMAL)
	{
		switch (oFmtLengths)
		{
			case F_NONE:
			case F_LONG:
				iPos = DoFormat<INT_32>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
				break;
			case F_SHORT:
				iPos = DoFormat<INT_16>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
				break;
			case F_LONG_LONG:
				iPos = DoFormat<INT_64>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
				break;
		}
	}
	// Unsigned, hex, octal
	else
	{
		switch (oFmtLengths)
		{
			case F_NONE:
			case F_LONG:
				iPos = DoFormat<UINT_32>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
				break;
			case F_SHORT:
				iPos = DoFormat<UINT_16>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
				break;
			case F_LONG_LONG:
				iPos = DoFormat<UINT_64>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
				break;
		}
	}

	UINT_32 iBufferPos = C_INT_BUFFER_LEN - iPos;
	// Left-aligned output
	if (iFmtFlags & F_LEFT_ALIGN || chPadSymbol == '0')
	{
		// Sign
		if      (bIsNegative)              { oBuffer.Append(1, '-'); --iWidth; }
		else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); --iWidth; }
		else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); --iWidth; }

		// Hash
		if (iFmtFlags & F_HASH_SIGN)
		{
			if      (oFmtSpecifier == F_OCTAL)
			{
				oBuffer.Append(1, '0');
			}
			else if (oFmtSpecifier == F_HEX || oFmtSpecifier == F_POINTER)
			{
				oBuffer.Append(1, '0');
				oBuffer.Append(1, szDigits[16]);
			}
		}

		// Zeroes, if need
		if (iPrecision > iPos)
		{
			iWidth -= (iPrecision - iPos);
			oBuffer.Append(iPrecision - iPos, '0');
		}

		if (chPadSymbol == '0')
		{
			// Spaces, if need
			if (iWidth > iPos) { oBuffer.Append(iWidth - iPos, '0'); }
			// Value
			oBuffer.Append(szBuffer + iBufferPos, iPos);
		}
		else
		{
			// Value
			oBuffer.Append(szBuffer + iBufferPos, iPos);
			// Spaces, if need
			if (iWidth > iPos) { oBuffer.Append(iWidth - iPos, ' '); }
		}
		return;
	}

	// Right-aligned
	INT_32 iFormattedLength = iPos;

	// Precision
	if (iPrecision > iPos)
	{
		iFormattedLength += (iPrecision - iPos);
	}

	// Sign?
	if (bIsNegative || iFmtFlags & (F_FORCE_SIGN | F_SIGN_SPACE)) { ++iFormattedLength; }

	// Hash
	if (iFmtFlags & F_HASH_SIGN)
	{
		if      (oFmtSpecifier == F_OCTAL)   { ++iFormattedLength; }
		else if (oFmtSpecifier == F_HEX ||
		         oFmtSpecifier == F_POINTER) { iFormattedLength += 2; }
	}

	// Spaces, if need
	if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); }

	// Sign
	if      (bIsNegative)              { oBuffer.Append(1, '-'); --iWidth; }
	else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); --iWidth; }
	else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); --iWidth; }

	// Hash
	if (iFmtFlags & F_HASH_SIGN)
	{
		if      (oFmtSpecifier == F_OCTAL)
		{
			oBuffer.Append(1, '0');
		}
		else if (oFmtSpecifier == F_HEX || oFmtSpecifier == F_POINTER)
		{
			oBuffer.Append(1, '0');
			oBuffer.Append(1, szDigits[16]);
		}
	}

	if (iPrecision > iPos) { oBuffer.Append(iPrecision - iPos, '0'); }
	// Value
	oBuffer.Append(szBuffer + iBufferPos, iPos);
}