Programming 版 (精华区)

发信人: SwordLea (飞刀李), 信区: Programming
标  题: [合集]自由打印函数
发信站: 哈工大紫丁香 (2004年01月15日11:15:49 星期四), 站内信件


────────────────────────────────────────
 jiaxuan (笑十子)                     于 Sat May 24 02:14:52 2003) 说道:

只剩浮点数没有测试过。其它的都试过了。
这个函数的一个主要作用是能方便地打印出结构中的元素。
如下所示:

typedef struct {
BYTE         bEle1;
BYTE         bEle2;
WORD         wEle3;
...
} MyStruct_T;

MyStruct_T   tMyStruct = {1, 2, 3, ...};
BYTE         baBuf[200];
tprintf(baBuf, 
    "MyStruct is {%a, %a, %2a, ...}", (BYTE *)&tMyStruct);

这样就避免了在代码中写很长的参数列表。默认的格式与普通的打印是兼容的。

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

/* Module Name: COMMON                        File Name: tprintf.c          */

/* Create Date: 2003-5-20 11:57               Author   : R.Z.Tian           */

/* Function   : print function from memory by format string                 */

/* Version    : 1.0                                                         */

/*--------------------------------------------------------------------------*/

/* History   : */
/* Date        Version  Person Activies                            */
/* 2003.05.20  1.0.0    RZ.Tian Create                              */
/*--------------------------------------------------------------------------*/


#define PrnWidthDft_M -1
#define PrnPreciDft_M 6
#define PrnTakeDataBytesDft_M 4
#define PrnTakeFloatBytesDft_M 4
#define PrnTakeCharBytesDft_M 1
#define PrnTakeImsiBytesDft_M 8
#define PrnTakeIpBytesDft_M 4
#define TEMP_BUF_SIZE_M 82

#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))

#define isDigit(a) \
(((a) <= '9') && ((a) >= '0'))

#define isLetter(a) \
((((a) <= 'z') && ((a) >= 'a')) || (((a) <= 'Z') && ((a) >= 'A')))

#define isPermitSpace(a) \
(((a) == ' ') || ((a) == '\t') || ((a) == '\n') || ((a) == '\v'))

#define isFormatEndChar(a) \
(((a) == 'd') || ((a) == 'u') || ((a) == 'x') || ((a) == 'X') || \
 ((a) == 'p') || ((a) == 's') || ((a) == 'k') || ((a) == 'z') || \
 ((a) == 'o') || ((a) == 'b') || ((a) == 'c') || ((a) == 'f') || \
 ((a) == 'e') || ((a) == 'E') || ((a) == 'g') || ((a) == 'G')) \

/*--------------------------------------------------------------------------*/

/* 格式化打印声明相关标志量及取得待打印操作数的相关控制变量结构 */
/*--------------------------------------------------------------------------*/

typedef struct
{
LONG lWidth; /* 打印数据宽度   */
LONG lPrecision; /* 数据精度 */

BYTE bType; /* 显示数据格式 */
BYTE bSubType; /* 显示数据子格式 */
BYTE bMod; /* 采用半长型或者长型打印标识 */
BYTE bTakeDataDecl; /* 取数据格式声明 */

BYTE bPreChar; /* 前导字符, ' '或'0'或无填充 */
BYTE bRight; /* 右对齐标志 */
BYTE bAlter; /* 非十进制数打印进制标识 */
BYTE bPlus; /* 打印正负号标识 */

BYTE bBigEndian; /* 取数阶标志 */
BYTE bBitTake; /* 按位取数标志 */
WORD wTakeBytes; /* 取数的字节数 */

BYTE bBitBigEndian; /* 按位取数阶标志 */
BYTE bRemainBits; /* 按位取数时剩余值有效比特数 */
WORD wTakeBits; /* 取数的比特数 */

DWORD dwRemainVal; /* 按位取数时剩余未用的值 */
DWORD dwReadVal; /* 待打印的数据值 */

} PrnFormatGlb_T;

typedef struct
{
DWORD dwH; /* 高阶字段值 */
DWORD dwL; /* 低阶字段值 */
} QWORD;

typedef struct
{
BYTE bNegtive; /* 正负数标识 */
LONG lPower; /* 数值阶 */
QWORD qwMantis; /* 尾数 */
} PFLOAT;

static BYTE sTempOutBuf[TEMP_BUF_SIZE_M * 2];

/*--------------------------------------------------------------------------*/

/* Function name : tranBits() */
/* Description   : 将数据按比特位逆序转换 */
/* Input         : dwTranVal - 待转换的数据        */
/*  : bBits - 数据的有效位数(待转换位数) */
/* Output  : 无 */
/* Return        : 无     */
/* Global Var    : 转换后的数 */
/* Author/Date   : R.Z.Tian/2003-5-22 08:22下午 */
/* Note          : 从低阶往高阶数比特位有效                                 */

/*--------------------------------------------------------------------------*/

static DWORD tranBits(DWORD dwTranVal, BYTE bBits)
{
BYTE bCount;
DWORD dwTempVal = 1, dwRetVal = 0;

for (bCount = 0; bCount < bBits / 2; bCount++, dwTempVal <<= 1)
{
dwRetVal += (dwTranVal & dwTempVal) << (bBits - 1 - bCount * 2);
dwRetVal += (dwTranVal >> (bBits - 1 - bCount * 2)) & dwTempVal;
}

return dwRetVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : GetTakeDataFormat() */
/* Description   : 获取从参数表中取数方式控制到打印控制结构 */
/* Input         : pbFmtStr - 格式控制串的起始地址 */
/*  : ppbData - 参数列表指针 */
/* Output  : ptFmt - 控制格式结构地址 */
/*  : ppbData - 参数列表指针 */
/* Return        : 下一个打印控制字符指针.    */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-20 11:57下午 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static char *GetTakeDataFormat(char *pbFmtStr, PrnFormatGlb_T *ptFmt, BYTE **p
pbData)
{
BYTE bTakeStep = 0, bTakeBytesDecl = 0, bTakeBitsDecl = 0;
char *pbRead = pbFmtStr;
LONG lFmtVal;

ptFmt->bBigEndian = 1;
ptFmt->wTakeBytes = PrnTakeCharBytesDft_M;

ptFmt->bBitTake = 0;
ptFmt->bBitBigEndian= 1;
ptFmt->wTakeBits = 0;

/*----------------------------------------------------------------------*/
/* 获得取数格式  ...(-  )(ddd)(.  (-  )(ddd))(a  )... */
/* 取数步骤:    s0   s1   s2   s3  s4   s5    s6  s7 */
/* 格式串最多有5个部分,在相应的状态如果取得的格式串与期望不符就退出 */
/*----------------------------------------------------------------------*/
while (pbRead[0] != '\0')
{
if (pbRead[0] == 'a')
{
pbRead++; break;
}

if (pbRead[0] == '-')
{
if (bTakeStep == 0)
{
bTakeStep = 1, ptFmt->bBigEndian = 0;
}
else if (bTakeStep == 3)
{
bTakeStep = 4, ptFmt->bBitBigEndian = 0;
}
else
{
break;
}

pbRead++; continue;
}

if (pbRead[0] == '.')
{
if (bTakeStep < 3)
{
bTakeStep = 3, ptFmt->bBitTake = 1;
}
else
{
break;
}

pbRead++; continue;
}

if (pbRead[0] == '*' || isDigit(pbRead[0]))
{
/*--------------------------------------------------------------*/
/* 取得数据长度,从格式串中取或者从参数列表中取 */
/*--------------------------------------------------------------*/
if (pbRead[0] == '*')
{
lFmtVal = (LONG)(*(SHORT *)(*ppbData)), *ppbData += 2, pbRead++;
}
else for (lFmtVal = 0; isDigit(pbRead[0]); pbRead++)
{
lFmtVal = lFmtVal * 10 + (pbRead[0] - '0');
}

if (bTakeStep < 3)
{
bTakeStep == 2, bTakeBytesDecl = 1;
if (lFmtVal < 0)
{
ptFmt->wTakeBytes = (WORD)(-lFmtVal), ptFmt->bBigEndian = 0;
}
else
{
ptFmt->wTakeBytes = (WORD)lFmtVal;
}
ptFmt->wTakeBytes = min(ptFmt->wTakeBytes, 0x1000);
}
else /* if (bTakeStep >= 3 && bTakeStep < 5) */
{
bTakeStep = 5, bTakeBitsDecl = 1;
if (lFmtVal < 0)
{
ptFmt->wTakeBits = (WORD)(-lFmtVal), ptFmt->bBitBigEndian = 0;
}
else
{
ptFmt->wTakeBits = (WORD)lFmtVal;
}
ptFmt->wTakeBits = min(ptFmt->wTakeBits, 0x1000);
}

ptFmt->bTakeDataDecl = 1;
continue;
}
else if (0 /* isPermitSpace(pbRead[0]) */)
{
pbRead++; continue;
}

break;
}

/*----------------------------------------------------------------------*/
/* 如果未声明取多少字节而又声明按位取操作数,则根据需求进行校验 */
/*----------------------------------------------------------------------*/
if (ptFmt->bBitTake)
{
if (!bTakeBitsDecl)
{
ptFmt->wTakeBits = 8;
}

if (!bTakeBytesDecl && ptFmt->bRemainBits >= ptFmt->wTakeBits)
{
ptFmt->wTakeBytes = 0;
}
else if (!bTakeBytesDecl)
{
ptFmt->bRemainBits = 0;
ptFmt->dwRemainVal = 0;
ptFmt->wTakeBytes = (ptFmt->wTakeBits - ptFmt->bRemainBits + 7) / 8;
}
}

return pbRead;
}

/*--------------------------------------------------------------------------*/

/* Function name : TakeDataByFormat() */
/* Description   : 按照格式控制符从内存地址中取数据 */
/* Input         : ptFmt - 控制格式结构地址 */
/*  : ppbDataAddr - 取数开始位置地址指针 */
/* Output  : 无 */
/* Return        : 下一个取数地址指针.     */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 12:15上午 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static LONG TakeDataByFormat(PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD w
DataLen)
{
int i;
WORD wTakeBytes = ptFmt->wTakeBytes;
WORD wTakeBits = ptFmt->wTakeBits, wReadBits;
BYTE *pbData = *ppbDataAddr, bReadChar;
DWORD dwReadVal = 0;

/*----------------------------------------------------------------------*/
/* 不按位取数,清空按位取数的保留值,取数溢出时只保留低位有效值 */
/*----------------------------------------------------------------------*/
if (!ptFmt->bBitTake)
{
ptFmt->dwRemainVal = 0;
ptFmt->bRemainBits = 0;

for (i = 0; i < ptFmt->wTakeBytes && i < wDataLen; i++)
{
if (ptFmt->bBigEndian)
{
dwReadVal = (dwReadVal << 8) + *pbData++;
}
else
{
dwReadVal += ((*pbData++) << (i * 8));
}
}

ptFmt->dwReadVal = dwReadVal, *ppbDataAddr = pbData;

return 0;
}

/*----------------------------------------------------------------------*/
/* 检验要取的比特数的有效性 */
/*----------------------------------------------------------------------*/
if (wTakeBits > wTakeBytes * 8 + ptFmt->bRemainBits)
{
wTakeBits = wTakeBytes * 8 + ptFmt->bRemainBits;
}
else if (ptFmt->bRemainBits >= wTakeBits)
{
ptFmt->bRemainBits -= wTakeBits;

if (ptFmt->bBigEndian)
{
dwReadVal = ptFmt->dwRemainVal >> ptFmt->bRemainBits;
if (ptFmt->bRemainBits < 32)
{
ptFmt->dwRemainVal &= (1 << (ptFmt->bRemainBits)) - 1;
}
}
else
{
if (wTakeBits < 32)
{
dwReadVal = ptFmt->dwRemainVal & ((1 << wTakeBits) - 1);
}
else
{
dwReadVal = ptFmt->dwRemainVal;
}
ptFmt->dwRemainVal >>= wTakeBits;
}

ptFmt->dwReadVal = dwReadVal, *ppbDataAddr = pbData;

return 1;
}

dwReadVal = ptFmt->dwRemainVal, wReadBits = (WORD)ptFmt->bRemainBits;

/*----------------------------------------------------------------------*/
/* 进行取数操作,边取数边取比特数 */
/*----------------------------------------------------------------------*/
for (i = 0; i < wTakeBytes && i < wDataLen; i++, ptFmt->bRemainBits += 8)
{
bReadChar = *pbData++;

if (!ptFmt->bBitBigEndian)
{
bReadChar = (BYTE)tranBits((DWORD)bReadChar, 8);
}

if (ptFmt->bBigEndian)
{
ptFmt->dwRemainVal = (ptFmt->dwRemainVal << 8) + bReadChar;
if (wReadBits + 8 <= wTakeBits)
{
wReadBits += 8;
dwReadVal = (dwReadVal << 8) + bReadChar;
}
else if (wReadBits < wTakeBits)
{
dwReadVal = (dwReadVal << (wTakeBits - wReadBits)) +
(bReadChar >> (8 - (wTakeBits - wReadBits)));
wReadBits = wTakeBits;
}
}
else
{
ptFmt->dwRemainVal += (bReadChar << ptFmt->bRemainBits);
if (wReadBits + 8 <= wTakeBits)
{
wReadBits += 8;
dwReadVal += (bReadChar << ptFmt->bRemainBits);
}
else if (wReadBits < wTakeBits)
{
dwReadVal += (bReadChar << ptFmt->bRemainBits);
if (wTakeBits < 32)
{
dwReadVal &= (1 << wTakeBits) - 1;
}
wReadBits = wTakeBits;
}
}
}

/*----------------------------------------------------------------------*/
/* 修正剩余量 */
/*----------------------------------------------------------------------*/
ptFmt->bRemainBits -= wTakeBits;

if (ptFmt->bBigEndian)
{
if (ptFmt->bRemainBits < 32)
{
ptFmt->dwRemainVal &= (1 << (ptFmt->bRemainBits)) - 1;
}
}
else
{
ptFmt->dwRemainVal >>= wTakeBits;
}

ptFmt->dwReadVal = dwReadVal;

/*
if (!ptFmt->bBitBigEndian)
{
ptFmt->dwReadVal = tranBits(dwReadVal, wTakeBits);
}
*/

*ppbDataAddr = pbData;

return 0;
}

/*--------------------------------------------------------------------------*/

/* Function name : ParsePercentFormat() */
/* Description   : 处理百分号'%'格式控制符 */
/* Input         : pbReadFmt - 当前的格式控制符位置指针 */
/*  : ppbData - 参数列表指针 */
/* Output  : ptFmt - 打印格式控制结构 */
/*  : ppbData - 参数列表指针 */
/* Return        : 下一个打印格式控制符的位置 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2002-01-16                                      */

/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static char *ParsePercentFormat(char *pbReadFmt, PrnFormatGlb_T *ptFmt, BYTE *
*ppbData)
{
BYTE bDataTypeDecl = 0;
BYTE bParseStep = 0;
char *pbRead = pbReadFmt;
BYTE *pbData = *ppbData;
LONG lFmtVal;

/*----------------------------------------------------------------------*/
/*  初始化打印描述结构             */
/*----------------------------------------------------------------------*/
ptFmt->lWidth = PrnWidthDft_M;
ptFmt->lPrecision = PrnWidthDft_M;

ptFmt->bType = 'd';
ptFmt->bSubType = '\0';
ptFmt->bMod = 'l';
ptFmt->bTakeDataDecl= 0;

ptFmt->bPreChar = ' ';
ptFmt->bRight = 1;
ptFmt->bAlter = 0;
ptFmt->bPlus = 0;

ptFmt->dwReadVal = 0;

/*----------------------------------------------------------------------*/
/* '%'后的格式说明,有两类,一类是取数的,一类是打印串,要区别对待 */
/*----------------------------------------------------------------------*/
while (pbRead[0] != '\0' && pbRead - pbReadFmt < 32 &&
(isDigit(pbRead[0]) || pbRead[0] == '*' ||
pbRead[0] == '.' || pbRead[0] == '-' /* || isPermitSpace(pbRead[0]) */))
{
pbRead++;
}

/*----------------------------------------------------------------------*/
/* 含有取数说明时,按其格式至数据表中取操作数,否则按默认值取数 */
/*----------------------------------------------------------------------*/
if (pbRead[0] == 'a')
{
pbRead = GetTakeDataFormat(pbReadFmt, ptFmt, ppbData);
}
else
{
ptFmt->bBigEndian = 1;
ptFmt->wTakeBytes = PrnTakeDataBytesDft_M;

ptFmt->bBitTake = 0;
ptFmt->bBitBigEndian= 1;
ptFmt->wTakeBits = 0,

ptFmt->bRemainBits = 0;
ptFmt->dwRemainVal = 0;

pbRead = pbReadFmt;
}

bParseStep = 1;

/*----------------------------------------------------------------------*/
/* 解析打印格式串 */
/*   获得取数格式  ...(*a)(-,+,#)(0  )(ddd)(.  (ddd))(h,l,L)(f  )... */
/*   取数步骤:    s0   s1  s2     s3   s4   s5  s6    s7    s8  s9 */
/* 格式串最多有5个部分,在相应的状态如果取得的格式串与期望不符就退出 */
/*----------------------------------------------------------------------*/
while (pbRead[0] != '\0')
{
/*------------------------------------------------------------------*/
/* 对齐符,符号显示,以及进制显示控制符不分先后,可有可无 */
/*------------------------------------------------------------------*/
if (pbRead[0] == '-' || pbRead[0] == '+' || pbRead[0] == '#')
{
if (bParseStep > 2)
{
break;
}

if (pbRead[0] == '-' && ptFmt->bRight)
{
ptFmt->bRight = 0;
}
else if (pbRead[0] == '-' && bParseStep == 2 && !ptFmt->bRight)
{
break;
}

if (pbRead[0] == '+' && !ptFmt->bPlus)
{
ptFmt->bPlus = 1;
}
else if (pbRead[0] == '+' && bParseStep == 2 && ptFmt->bPlus)
{
break;
}

if (pbRead[0] == '#' && !ptFmt->bAlter)
{
ptFmt->bAlter = 1;
}
else if (pbRead[0] == '#' && bParseStep == 2 && ptFmt->bAlter)
{
break;
}

bParseStep = 2; pbRead++; continue;
}

if (pbRead[0] == '0')
{
if (bParseStep <= 2)
{
ptFmt->bPreChar = pbRead[0];
}
else
{
break;
}

bParseStep = 3; pbRead++; continue;
}

if (pbRead[0] == '.')
{
if (bParseStep >= 5)
{
break;
}

bParseStep = 5; pbRead++; continue;
}

/*------------------------------------------------------------------*/
/* 取数据宽度,对于格式'*',从参数列表中取宽度指示(只认一个字节) */
/*------------------------------------------------------------------*/
if (pbRead[0] == '*' || isDigit(pbRead[0]))
{
/*--------------------------------------------------------------*/
/* 取得数据长度,从格式串中取或者从参数列表中取 */
/*--------------------------------------------------------------*/
if (pbRead[0] == '*')
{
lFmtVal = (LONG)(*(SHORT *)(*ppbData)), *ppbData += 2, pbRead++;
}
else for (lFmtVal = 0; isDigit(pbRead[0]); pbRead++)
{
lFmtVal = lFmtVal * 10 + (pbRead[0] - '0');
}

/*--------------------------------------------------------------*/
/* 将长度赋给宽度或者精度 */
/*--------------------------------------------------------------*/
if (bParseStep < 4 && lFmtVal < 0)
{
ptFmt->bRight = 0;
lFmtVal = min(-lFmtVal, 80);
}
else
{
lFmtVal = min(-lFmtVal, 80);
}

if (bParseStep < 4)
{
ptFmt->lWidth = lFmtVal, bParseStep = 4;
}
else if (bParseStep == 5)
{
ptFmt->lPrecision = -lFmtVal, bParseStep = 6;
}
else
{
break;
}

continue;

} /* if (pbRead[0] == '*' || isDigit(pbRead[0])) */

/*------------------------------------------------------------------*/
/* 检验长度模式 */
/*------------------------------------------------------------------*/
if ((bParseStep < 7) &&
(pbRead[0] == 'h' || pbRead[0] == 'l' || pbRead[0] == 'L'))
{
ptFmt->bMod = pbRead[0];
bParseStep = 7; pbRead++; continue;
}

if (isFormatEndChar(pbRead[0]))
{
ptFmt->bType = *pbRead++, bParseStep = 8;
ptFmt->bSubType = pbRead[0];
if (ptFmt->bType == 'z' && pbRead[0] != '\0')
{
pbRead++;
}
break;
}
else if (0 /* isPermitSpace(pbRead[0]) */)
{
pbRead++; continue;
}

break;

} /* while (pbRead[0] != '\0') */

/*----------------------------------------------------------------------*/
/* 未找到数据声明格式,则取消所有的格式指定,将'%'后的字符原样输出 */
/*----------------------------------------------------------------------*/
if (!ptFmt->bTakeDataDecl && bParseStep < 7)
{
ptFmt->bType = '\0', *ppbData = pbData, pbRead = pbReadFmt;
}

return pbRead;
}

/*--------------------------------------------------------------------------*/

/* Function name : PutChar() */
/* Description   : 向特定内存输出一个字符 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wChar - 待输出字符(可以是宽字符格式) */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 16:16 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG PutChar(BYTE *pbOutLoc, BYTE bChar)
{
BYTE *pbPut = pbOutLoc;
ULONG dwPrnCount;

*pbPut++ = bChar;

pbPut[0] = '\0';

dwPrnCount = pbPut - pbOutLoc;

return dwPrnCount;
}

/*--------------------------------------------------------------------------*/

/* Function name : PutString() */
/* Description   : 向特定内存输出一个字符串 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbString - 待输出字符串 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 16:16 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG PutString(BYTE *pbOutLoc, WORD wBufLen, BYTE *pbString)
{
BYTE *pbPut = pbOutLoc, *pbRead = pbString;
ULONG dwPrnCount = 0;

while (pbRead[0] != '\0' && dwPrnCount < wBufLen)
{
*pbPut++ = *pbRead++, dwPrnCount++;
}

pbPut[0] = '\0';

return dwPrnCount;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutWidthCheck() */
/* Description   : 输出宽度校验 */
/* Input         : ppbS - 输出起始地址 */
/*  : ppbE - 输出终止地址 */
/*  : pbFmt - 打印格式控制结构 */
/*  : bKeepLen - 保留长度 */
/* Output  : ppbBegin - 输出起始地址 */
/*  : ppbEnd - 输出终止地址 */
/* Return        : 功能或者失败 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 9:24 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

LONG OutPutWidthCheck(BYTE **ppbS, BYTE **ppbE, PrnFormatGlb_T *ptFmt, BYTE bK
eepLen)
{
BYTE *pbOutBeg = *ppbS, *pbOutEnd = *ppbE;

/*----------------------------------------------------------------------*/
/* 实际输出长度比限定长度超长,根据对齐方式在前面或后面选择打上'*'标记 */
/*----------------------------------------------------------------------*/
if (ptFmt->lWidth >= 0 && pbOutEnd - pbOutBeg + bKeepLen > ptFmt->lWidth)
{
if (ptFmt->bRight && !ptFmt->bAlter)
{
pbOutBeg = pbOutEnd + bKeepLen - ptFmt->lWidth;
pbOutBeg[0] =  '*';
}
else if (/* ptFmt->bRight && */ !ptFmt->bAlter)
{
pbOutEnd = pbOutBeg - bKeepLen + ptFmt->lWidth;
*(pbOutEnd - 1) = '*';
}

*ppbS = pbOutBeg, *ppbE = pbOutEnd;

return 1;
}

/*----------------------------------------------------------------------*/
/* 否则如果有宽度及精度指示,按其值进行'0'填充 */
/*----------------------------------------------------------------------*/
while (pbOutEnd - pbOutBeg < TEMP_BUF_SIZE_M - 1 &&
pbOutEnd - pbOutBeg < ptFmt->lPrecision)
{
*(--pbOutBeg) = '0';
}

if (ptFmt->bRight)
{
while (pbOutEnd - pbOutBeg < TEMP_BUF_SIZE_M - 1 &&
pbOutEnd - pbOutBeg + bKeepLen < ptFmt->lWidth)
{
*(--pbOutBeg) = ptFmt->bPreChar;
}
}
else /* if (!ptFmt->bRight) */
{
while (pbOutEnd - pbOutBeg < TEMP_BUF_SIZE_M - 1 &&
pbOutEnd - pbOutBeg + bKeepLen < ptFmt->lWidth)
{
*(pbOutEnd++) = ptFmt->bPreChar;
}
}

*ppbS = pbOutBeg, *ppbE = pbOutEnd;

return 0;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutDecimal() */
/* Description   : 按照打印格式符从相应的地址中取出数据并打印 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 9:24 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutDecimal(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE bNegtive = 0, bPreKeepLen = 0;
DWORD dwAbsVal = 0, dwTempVal;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->lPrecision > 0 && ptFmt->lWidth < ptFmt->lPrecision + 1)
{
ptFmt->lWidth = ptFmt->lPrecision + 1;
}

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->bType == 'u' && ptFmt->bMod == 'h')
{
dwAbsVal = (WORD)ptFmt->dwReadVal;
}
else if (ptFmt->bType == 'u' /* && ptFmt->bMod != 'h' */)
{
dwAbsVal = ptFmt->dwReadVal;
}
else if (/* ptFmt->bType == 'd' && */ ptFmt->bMod == 'h')
{
if ((SHORT)ptFmt->dwReadVal < 0)
{
dwAbsVal = -((SHORT)ptFmt->dwReadVal), bNegtive = 1;
}
else
{
dwAbsVal = (SHORT)ptFmt->dwReadVal;
}
}
else /* if (ptFmt->bType == 'd' && ptFmt->bMod != 'h') */
{
if ((LONG)ptFmt->dwReadVal < 0)
{
dwAbsVal = -((LONG)ptFmt->dwReadVal), bNegtive = 1;
}
else
{
dwAbsVal = (LONG)ptFmt->dwReadVal;
}
}

if (dwAbsVal == 0)
{
*(--pbOutBeg) = '0';
}
/*----------------------------------------------------------------------*/
/* 对于没有32位除法指令的机器来说,下面的代码可能有问题 */
/*----------------------------------------------------------------------*/
else for (dwTempVal = dwAbsVal; dwTempVal > 0; /* none */)
{
*(--pbOutBeg) = (BYTE)(dwTempVal % 10 + '0'), dwTempVal /= 10;
}

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
if (ptFmt->bAlter || !ptFmt->bRight)
{
bPreKeepLen = (bNegtive || ptFmt->bPlus) ? 1 : 0;
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (bNegtive)
{
*(--pbOutBeg) = '-';
}
else if (ptFmt->bPlus)
{
*(--pbOutBeg) = '+';
}
}
else
{
if (bNegtive)
{
*(--pbOutBeg) = '-';
}
else if (ptFmt->bPlus)
{
*(--pbOutBeg) = '+';
}

OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, 0);
}

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutHex() */
/* Description   : 按照打印格式符从相应的地址中取出数据并打印 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 16:57 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutHex(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE baHexTbl[16];
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE bChar = '0', bPreKeepLen = 0;
DWORD dwAbsVal = 0, dwTempVal;

bPreKeepLen = (ptFmt->bAlter) ? 3 : 0;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->lPrecision > 0 && ptFmt->lWidth < ptFmt->lPrecision + bPreKeepLen)

{
ptFmt->lWidth = ptFmt->lPrecision + bPreKeepLen;
}

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

for (dwTempVal = 0; dwTempVal < 9; dwTempVal++)
{
baHexTbl[dwTempVal] = bChar++;
}

bChar = (ptFmt->bType == 'x') ? 'a' : 'A';
for (dwTempVal = 10; dwTempVal < 16; dwTempVal++)
{
baHexTbl[dwTempVal] = bChar++;
}

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->bMod == 'h')
{
dwAbsVal = (WORD)ptFmt->dwReadVal;
}
else /* if (ptFmt->bMod != 'h') */
{
dwAbsVal = ptFmt->dwReadVal;
}

if (dwAbsVal == 0)
{
*(--pbOutBeg) = '0';
}
else for (dwTempVal = dwAbsVal; dwTempVal > 0; /* none */)
{
*(--pbOutBeg) = baHexTbl[dwTempVal & 0xf], dwTempVal >>= 4;
}

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (ptFmt->bAlter)
{
*(--pbOutBeg) = ' ';
*(--pbOutBeg) = (ptFmt->bType == 'x' ? 'x' : 'X');
*(--pbOutBeg) = '0';
}

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutOctet() */
/* Description   : 按照打印格式符从相应的地址中取出数据并打印 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 16:57 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutOctet(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE bPreKeepLen = 0;
DWORD dwAbsVal = 0, dwTempVal;

bPreKeepLen = (ptFmt->bAlter) ? 2 : 0;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->lPrecision > 0 && ptFmt->lWidth < ptFmt->lPrecision + bPreKeepLen)

{
ptFmt->lWidth = ptFmt->lPrecision + bPreKeepLen;
}

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->bMod == 'h')
{
dwAbsVal = (WORD)ptFmt->dwReadVal;
}
else /* if (ptFmt->bMod != 'h') */
{
dwAbsVal = ptFmt->dwReadVal;
}

if (dwAbsVal == 0)
{
*(--pbOutBeg) = '0';
}
else for (dwTempVal = dwAbsVal; dwTempVal > 0; /* none */)
{
*(--pbOutBeg) = (BYTE)((dwTempVal & 7) + '0'), dwTempVal >>= 3;
}

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (ptFmt->bAlter)
{
*(--pbOutBeg) = ' ';
*(--pbOutBeg) = 'O';
}

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutBinary() */
/* Description   : 按照打印格式符从相应的地址中取出数据并打印 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 17:31 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutBinary(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE bPreKeepLen = 0;
DWORD dwAbsVal = 0, dwTempVal;

bPreKeepLen = (ptFmt->bAlter) ? 2 : 0;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->lPrecision > 0 && ptFmt->lWidth < ptFmt->lPrecision + bPreKeepLen)

{
ptFmt->lWidth = ptFmt->lPrecision + bPreKeepLen;
}

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->bMod == 'h')
{
dwAbsVal = (WORD)ptFmt->dwReadVal;
}
else /* if (ptFmt->bMod != 'h') */
{
dwAbsVal = ptFmt->dwReadVal;
}

if (dwAbsVal == 0)
{
*(--pbOutBeg) = '0';
}
else for (dwTempVal = dwAbsVal; dwTempVal > 0; /* none */)
{
*(--pbOutBeg) = (BYTE)((dwTempVal & 1) + '0'), dwTempVal >>= 1;
}

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (ptFmt->bAlter)
{
*(--pbOutBeg) = ' ';
*(--pbOutBeg) = 'b';
}

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutChar() */
/* Description   : 按照打印格式符从相应的地址中取出字符并打印 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 17:31 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutChar(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
DWORD dwTempVal;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据,并检验取数据默认值 */
/*----------------------------------------------------------------------*/
if (!ptFmt->bTakeDataDecl)
{
ptFmt->wTakeBytes = PrnTakeCharBytesDft_M;
}
ptFmt->lPrecision = 0;

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

*(--pbOutBeg) = (char)ptFmt->dwReadVal;

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, 0);

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutString() */
/* Description   : 按照打印格式符从相应的地址中取出字符串并打印 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 17:31 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutString(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbReadData;
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M / 2 - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M / 2 - 1];
DWORD dwTempVal;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
ptFmt->lPrecision = 0;

for (pbReadData = *ppbDataAddr; pbReadData[0] != '\0'; /* none */)
{
if (pbOutEnd - sTempOutBuf < TEMP_BUF_SIZE_M - 1)
{
*pbOutEnd++ = *pbReadData++;
}
}

*ppbDataAddr = pbReadData;

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, 0);

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : zeroQword() */
/* Description   : 判断QWORD是否为0 */
/* Input         : qwVal - 待判断QWORD */
/* Output  : 无   */
/* Return        : 是或不是 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-24 12:12上午 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static LONG zeroQword(QWORD qwVal)
{
if (qwVal.dwH == 0 && qwVal.dwL == 0)
{
return 1;
}

return 0;
}

/*--------------------------------------------------------------------------*/

/* Function name : QwordPlus() */
/* Description   : 两个四字长的数据相加 */
/* Input         : qwVal1 - 第一个四字长操作数 */
/*   : qwVal2 - 第二个四字长操作数 */
/* Output  : 无   */
/* Return        : 两个四字长操作数的和 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 10:34下午 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static QWORD QwordPlus(QWORD qwVal1, QWORD qwVal2)
{
DWORD dwOverVal;
QWORD qwRet = {0, 0};

qwRet.dwL = qwVal1.dwL + qwVal2.dwL;
qwRet.dwH = qwVal1.dwH + qwVal2.dwH;

/*----------------------------------------------------------------------*/
/* 低阶数据溢出校正 */
/*----------------------------------------------------------------------*/
dwOverVal = ((qwVal1.dwL & 0xffff) + (qwVal2.dwL & 0xffff)) >> 16;
dwOverVal = (dwOverVal + (qwVal1.dwL >> 16) + (qwVal2.dwL >> 16)) >> 16;
qwRet.dwH += dwOverVal;

return qwRet;
}

/*--------------------------------------------------------------------------*/

/* Function name : QwordMinus() */
/* Description   : 两个四字长的数据相减 */
/* Input         : qwVal1 - 第一个四字长操作数 */
/*   : qwVal2 - 第二个四字长操作数 */
/* Output  : 无   */
/* Return        : 两个四字长操作数的差 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 11:58下午 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static QWORD QwordPlus(QWORD qwVal1, QWORD qwVal2)
{
QWORD qwRet = {0, 0};

qwRet.dwL = qwVal1.dwL - qwVal2.dwL;
qwRet.dwH = qwVal1.dwH - qwVal2.dwH;

/*----------------------------------------------------------------------*/
/* 数据溢出校正 */
/*----------------------------------------------------------------------*/
qwRet.dwH -= (qwVal1.dwL < qwVal2.dwL) ? 1 : 0;

return qwRet;
}

/*--------------------------------------------------------------------------*/

/* Function name : QwordMultiNum() */
/* Description   : 四字长的数据乘以一个数 */
/* Input         : qwVal - 四字长操作数 */
/*   : BYTE - 乘数 */
/* Output  : 无   */
/* Return        : 乘积 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 10:48下午 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static QWORD QwordMultiNum(QWORD qwVal, BYTE bVal)
{
DWORD dwOverVal;
QWORD qwRet = {0, 0};

qwRet.dwH = qwVal.dwH * bVal;
qwRet.dwL = qwVal.dwL * bVal;

/*----------------------------------------------------------------------*/
/* 低阶数据溢出校正 */
/*----------------------------------------------------------------------*/
dwOverVal = ((qwVal.dwL & 0xffff) * bVal) >> 16;
dwOverVal = (dwOverVal + ((qwVal.dwL >> 16) * bVal)) >> 16;
qwRet.dwH += dwOverVal;

return qwRet;
}

/*--------------------------------------------------------------------------*/

/* Function name : QwordDividNum() */
/* Description   : 四字长的数据除以一个数 */
/* Input         : qwVal - 四字长操作数 */
/*   : bVal - 除数 */
/* Output  : 无   */
/* Return        : 商 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 10:34下午 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static QWORD QwordDividNum(QWORD qwVal, BYTE bVal)
{
DWORD dwOverVal1, dwOverVal2;
QWORD qwRet = {0, 0};

qwRet.dwL = qwVal.dwL / bVal;

if (qwVal.dwH == 0)
{
return qwRet;
}

qwRet.dwH = (qwVal.dwH & 0xffffff00) / bVal;

/*----------------------------------------------------------------------*/
/* 只有高阶的末尾字节进行除操作才有溢出 */
/*----------------------------------------------------------------------*/
dwOverVal1 = ((qwVal.dwH & 0xff) << 8) / bVal;
dwOverVal2 = (((dwOverVal1 & 0xff) + (qwRet.dwL >> 24)) >> 8);
qwRet.dwH += (dwOverVal1 >> 8) + dwOverVal2;
qwRet.dwL += (dwOverVal1 & 0xff) << 24;

return qwRet;
}

/*--------------------------------------------------------------------------*/

/* Function name : QwordModNum() */
/* Description   : 四字长的数据除以一个数的余数 */
/* Input         : qwVal - 四字长操作数 */
/*   : bVal - 除数 */
/* Output  : 无   */
/* Return        : 商 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-24 12:06上午 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static BYTE QwordModNum(QWORD qwVal, BYTE bVal)
{
QWORD qwRet = {0, 0};

qwRet = QwordMinus(qwVal, QwordDividNum(qwVal, bVal));

return (BYTE)(qwRet.dwL & 0xff);
}

/*--------------------------------------------------------------------------*/

/* Function name : FloatGetDecMantisFromBin() */
/* Description   : 将二进制的尾数转化为一个十进制的浮点数 */
/* Input         : qwBinMantis - 二进制尾数 */
/* Output  : 无   */
/* Return        : 十进制表示的浮点数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 07:44下午 */
/* Note          : 二进制尾数最高位有效,十进制尾数最低位有效(尾数是整数)   */

/*--------------------------------------------------------------------------*/

static PFLOAT FloatGetDecMantisFromBin(QWORD qwBinMantis)
{
int i = 0;
PFLOAT tDecF = {0, 0, {0, 0}};
QWORD qwTemp1 = {0, 5};

if (qwBinMantis.dwH == 0 && qwBinMantis.dwL == 0)
{
return tDecF;
}

/*----------------------------------------------------------------------*/
/* 尾数计算是从小数点后开始,因此为-1次方 */
/*----------------------------------------------------------------------*/
tDecF.lPower = -1;

while (qwBinMantis.dwH != 0)
{
if (qwBinMantis.dwH & 0x80000000)
{
tDecF.qwMantis = QwordPlus(tDecF.qwMantis, qwTemp1);
}

qwBinMantis.dwH <<= 1, i++;
/*------------------------------------------------------------------*/
/* 确保尾数有效而不产生溢出 */
/*------------------------------------------------------------------*/
if (tDecF.qwMantis.dwH < 0x19999999)
{
tDecF.lPower--;
qwTemp1 = QwordMultiNum(qwTemp1, 5);
tDecF.qwMantis = QwordMultiNum(tDecF.qwMantis, 10);
}
else
{
qwTemp1 = QwordDividNum(qwTemp1, 2);
}
}

if (qwBinMantis.dwL == 0)
{
return tDecF;
}

/*----------------------------------------------------------------------*/
/* 双精度数,跳到2^(-32)之后 */
/*----------------------------------------------------------------------*/
for (/* none */; i < 32; i++)
{
if (tDecF.qwMantis.dwH == 0 && tDecF.qwMantis.dwL == 0 &&
qwTemp1.dwH < 0x19999999)
{
tDecF.lPower--;
qwTemp1 = QwordMultiNum(qwTemp1, 5);
}
else if (tDecF.qwMantis.dwH < 0x19999999)
{
tDecF.lPower--;
qwTemp1 = QwordMultiNum(qwTemp1, 5);
tDecF.qwMantis = QwordMultiNum(tDecF.qwMantis, 10);
}
else
{
qwTemp1 = QwordDividNum(qwTemp1, 2);
}
}

/*----------------------------------------------------------------------*/
/* 计算后11个比特位产生的有效精度 */
/*----------------------------------------------------------------------*/
while (qwBinMantis.dwL != 0)
{
if (qwBinMantis.dwL & 0x80000000)
{
tDecF.qwMantis = QwordPlus(tDecF.qwMantis, qwTemp1);
}

qwBinMantis.dwL <<= 1, i++;
if (tDecF.qwMantis.dwH < 0x19999999)
{
tDecF.lPower--;
qwTemp1 = QwordMultiNum(qwTemp1, 5);
tDecF.qwMantis = QwordMultiNum(tDecF.qwMantis, 10);
}
else
{
qwTemp1 = QwordDividNum(qwTemp1, 2);
}
}

return tDecF;
}

/*--------------------------------------------------------------------------*/

/* Function name : FloatDecMultiBinPower() */
/* Description   : 将十进制的浮点数乘以2的某次方 */
/* Input         : tDecF - 十进制表示的浮点数 */
/* Output  : 无   */
/* Return        : 十进制表示的浮点数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 07:44下午 */
/* Note          : 二进制尾数最高位有效,十进制尾数最低位有效(尾数是整数)   */

/*--------------------------------------------------------------------------*/

static PFLOAT FloatDecMultiBinPower(PFLOAT tDecF, LONG lPower)
{
if (lPower == 0 || zeroQword(tDecF.qwMantis))
{
return tDecF;
}

if (lPower < 0) for (/* none */; lPower != 0; lPower++)
{
tDecF.qwMantis = QwordDividNum(tDecF.qwMantis, 2);
if (tDecF.qwMantis.dwH < 0x19999999)
{
tDecF.lPower--;
tDecF.qwMantis = QwordMultiNum(tDecF.qwMantis, 10);
}
}
else for (/* none */; lPower != 0; lPower--)
{
if (tDecF.qwMantis.dwH & 0x80000000)
{
tDecF.lPower++;
tDecF.qwMantis = QwordDividNum(tDecF.qwMantis, 10);
}
tDecF.qwMantis = QwordMultiNum(tDecF.qwMantis, 2);
}

return tDecF;
}

/*--------------------------------------------------------------------------*/

/* Function name : FloatBinToDec() */
/* Description   : 将以二进制表示的浮点数转化为以十进制表示的浮点数 */
/* Input         : tBinF - 二进制表示的浮点数 */
/* Output  : 无   */
/* Return        : 十进制表示的浮点数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 07:14下午 */
/* Note          : 二进制尾数最高位有效,十进制尾数最低位有效(尾数是整数)   */

/*--------------------------------------------------------------------------*/

static PFLOAT FloatBinToDec(PFLOAT tBinF)
{
PFLOAT tDecF = {0, 0, {0, 0}};
QWORD qwTemp;

/*----------------------------------------------------------------------*/
/* 首先得到十进制的尾数,并计算递减的阶差 */
/*----------------------------------------------------------------------*/
tDecF = FloatGetDecMantisFromBin(tBinF.qwMantis);

/*----------------------------------------------------------------------*/
/* 十进制到二进制的阶差转换 */
/*----------------------------------------------------------------------*/
tDecF = FloatDecMultiBinPower(tDecF, tBinF.lPower);

/*----------------------------------------------------------------------*/
/* 十进制的尾数都是用整数表示的,下面进行数值调整 */
/*----------------------------------------------------------------------*/
while (QwordModNum(tDecF, 10) != 0)
{
tDecF.lPower--;
tDecF.qwMantis = QwordDividNum(tDecF.qwMantis, 10);
}

tDecF.bNegtive = tBinF.bNegtive;

return tDecF;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutFloat() */
/* Description   : 输出浮点数 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-22 10:11下午 */
/* Note          :                                                          */

/* 单精度实数: */
/*    +--+---------------+------------------------------------------------+ */

/*    |b |b b b b b b b b|b b b b b b b b b b b b b b b b b b b b b b b b | */

/*    +--+---------------+------------------------------------------------+ */

/*    |±|指数阶码, 8比特| 尾数, 23比特, 共32比特                         | */

/*    +--+---------------+------------------------------------------------+ */

/* 双精度实数: */
/*    +--+-----------+----------------------------------------------------+ */

/*    |b |bbbbbbbbbbb|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| */

/*    +--+-----------+----------------------------------------------------+ */

/*    |±|阶码,11比特| 尾数, 52比特, 共64比特                             | */

/*    +--+-----------+----------------------------------------------------+ */

/*--------------------------------------------------------------------------*/

static ULONG OutPutFloat(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
DWORD dwTempVal;
QWORD qwTemp;
LONG lValLen = 0; /* 有效数据长度 */
BYTE bScientDisp = 0; /* 科学计数法显示数据 */
PFLOAT tBinF = {0, 0, {0, 0}}; /* 二进制表示浮点数 */
PFLOAT tDecF = {0, 0, {0, 0}}; /* 十进制表示浮点数 */
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据,并检验取数据默认值 */
/*----------------------------------------------------------------------*/
if (ptFmt->lPrecision < 0 &&
(ptFmt->bType == 'f' || ptFmt->bType == 'e' || ptFmt->bType == 'E'))
{
ptFmt->lPrecision = PrnPreciDft_M;
}
if (!ptFmt->bTakeDataDecl)
{
ptFmt->wTakeBytes = PrnTakeFloatBytesDft_M;
}

/*----------------------------------------------------------------------*/
/* 按双精度或者单精度数据定义取数,二进制尾数上的最高有效'1'往往被省略 */
/*----------------------------------------------------------------------*/
if (ptFmt->wTakeBytes <= 4)
{
ptFmt->bBitTake = 0;
ptFmt->wTakeBytes = 4;
TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

tBinF.bNegtive = (ptFmt->dwReadVal >> 31) ? 1 : 0;
tBinF.lPower = (LONG)((ptFmt->dwReadVal >> 23) & 0xff);
tBinF.qwMantis.dwH = (ptFmt->dwReadVal & 0x7fffff) << 8;
tBinF.qwMantis.dwL = 0
tBinF.qwMantis.dwH |= tBinF.lPower ? 0 : 0x800000;
tBinF.lPower = tBinF.lPower - 0x7f + 1; /* 将移码转化为补码 */
}
else
{
ptFmt->bBitTake = 0;
ptFmt->wTakeBytes = 4;

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);
if (ptFmt->bBigEndian)
{
tBinF.bNegtive = (ptFmt->dwReadVal >> 31) ? 1 : 0;
tBinF.lPower = ((ptFmt->dwReadVal >> 20) & 0x7ff);
tBinF.qwMantis.dwH = (ptFmt->dwReadVal) << 11;
}
else
{
tBinF.qwMantis.dwH = (ptFmt->dwReadVal) & 0x7ff;
tBinF.qwMantis.dwL = (ptFmt->dwReadVal) << 11;
}

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);
if (ptFmt->bBitEndian)
{
tBinF.qwMantis.dwH |= (ptFmt->dwReadVal) & 0x7ff;
tBinF.qwMantis.dwL = (ptFmt->dwReadVal) << 11;
}
else
{
bNegtive = (ptFmt->dwReadVal >> 31) ? 1 : 0;
tBinF.lPower = ((ptFmt->dwReadVal >> 20) & 0x7ff);
tBinF.qwMantis.dwH |= (ptFmt->dwReadVal) << 11;
}

ptFmt->wTakeBytes = 8;

tBinF.qwMantis.dwH |= tBinF.lPower ? 0 : 0x80000000;
tBinF.lPower = tBinF.lPower - 0x7ff + 1; /* 将移码转化为补码 */
}

/*----------------------------------------------------------------------*/
/* 将二进制表示的浮点数转化为十进制表示的浮点数,并计算有效数据长度 */
/*----------------------------------------------------------------------*/
tDecF = FloatBinToDec(tBinF);
for (qwTemp = tDecF.qwMantis; !zeroQword(qwTemp); lValLen++)
{
qwTemp = QwordDividNum(qwTemp, 10);
}

/*----------------------------------------------------------------------*/
/* 判断是直接以小数点形式显示数据还是按科学计数法显示数据 */
/*----------------------------------------------------------------------*/
if (tDecF.lPower > 16 || tDecF.lPower < -16 || ptFmt->bType == 'e' ||
ptFmt->bType == 'E' /* || */)
{
bScientDisp = 1;
}

qwTemp = tDecF.qwMantis, dwTempVal = 0;

if (bScientDisp)
{ /*------------------------------------------------------------------*/
/* 所有的数据位都是小数,所以lValLen就是小数位长度 */
/*------------------------------------------------------------------*/
for (/**/; (pbOutEnd - pbOutBeg) < ptFmt->lPrecision - lValLen; /**/)
{
*(--pbOutBeg) = '0';
}
/*------------------------------------------------------------------*/
/* 数据长度不够时补'0',超过时就剔除有效数据 */
/*------------------------------------------------------------------*/
for (/**/; dwTempVal < lValLen - ptFmt->lPrecision; dwTempVal++)
{
qwTemp = QwordDividNum(qwTemp, 10);
}

while (!zeroQword(qwTemp))
{
*(--pbOutBeg) = '0' + QwordModNum(qwTemp, 10);
qwTemp = QwordDividNum(qwTemp, 10);
}

*(--pbOugBeg) = '.';
*(--pbOugBeg) = '0';

lValLen = tDecF.lPower + lValLen;
(*pbOutEnd++) = (ptFmt->bType == 'e' || ptFmt->bType == 'g') ? 'e' : 'E';
(*pbOutEnd++) = lValLen < 0 ? '-' : '+';
lValLen = (lValLen < 0) ? -lValLen : lValLen;
(*pbOutEnd++) = '0' + (lValLen / 100) % 10;
(*pbOutEnd++) = '0' + (lValLen / 10) % 10;
(*pbOutEnd++) = '0' + lValLen % 10;
}
else
{ /*------------------------------------------------------------------*/
/* 阶码的值小于0,那么它的绝对值就是小数长度(精度数) */
/*------------------------------------------------------------------*/
if (tDecF.lPower < 0)
{
for (/* none */;
(pbOutEnd - pbOutBeg) < ptFmt->lPrecision + tDecF.lPower;
/* none */)
{
*(--pbOutBeg) = '0';
}
for (/* none */;
dwTempVal < -tDecF.lPower - ptFmt->lPrecision;
dwTempVal++)
{
qwTemp = QwordDividNum(qwTemp, 10);
}

for (/* none */; dwTempVal < -tDecF.lPower; dwTempVal++)
{
*(--pbOutBeg) = '0' + QwordModNum(qwTemp, 10);
qwTemp = QwordDividNum(qwTemp, 10);
}

*(--pbOugBeg) = '.';
}
/*------------------------------------------------------------------*/
/* 纯整数,直接用'0'补齐小数长度,并补齐整数部分 */
/*------------------------------------------------------------------*/
else
{
for (/* */; (pbOutEnd - pbOutBeg) < ptFmt->lPrecision; /* */)
{
*(--pbOutBeg) = '0';
}

*(--pbOugBeg) = '.';

for (/* none */; dwTempVal < tDecF.lPower; dwTempVal++)
{
*(--pbOutBeg) = '0';
}
}

if (zerQword(qwTemp))
{
*(--pbOutBeg) = '0';
}
else while (!zero(qwTemp))
{
*(--pbOutBeg) = '0' + QwordModNum(qwTemp, 10);
qwTemp = QwordDividNum(qwTemp, 10);
}
}

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
if (ptFmt->bAlter || !ptFmt->bRight)
{
bPreKeepLen = (tDecF.bNegtive || ptFmt->bPlus) ? 1 : 0;
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (tDecF.bNegtive)
{
*(--pbOutBeg) = '-';
}
else if (ptFmt->bPlus)
{
*(--pbOutBeg) = '+';
}
}
else
{
if (tDecF.bNegtive)
{
*(--pbOutBeg) = '-';
}
else if (ptFmt->bPlus)
{
*(--pbOutBeg) = '+';
}

OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, 0);
}

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutImsi() */
/* Description   : 输出IMSI */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-22 12:33上午 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutImsi(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE bPreKeepLen, *pbData = *ppbDataAddr;
DWORD dwTempVal;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据,并检验取数据默认值 */
/*----------------------------------------------------------------------*/
if (!ptFmt->bTakeDataDecl)
{
ptFmt->wTakeBytes = 8;
}

for (dwTempVal = 0; dwTempVal < 16; dwTempVal++)
{
if (dwTempVal % 2 == 0)
{
if ((pbData[0] & 0xf) > 9 && !ptFmt->bAlter)
{
break;
}
else if ((pbData[0] & 0xf) > 9)
{
pbOutEnd[0] = (pbData[0] & 0xf) - 10 + 'a';
}
else
{
pbOutEnd[0] = (pbData[0] & 0xf) + '0';
}
}
else
{
if ((pbData[0] >> 4) > 9 && !ptFmt->bAlter)
{
break;
}
else if ((pbData[0] >> 4) > 9)
{
pbOutEnd[0] = (pbData[0] >> 4) - 10 + 'a';
}
else
{
pbOutEnd[0] = (pbData[0] >> 4) + '0';
}

pbData++;

if (pbData > *ppbDataAddr + ptFmt->wTakeBytes)
{
pbOutEnd++;
break;
}
}

pbOutEnd++;
}

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
bPreKeepLen = ptFmt->bAlter ? 6 : 0;
ptFmt->lPrecision = 0, ptFmt->bPreChar = ' ';
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (ptFmt->bAlter)
{
*(--pbOutBeg) = ' ';
*(--pbOutBeg) = ':';
*(--pbOutBeg) = 'I';
*(--pbOutBeg) = 'S';
*(--pbOutBeg) = 'M';
*(--pbOutBeg) = 'I';
}

pbOutEnd[0] = '\0';

*ppbDataAddr += ptFmt->wTakeBytes;

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutIp() */
/* Description   : 输出IP地址 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-22 12:33上午 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutIp(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE bIpVal, bPreKeepLen, *pbTemp;
DWORD dwTempVal;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据,并检验取数据默认值 */
/*----------------------------------------------------------------------*/
if (!ptFmt->bTakeDataDecl)
{
ptFmt->wTakeBytes = 4;
}

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

for (dwTempVal = 0; dwTempVal < 4; dwTempVal++)
{
bIpVal = (BYTE)((ptFmt->dwReadVal >> (dwTempVal * 8)) & 0xff);

pbTemp = pbOutBeg;

if (bIpVal == 0)
{
*(--pbOutBeg) = '0';
}
else while (bIpVal > 0)
{
*(--pbOutBeg) = bIpVal % 10 + '0', bIpVal /= 10;
}

while (ptFmt->lPrecision > 0 && pbTemp - pbOutBeg < 10 &&
pbTemp - pbOutBeg < ptFmt->lPrecision)
{
*(--pbOutBeg) = ptFmt->bPreChar;
}

*(--pbOutBeg) = '.';
}

pbOutBeg++;

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
bPreKeepLen = ptFmt->bAlter ? 4 : 0;
ptFmt->lPrecision = 0, ptFmt->bPreChar = ' ';
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (ptFmt->bAlter)
{
*(--pbOutBeg) = ' ';
*(--pbOutBeg) = ':';
*(--pbOutBeg) = 'P';
*(--pbOutBeg) = 'I';
}

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutZteTypeData() */
/* Description   : 打印中兴公司自定义格式 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 10:04下午 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutZteTypeData(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
switch (ptFmt->bSubType)
{
case 'M':
return OutPutImsi(pbOutLoc, wBufLen, ptFmt, ppbDataAddr, wDataLen);
case 'I':
return OutPutIp(pbOutLoc, wBufLen, ptFmt, ppbDataAddr, wDataLen);
default:
return 0;
}
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutSkip() */
/* Description   : 跳过参数列表处理 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 10:11下午 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutSkip(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbReadData = *ppbDataAddr;

pbReadData += ptFmt->wTakeBytes;

if (ptFmt->bBitTake)
{
if (ptFmt->bRemainBits > ptFmt->wTakeBits)
{
ptFmt->bRemainBits -= ptFmt->wTakeBits;
if (ptFmt->bBigEndian && ptFmt->bRemainBits < 32)
{
ptFmt->dwRemainVal &= (1 << ptFmt->bRemainBits) - 1;
}
else if (!ptFmt->bBigEndian)
{
ptFmt->dwRemainVal >>= ptFmt->wTakeBits;
}
}
else
{
ptFmt->bRemainBits = 0;
ptFmt->dwRemainVal = 0;
}
}

*ppbDataAddr = pbReadData;

return 0;
}

/*--------------------------------------------------------------------------*/

/* Function name : tprintf1() */
/* Description   : 格式化控制打印函数总入口 */
/* Input         : pbBuf - 输出字符串地址指针 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 格式化控制字符串 */
/*  : pbAddr - 数据内存起始地址 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数统计,字串尾字符'\0'不参加计数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-19 20:11 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

ULONG tprintf1(BYTE *pbBuf, WORD wBufLen, char *pbFmt, BYTE *pbDataAddr, WORD 
wDataLen)
{
char *pbReadFmt = pbFmt;
BYTE bAmongPercentFmt = 0;
BYTE *pbReadData = pbDataAddr;
BYTE *pbOutLoc = pbBuf;

DWORD dwPrnCount = 0;

PrnFormatGlb_T tFmtStatus;

if (pbOutLoc == NULL)
{
return dwPrnCount;
}

tFmtStatus.bRemainBits = 0;
tFmtStatus.dwRemainVal = 0;

while (pbReadFmt[0] != '\0' && pbOutLoc - pbBuf < wBufLen)
    {
if (pbReadFmt[0] != '%' && !bAmongPercentFmt)
{
pbOutLoc += PutChar(pbOutLoc, pbReadFmt[0]);
pbReadFmt++; continue;
}
else if (pbReadFmt[0] == '%' && !bAmongPercentFmt)
{
bAmongPercentFmt = 1;
pbReadFmt++; continue;
}

        pbReadFmt = ParsePercentFormat(pbReadFmt, &tFmtStatus, &pbReadData);
if (pbReadData > pbDataAddr + wDataLen)
{
break;
}

        /*------------------------------------------------------------------*/

        /* 支持的百分符"%"打印控制格式:                                     */

        /*------------------------------------------------------------------*/

        /*  a     -   取数控制符(不在打印输出中处理)                        */

        /*  b     -   二进制数                                              */

        /*  c     -   一个字符                                              */

        /*  d     -   带符号的十进制数                                      */

/*  e,E   -   科学计数法形式的浮点数输出,指数符'e'小写或大写       */
/*  f     -   浮点数输出,默认小数点后6位精度                       */
/*  g,G   -   选择进行的浮点数输出,采用"e,E"格式时指数符相应改变   */
/*  h     -   整数长度限定,两字节长度(附加控制)                    */
        /*  k     -   跳过数个字节或者比特位数据                            */

        /*  l     -   整数长度限定,四字节长度(附加控制, 作为默认值)        */

        /*  o     -   八进制数                                              */

        /*  u     -   无符号的十进制数                                      */

        /*  p     -   指针                                                  */

        /*  s     -   字符串                                                */

        /*  x,X   -   十六进制数,'a-f'根据'x,X'决定是采用小写还是大写      */

        /*  zI    -   中兴自定义IP地址                                      */

        /*  zM    -   中兴自定义IMSI                                        */

        /*------------------------------------------------------------------*/

switch (tFmtStatus.bType)
{
case 'd':
case 'u':
pbOutLoc += OutPutDecimal(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'p':
case 'x':
case 'X':
pbOutLoc += OutPutHex(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'o':
pbOutLoc += OutPutOctet(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'b':
pbOutLoc += OutPutBinary(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'c':
pbOutLoc += OutPutChar(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 's':
pbOutLoc += OutPutString(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'k':
pbOutLoc += OutPutSkip(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
pbOutLoc += OutPutFloat(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'z':
pbOutLoc += OutPutZteTypeData(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
default:
pbOutLoc += PutChar(pbOutLoc, pbReadFmt[0]), pbReadFmt++;
break;
}

bAmongPercentFmt = 0;
}

return (dwPrnCount = pbOutLoc - pbBuf);
}

/*--------------------------------------------------------------------------*/

/* Function name : tprintf() */
/* Description   : 格式化控制打印函数入口 */
/* Input         : pbBuf - 输出字符串地址指针 */
/*  : pbFmt - 格式化控制字符串 */
/*  : pbAddr - 数据内存起始地址 */
/* Output  : none   */
/* Return        : 打印的字符个数统计,字串尾字符'\0'不参加计数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 13:31 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

ULONG tprintf(BYTE *pbBuf, char *pbFmt, BYTE *pbDataAddr)
{
return tprintf1(pbBuf, 0x7fff, pbFmt, pbDataAddr, 0x7fff);
}

/*--------------------------------------------------------------------------*/

/* Function name : isBigEndian() */
/* Description   : 测试本机的字节阶是否大数阶(低地址更高阶) */
/* Input         : 无 */
/* Output  : 无   */
/* Return        : 真或假 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-19 20:11 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

LONG isBigEndian(void)
{
union
{
BYTE cChar[2];
WORD wShort;
} u1;

u1.cChar[0] = 1, u1.cChar[1] = 2;

if (u1.wShort == (1 << 8) + 2)
{
return -1;
}

return 0;
}

/*----------------------------------文件结束--------------------------------*/




────────────────────────────────────────
 jiaxuan (笑十子)                     于 Sun May 25 02:17:43 2003) 说道:

【 在 fib (May Flower) 的大作中提到: 】
: 很漂亮,虽然不知道有什么用
这个函数提供的功能与printf()函数相仿。
不同的是printf()函数直接打印到控制口,
而且以多参数表形式给出要打印的参数。
不提供对数据的理解功能。
而这个函数独立于控制口,
但需要你提供输出字符串的内存地址,
然后你可以从那里取你要得到的字符串。

下面的代码测试过了,
可以提供浮点数的转换功能,
因此可以打印浮点数。只要支持C的机器上,
相信下面的代码都能编译过,
没有复杂的文件包含关系,就是一个简简单单的函数。

#define LONG long
#define BYTE unsigned char
#define DWORD unsigned long
#define ULONG unsigned long
#define USHORT unsigned short
#define WORD unsigned short
#define SHORT short
#define NULL 0

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

/* Module Name: COMMON                        File Name: tprintf.c          */

/* Create Date: 2003-5-20 11:57               Author   : R.Z.Tian           */

/* Function   : print function from memory by format string                 */

/* Version    : 1.0                                                         */

/* -------------------------------------------------------------------------*/

/*                 Copyright 2001 - 2005, ZTE, Inc, China.                  */

/*                           ALL RIGHTS RESERVED                            */

/*                                                                          */

/*  Permission is hereby granted to licensees of ZTE, Inc. products to use  */

/*  or abstract this computer program for the sole purpose of implementing  */

/*  a product based on ZTE, Inc. products.  No  other rights to reproduce,  */

/*  use, or disseminate this computer program, whether in part or in whole, */

/*  are granted. ZTE, Inc.  makes  no  representation  or warranties  with  */

/*  respect to the performance of this computer program,  and specifically  */

/*  disclaims any responsibility for any damages, special or consequential, */

/*  connected with the use of this program.                                 */

/*--------------------------------------------------------------------------*/

/* History   : */
/* Date        Version  Person Activies                            */
/* 2003.05.20  1.0.0    RZ.Tian Create                              */
/*--------------------------------------------------------------------------*/


#define FloatZeroPowerRef_M 0x7f /* 浮点数0指数移码数 */
#define DoubleZeroPowerRef_M 0x3ff /* 双精度数0指数移码数 */

#define PrnWidthDft_M -1 /* 默认输出数据宽度 */
#define PrnPreciDft_M 6 /* 默认输出数据精度 */
#define PrnTakeDataBytesDft_M 4 /* 默认取数据的字节长度 */
#define PrnTakeFloatBytesDft_M 4 /* 默认取浮点数的字节数 */
#define PrnTakeCharBytesDft_M 1 /* 默认取字符数据字节数 */
#define PrnTakeImsiBytesDft_M 8 /* 默认取IMSI的字节数 */
#define PrnTakeIpBytesDft_M 4 /* 默认取IP地址的字节数 */
#define TEMP_BUF_SIZE_M 82 /* 临时缓存大小 */

#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))

#define isDigit(a) \
(((a) <= '9') && ((a) >= '0'))

#define isLetter(a) \
((((a) <= 'z') && ((a) >= 'a')) || (((a) <= 'Z') && ((a) >= 'A')))

#define isPermitSpace(a) \
(((a) == ' ') || ((a) == '\t') || ((a) == '\n') || ((a) == '\v'))

#define isFormatEndChar(a) \
(((a) == 'd') || ((a) == 'u') || ((a) == 'x') || ((a) == 'X') || \
 ((a) == 'p') || ((a) == 's') || ((a) == 'k') || ((a) == 'z') || \
 ((a) == 'o') || ((a) == 'b') || ((a) == 'c') || ((a) == 'f') || \
 ((a) == 'e') || ((a) == 'E') || ((a) == 'g') || ((a) == 'G')) \

/*--------------------------------------------------------------------------*/

/* 格式化打印声明相关标志量及取得待打印操作数的相关控制变量结构 */
/*--------------------------------------------------------------------------*/

typedef struct
{
BYTE bType; /* 显示数据格式 */
BYTE bSubType; /* 显示数据子格式 */
BYTE bMod; /* 采用半长型或者长型打印标识 */
BYTE bTakeDataDecl; /* 取数据格式声明 */

LONG lWidth; /* 打印数据宽度   */
LONG lPrecision; /* 数据精度 */

BYTE bPreChar; /* 前导字符, ' '或'0'或无填充 */
BYTE bRight; /* 右对齐标志 */
BYTE bAlter; /* 提示符显示功能标识 */
BYTE bPlus; /* 打印正负号标识 */

BYTE bBigEndian; /* 取数阶标志 */
BYTE bBitTake; /* 按位取数标志 */
WORD wTakeBytes; /* 取数的字节数 */

BYTE bBitBigEndian; /* 按位取数阶标志 */
BYTE bRemainBits; /* 按位取数时剩余值有效比特数 */
WORD wTakeBits; /* 取数的比特数 */

DWORD dwRemainVal; /* 按位取数时剩余未用的值 */
DWORD dwReadVal; /* 待打印的数据值 */

} PrnFormatGlb_T;

typedef struct
{
DWORD dwH; /* 高阶字段值 */
DWORD dwL; /* 低阶字段值 */
} QWORD;

typedef struct
{
BYTE bNegtive; /* 正负数标识 */
LONG lPower; /* 数值阶 */
QWORD qwMantis; /* 尾数 */
} PFLOAT;

static BYTE sTempOutBuf[TEMP_BUF_SIZE_M * 2];

/*--------------------------------------------------------------------------*/

/* Function name : tranBits() */
/* Description   : 将数据按比特位逆序转换 */
/* Input         : dwTranVal - 待转换的数据        */
/*  : bBits - 数据的有效位数(待转换位数) */
/* Output  : 无 */
/* Return        : 无     */
/* Global Var    : 转换后的数 */
/* Author/Date   : R.Z.Tian/2003-5-22 08:22下午 */
/* Note          : 从低阶往高阶数比特位有效                                 */

/*--------------------------------------------------------------------------*/

static DWORD tranBits(DWORD dwTranVal, BYTE bBits)
{
BYTE bCount;
DWORD dwTempVal = 1, dwRetVal = 0;

for (bCount = 0; bCount < bBits / 2; bCount++, dwTempVal <<= 1)
{
dwRetVal += (dwTranVal & dwTempVal) << (bBits - 1 - bCount * 2);
dwRetVal += (dwTranVal >> (bBits - 1 - bCount * 2)) & dwTempVal;
}

return dwRetVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : isBigEndian() */
/* Description   : 测试本机的字节阶是否大数阶(低地址更高阶) */
/* Input         : 无 */
/* Output  : 无   */
/* Return        : 真或假 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-19 20:11 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

LONG isBigEndian(void)
{
union
{
BYTE cChar[2];
WORD wShort;
} u1;

u1.cChar[0] = 1, u1.cChar[1] = 2;

if (u1.wShort == (1 << 8) + 2)
{
return 1;
}

return 0;
}

/*--------------------------------------------------------------------------*/

/* Function name : GetTakeDataFormat() */
/* Description   : 获取从参数表中取数方式到打印控制结构 */
/* Input         : pbFmtStr - 格式控制串的起始地址 */
/*  : ppbData - 参数列表指针 */
/* Output  : ptFmt - 控制格式结构地址 */
/*  : ppbData - 参数列表指针 */
/* Return        : 下一个打印控制字符指针.    */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-20 11:57下午 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static char *GetTakeDataFormat(char *pbFmtStr, PrnFormatGlb_T *ptFmt, BYTE **p
pbData)
{
BYTE bTakeStep = 0, bTakeBytesDecl = 0, bTakeBitsDecl = 0;
char *pbRead = pbFmtStr;
LONG lFmtVal;

ptFmt->bBigEndian = 1;
ptFmt->wTakeBytes = PrnTakeCharBytesDft_M;

ptFmt->bBitTake = 0;
ptFmt->bBitBigEndian= 1;
ptFmt->wTakeBits = 0;

/*----------------------------------------------------------------------*/
/* 获得取数格式  ...(-  )(ddd)(.  (-  )(ddd))(a  )... */
/* 取数步骤:    s0   s1   s2   s3  s4   s5    s6  s7 */
/* 格式串最多有5个部分,在相应的状态如果取得的格式串与期望不符就退出 */
/*----------------------------------------------------------------------*/
while (pbRead[0] != '\0')
{
if (pbRead[0] == 'a')
{
pbRead++; break;
}

if (pbRead[0] == '-')
{
if (bTakeStep == 0)
{
bTakeStep = 1, ptFmt->bBigEndian = 0;
}
else if (bTakeStep == 3)
{
bTakeStep = 4, ptFmt->bBitBigEndian = 0;
}
else
{
break;
}

pbRead++; continue;
}

if (pbRead[0] == '.')
{
if (bTakeStep < 3)
{
bTakeStep = 3, ptFmt->bBitTake = 1;
}
else
{
break;
}

pbRead++; continue;
}

if (pbRead[0] == '*' || isDigit(pbRead[0]))
{
/*--------------------------------------------------------------*/
/* 取得数据长度,从格式串中取或者从参数列表中取 */
/*--------------------------------------------------------------*/
if (pbRead[0] == '*')
{
lFmtVal = (LONG)(*(SHORT *)(*ppbData)), *ppbData += 2, pbRead++;
}
else for (lFmtVal = 0; isDigit(pbRead[0]); pbRead++)
{
lFmtVal = lFmtVal * 10 + (pbRead[0] - '0');
}

if (bTakeStep < 3)
{
bTakeStep == 2, bTakeBytesDecl = 1;
if (lFmtVal < 0)
{
ptFmt->wTakeBytes = (WORD)(-lFmtVal), ptFmt->bBigEndian = 0;
}
else
{
ptFmt->wTakeBytes = (WORD)lFmtVal;
}
ptFmt->wTakeBytes = min(ptFmt->wTakeBytes, 0x1000);
}
else /* if (bTakeStep >= 3 && bTakeStep < 5) */
{
bTakeStep = 5, bTakeBitsDecl = 1;
if (lFmtVal < 0)
{
ptFmt->wTakeBits = (WORD)(-lFmtVal), ptFmt->bBitBigEndian = 0;
}
else
{
ptFmt->wTakeBits = (WORD)lFmtVal;
}
ptFmt->wTakeBits = min(ptFmt->wTakeBits, 0x1000);
}

ptFmt->bTakeDataDecl = 1;
continue;
}
else if (0 /* isPermitSpace(pbRead[0]) */)
{
pbRead++; continue;
}

break;
}

/*----------------------------------------------------------------------*/
/* 如果未声明取多少字节而又声明按位取操作数,则根据需求进行校验 */
/*----------------------------------------------------------------------*/
if (ptFmt->bBitTake)
{
if (!bTakeBitsDecl)
{
ptFmt->wTakeBits = 8;
}

if (!bTakeBytesDecl && ptFmt->bRemainBits >= ptFmt->wTakeBits)
{
ptFmt->wTakeBytes = 0;
}
else if (!bTakeBytesDecl)
{
ptFmt->bRemainBits = 0;
ptFmt->dwRemainVal = 0;
ptFmt->wTakeBytes = (ptFmt->wTakeBits - ptFmt->bRemainBits + 7) / 8;
}
}

return pbRead;
}

/*--------------------------------------------------------------------------*/

/* Function name : TakeDataByFormat() */
/* Description   : 按照格式控制符从内存地址中取数据 */
/* Input         : ptFmt - 控制格式结构地址 */
/*  : ppbDataAddr - 取数开始位置地址指针 */
/* Output  : 无 */
/* Return        : 下一个取数地址指针.     */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 12:15上午 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static LONG TakeDataByFormat(PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD w
DataLen)
{
int i;
WORD wTakeBytes = ptFmt->wTakeBytes;
WORD wTakeBits = ptFmt->wTakeBits, wReadBits;
BYTE *pbData = *ppbDataAddr, bReadChar;
DWORD dwReadVal = 0;

/*----------------------------------------------------------------------*/
/* 不按位取数,清空按位取数的保留值,取数溢出时只保留低位有效值 */
/*----------------------------------------------------------------------*/
if (!ptFmt->bBitTake)
{
ptFmt->dwRemainVal = 0;
ptFmt->bRemainBits = 0;

for (i = 0; i < ptFmt->wTakeBytes && i < wDataLen; i++)
{
if (ptFmt->bBigEndian)
{
dwReadVal = (dwReadVal << 8) + *pbData++;
}
else
{
dwReadVal += ((*pbData++) << (i * 8));
}
}

ptFmt->dwReadVal = dwReadVal, *ppbDataAddr = pbData;

return 0;
}

/*----------------------------------------------------------------------*/
/* 检验要取的比特数的有效性 */
/*----------------------------------------------------------------------*/
if (wTakeBits > wTakeBytes * 8 + ptFmt->bRemainBits)
{
wTakeBits = wTakeBytes * 8 + ptFmt->bRemainBits;
}
else if (ptFmt->bRemainBits >= wTakeBits)
{
ptFmt->bRemainBits -= wTakeBits;

if (ptFmt->bBigEndian)
{
dwReadVal = ptFmt->dwRemainVal >> ptFmt->bRemainBits;
if (ptFmt->bRemainBits < 32)
{
ptFmt->dwRemainVal &= (1 << (ptFmt->bRemainBits)) - 1;
}
}
else
{
if (wTakeBits < 32)
{
dwReadVal = ptFmt->dwRemainVal & ((1 << wTakeBits) - 1);
}
else
{
dwReadVal = ptFmt->dwRemainVal;
}
ptFmt->dwRemainVal >>= wTakeBits;
}

ptFmt->dwReadVal = dwReadVal, *ppbDataAddr = pbData;

return 1;
}

dwReadVal = ptFmt->dwRemainVal, wReadBits = (WORD)ptFmt->bRemainBits;

/*----------------------------------------------------------------------*/
/* 进行取数操作,边取数边取比特数 */
/*----------------------------------------------------------------------*/
for (i = 0; i < wTakeBytes && i < wDataLen; i++, ptFmt->bRemainBits += 8)
{
bReadChar = *pbData++;

if (!ptFmt->bBitBigEndian)
{
bReadChar = (BYTE)tranBits((DWORD)bReadChar, 8);
}

if (ptFmt->bBigEndian)
{
ptFmt->dwRemainVal = (ptFmt->dwRemainVal << 8) + bReadChar;
if (wReadBits + 8 <= wTakeBits)
{
wReadBits += 8;
dwReadVal = (dwReadVal << 8) + bReadChar;
}
else if (wReadBits < wTakeBits)
{
dwReadVal = (dwReadVal << (wTakeBits - wReadBits)) +
(bReadChar >> (8 - (wTakeBits - wReadBits)));
wReadBits = wTakeBits;
}
}
else
{
ptFmt->dwRemainVal += (bReadChar << ptFmt->bRemainBits);
if (wReadBits + 8 <= wTakeBits)
{
wReadBits += 8;
dwReadVal += (bReadChar << ptFmt->bRemainBits);
}
else if (wReadBits < wTakeBits)
{
dwReadVal += (bReadChar << ptFmt->bRemainBits);
if (wTakeBits < 32)
{
dwReadVal &= (1 << wTakeBits) - 1;
}
wReadBits = wTakeBits;
}
}
}

/*----------------------------------------------------------------------*/
/* 修正剩余量 */
/*----------------------------------------------------------------------*/
ptFmt->bRemainBits -= wTakeBits;

if (ptFmt->bBigEndian)
{
if (ptFmt->bRemainBits < 32)
{
ptFmt->dwRemainVal &= (1 << (ptFmt->bRemainBits)) - 1;
}
}
else
{
ptFmt->dwRemainVal >>= wTakeBits;
}

ptFmt->dwReadVal = dwReadVal;

/*
if (!ptFmt->bBitBigEndian)
{
ptFmt->dwReadVal = tranBits(dwReadVal, wTakeBits);
}
*/

*ppbDataAddr = pbData;

return 0;
}

/*--------------------------------------------------------------------------*/

/* Function name : ParsePercentFormat() */
/* Description   : 处理百分号'%'格式控制符 */
/* Input         : pbReadFmt - 当前的格式控制符位置指针 */
/*  : ppbData - 参数列表指针 */
/* Output  : ptFmt - 打印格式控制结构 */
/*  : ppbData - 参数列表指针 */
/* Return        : 下一个打印格式控制符的位置 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2002-01-16                                      */

/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static char *ParsePercentFormat(char *pbReadFmt, PrnFormatGlb_T *ptFmt, BYTE *
*ppbData)
{
BYTE bDataTypeDecl = 0;
BYTE bParseStep = 0;
char *pbRead = pbReadFmt;
BYTE *pbData = *ppbData;
LONG lFmtVal;

/*----------------------------------------------------------------------*/
/*  初始化打印描述结构             */
/*----------------------------------------------------------------------*/
ptFmt->lWidth = PrnWidthDft_M;
ptFmt->lPrecision = PrnWidthDft_M;

ptFmt->bType = 'd';
ptFmt->bSubType = '\0';
ptFmt->bMod = 'l';
ptFmt->bTakeDataDecl= 0;

ptFmt->bPreChar = ' ';
ptFmt->bRight = 1;
ptFmt->bAlter = 0;
ptFmt->bPlus = 0;

ptFmt->dwReadVal = 0;

/*----------------------------------------------------------------------*/
/* '%'后的格式说明,有两类,一类是取数的,一类是打印串,要区别对待 */
/*----------------------------------------------------------------------*/
while (pbRead[0] != '\0' && pbRead - pbReadFmt < 32 &&
(isDigit(pbRead[0]) || pbRead[0] == '*' ||
pbRead[0] == '.' || pbRead[0] == '-' /* || isPermitSpace(pbRead[0]) */))
{
pbRead++;
}

/*----------------------------------------------------------------------*/
/* 含有取数说明时,按其格式至数据表中取操作数,否则按默认值取数 */
/*----------------------------------------------------------------------*/
if (pbRead[0] == 'a')
{
pbRead = GetTakeDataFormat(pbReadFmt, ptFmt, ppbData);
}
else
{
ptFmt->bBigEndian = isBigEndian() ? 1 : 0;
ptFmt->wTakeBytes = PrnTakeDataBytesDft_M;

ptFmt->bBitTake = 0;
ptFmt->bBitBigEndian= 1;
ptFmt->wTakeBits = 0,

ptFmt->bRemainBits = 0;
ptFmt->dwRemainVal = 0;

pbRead = pbReadFmt;
}

bParseStep = 1;

/*----------------------------------------------------------------------*/
/* 解析打印格式串 */
/*   获得取数格式  ...(*a)(-,+,#)(0  )(ddd)(.  (ddd))(h,l,L)(f  )... */
/*   取数步骤:    s0   s1  s2     s3   s4   s5  s6    s7    s8  s9 */
/* 格式串最多有5个部分,在相应的状态如果取得的格式串与期望不符就退出 */
/*----------------------------------------------------------------------*/
while (pbRead[0] != '\0')
{
/*------------------------------------------------------------------*/
/* 对齐符,符号显示,以及进制显示控制符不分先后,可有可无 */
/*------------------------------------------------------------------*/
if (pbRead[0] == '-' || pbRead[0] == '+' || pbRead[0] == '#')
{
if (bParseStep > 2)
{
break;
}

if (pbRead[0] == '-' && ptFmt->bRight)
{
ptFmt->bRight = 0;
}
else if (pbRead[0] == '-' && bParseStep == 2 && !ptFmt->bRight)
{
break;
}

if (pbRead[0] == '+' && !ptFmt->bPlus)
{
ptFmt->bPlus = 1;
}
else if (pbRead[0] == '+' && bParseStep == 2 && ptFmt->bPlus)
{
break;
}

if (pbRead[0] == '#' && !ptFmt->bAlter)
{
ptFmt->bAlter = 1;
}
else if (pbRead[0] == '#' && bParseStep == 2 && ptFmt->bAlter)
{
break;
}

bParseStep = 2; pbRead++; continue;
}

if (pbRead[0] == '0')
{
if (bParseStep <= 2)
{
ptFmt->bPreChar = pbRead[0];
}
else
{
break;
}

bParseStep = 3; pbRead++; continue;
}

if (pbRead[0] == '.')
{
if (bParseStep >= 5)
{
break;
}

bParseStep = 5; pbRead++; continue;
}

/*------------------------------------------------------------------*/
/* 取数据宽度,对于格式'*',从参数列表中取宽度指示(只认一个字节) */
/*------------------------------------------------------------------*/
if (pbRead[0] == '*' || isDigit(pbRead[0]))
{
/*--------------------------------------------------------------*/
/* 取得数据长度,从格式串中取或者从参数列表中取 */
/*--------------------------------------------------------------*/
if (pbRead[0] == '*')
{
lFmtVal = (LONG)(*(SHORT *)(*ppbData)), *ppbData += 2, pbRead++;
}
else for (lFmtVal = 0; isDigit(pbRead[0]); pbRead++)
{
lFmtVal = lFmtVal * 10 + (pbRead[0] - '0');
}

/*--------------------------------------------------------------*/
/* 将长度赋给宽度或者精度 */
/*--------------------------------------------------------------*/
if (bParseStep < 4 && lFmtVal < 0)
{
ptFmt->bRight = 0;
lFmtVal = min(-lFmtVal, 80);
}
else
{
lFmtVal = min(-lFmtVal, 80);
}

if (bParseStep < 4)
{
ptFmt->lWidth = lFmtVal, bParseStep = 4;
}
else if (bParseStep == 5)
{
ptFmt->lPrecision = -lFmtVal, bParseStep = 6;
}
else
{
break;
}

continue;

} /* if (pbRead[0] == '*' || isDigit(pbRead[0])) */

/*------------------------------------------------------------------*/
/* 检验长度模式 */
/*------------------------------------------------------------------*/
if ((bParseStep < 7) &&
(pbRead[0] == 'h' || pbRead[0] == 'l' || pbRead[0] == 'L'))
{
ptFmt->bMod = pbRead[0];
bParseStep = 7; pbRead++; continue;
}

if (isFormatEndChar(pbRead[0]))
{
ptFmt->bType = *pbRead++, bParseStep = 8;
ptFmt->bSubType = pbRead[0];
if (ptFmt->bType == 'z' && pbRead[0] != '\0')
{
pbRead++;
}
break;
}
else if (0 /* isPermitSpace(pbRead[0]) */)
{
pbRead++; continue;
}

break;

} /* while (pbRead[0] != '\0') */

/*----------------------------------------------------------------------*/
/* 未找到数据声明格式,则取消所有的格式指定,将'%'后的字符原样输出 */
/*----------------------------------------------------------------------*/
if (!ptFmt->bTakeDataDecl && bParseStep < 7)
{
ptFmt->bType = '\0', *ppbData = pbData, pbRead = pbReadFmt;
}

return pbRead;
}

/*--------------------------------------------------------------------------*/

/* Function name : PutChar() */
/* Description   : 向特定内存输出一个字符 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wChar - 待输出字符(可以是宽字符格式) */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 16:16 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG PutChar(BYTE *pbOutLoc, BYTE bChar)
{
BYTE *pbPut = pbOutLoc;
ULONG dwPrnCount;

*pbPut++ = bChar;

pbPut[0] = '\0';

dwPrnCount = pbPut - pbOutLoc;

return dwPrnCount;
}

/*--------------------------------------------------------------------------*/

/* Function name : PutString() */
/* Description   : 向特定内存输出一个字符串 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbString - 待输出字符串 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 16:16 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG PutString(BYTE *pbOutLoc, WORD wBufLen, BYTE *pbString)
{
BYTE *pbPut = pbOutLoc, *pbRead = pbString;
ULONG dwPrnCount = 0;

while (pbRead[0] != '\0' && dwPrnCount < wBufLen)
{
*pbPut++ = *pbRead++, dwPrnCount++;
}

pbPut[0] = '\0';

return dwPrnCount;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutWidthCheck() */
/* Description   : 输出宽度校验 */
/* Input         : ppbS - 输出起始地址 */
/*  : ppbE - 输出终止地址 */
/*  : pbFmt - 打印格式控制结构 */
/*  : bKeepLen - 保留长度 */
/* Output  : ppbBegin - 输出起始地址 */
/*  : ppbEnd - 输出终止地址 */
/* Return        : 功能或者失败 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 9:24 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

LONG OutPutWidthCheck(BYTE **ppbS, BYTE **ppbE, PrnFormatGlb_T *ptFmt, BYTE bK
eepLen)
{
BYTE *pbOutBeg = *ppbS, *pbOutEnd = *ppbE;

/*----------------------------------------------------------------------*/
/* 实际输出长度比限定长度超长,根据对齐方式在前面或后面选择打上'*'标记 */
/*----------------------------------------------------------------------*/
if (ptFmt->lWidth >= 0 && pbOutEnd - pbOutBeg + bKeepLen > ptFmt->lWidth)
{
if (ptFmt->bRight && !ptFmt->bAlter)
{
pbOutBeg = pbOutEnd + bKeepLen - ptFmt->lWidth;
pbOutBeg[0] =  '*';
}
else if (/* ptFmt->bRight && */ !ptFmt->bAlter)
{
pbOutEnd = pbOutBeg - bKeepLen + ptFmt->lWidth;
*(pbOutEnd - 1) = '*';
}

*ppbS = pbOutBeg, *ppbE = pbOutEnd;

return 1;
}

/*----------------------------------------------------------------------*/
/* 否则如果有宽度及精度指示,按其值进行'0'填充 */
/*----------------------------------------------------------------------*/
while (pbOutEnd - pbOutBeg < TEMP_BUF_SIZE_M - 1 &&
pbOutEnd - pbOutBeg < ptFmt->lPrecision)
{
*(--pbOutBeg) = '0';
}

if (ptFmt->bRight)
{
while (pbOutEnd - pbOutBeg < TEMP_BUF_SIZE_M - 1 &&
pbOutEnd - pbOutBeg + bKeepLen < ptFmt->lWidth)
{
*(--pbOutBeg) = ptFmt->bPreChar;
}
}
else /* if (!ptFmt->bRight) */
{
while (pbOutEnd - pbOutBeg < TEMP_BUF_SIZE_M - 1 &&
pbOutEnd - pbOutBeg + bKeepLen < ptFmt->lWidth)
{
*(pbOutEnd++) = ptFmt->bPreChar;
}
}

*ppbS = pbOutBeg, *ppbE = pbOutEnd;

return 0;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutDecimal() */
/* Description   : 按照打印格式符从相应的地址中取出数据并打印 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 9:24 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutDecimal(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE bNegtive = 0, bPreKeepLen = 0;
DWORD dwAbsVal = 0, dwTempVal;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->lPrecision > 0 && ptFmt->lWidth < ptFmt->lPrecision + 1)
{
ptFmt->lWidth = ptFmt->lPrecision + 1;
}

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->bType == 'u' && ptFmt->bMod == 'h')
{
dwAbsVal = (WORD)ptFmt->dwReadVal;
}
else if (ptFmt->bType == 'u' /* && ptFmt->bMod != 'h' */)
{
dwAbsVal = ptFmt->dwReadVal;
}
else if (/* ptFmt->bType == 'd' && */ ptFmt->bMod == 'h')
{
if ((SHORT)ptFmt->dwReadVal < 0)
{
dwAbsVal = -((SHORT)ptFmt->dwReadVal), bNegtive = 1;
}
else
{
dwAbsVal = (SHORT)ptFmt->dwReadVal;
}
}
else /* if (ptFmt->bType == 'd' && ptFmt->bMod != 'h') */
{
if ((LONG)ptFmt->dwReadVal < 0)
{
dwAbsVal = -((LONG)ptFmt->dwReadVal), bNegtive = 1;
}
else
{
dwAbsVal = (LONG)ptFmt->dwReadVal;
}
}

if (dwAbsVal == 0)
{
*(--pbOutBeg) = '0';
}
/*----------------------------------------------------------------------*/
/* 对于没有32位除法指令的机器来说,下面的代码可能有问题 */
/*----------------------------------------------------------------------*/
else for (dwTempVal = dwAbsVal; dwTempVal > 0; /* none */)
{
*(--pbOutBeg) = (BYTE)(dwTempVal % 10 + '0'), dwTempVal /= 10;
}

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
if (ptFmt->bAlter || !ptFmt->bRight)
{
bPreKeepLen = (bNegtive || ptFmt->bPlus) ? 1 : 0;
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (bNegtive)
{
*(--pbOutBeg) = '-';
}
else if (ptFmt->bPlus)
{
*(--pbOutBeg) = '+';
}
}
else
{
if (bNegtive)
{
*(--pbOutBeg) = '-';
}
else if (ptFmt->bPlus)
{
*(--pbOutBeg) = '+';
}

OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, 0);
}

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutHex() */
/* Description   : 按照打印格式符从相应的地址中取出数据并打印 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 16:57 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutHex(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE baHexTbl[16];
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE bChar = '0', bPreKeepLen = 0;
DWORD dwAbsVal = 0, dwTempVal;

bPreKeepLen = (ptFmt->bAlter) ? 3 : 0;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->lPrecision > 0 && ptFmt->lWidth < ptFmt->lPrecision + bPreKeepLen)

{
ptFmt->lWidth = ptFmt->lPrecision + bPreKeepLen;
}

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

for (dwTempVal = 0; dwTempVal < 9; dwTempVal++)
{
baHexTbl[dwTempVal] = bChar++;
}

bChar = (ptFmt->bType == 'x') ? 'a' : 'A';
for (dwTempVal = 10; dwTempVal < 16; dwTempVal++)
{
baHexTbl[dwTempVal] = bChar++;
}

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->bMod == 'h')
{
dwAbsVal = (WORD)ptFmt->dwReadVal;
}
else /* if (ptFmt->bMod != 'h') */
{
dwAbsVal = ptFmt->dwReadVal;
}

if (dwAbsVal == 0)
{
*(--pbOutBeg) = '0';
}
else for (dwTempVal = dwAbsVal; dwTempVal > 0; /* none */)
{
*(--pbOutBeg) = baHexTbl[dwTempVal & 0xf], dwTempVal >>= 4;
}

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (ptFmt->bAlter)
{
*(--pbOutBeg) = ' ';
*(--pbOutBeg) = (ptFmt->bType == 'x' ? 'x' : 'X');
*(--pbOutBeg) = '0';
}

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutOctet() */
/* Description   : 按照打印格式符从相应的地址中取出数据并打印 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 16:57 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutOctet(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE bPreKeepLen = 0;
DWORD dwAbsVal = 0, dwTempVal;

bPreKeepLen = (ptFmt->bAlter) ? 2 : 0;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->lPrecision > 0 && ptFmt->lWidth < ptFmt->lPrecision + bPreKeepLen)

{
ptFmt->lWidth = ptFmt->lPrecision + bPreKeepLen;
}

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->bMod == 'h')
{
dwAbsVal = (WORD)ptFmt->dwReadVal;
}
else /* if (ptFmt->bMod != 'h') */
{
dwAbsVal = ptFmt->dwReadVal;
}

if (dwAbsVal == 0)
{
*(--pbOutBeg) = '0';
}
else for (dwTempVal = dwAbsVal; dwTempVal > 0; /* none */)
{
*(--pbOutBeg) = (BYTE)((dwTempVal & 7) + '0'), dwTempVal >>= 3;
}

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (ptFmt->bAlter)
{
*(--pbOutBeg) = ' ';
*(--pbOutBeg) = 'O';
}

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutBinary() */
/* Description   : 按照打印格式符从相应的地址中取出数据并打印 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 17:31 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutBinary(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE bPreKeepLen = 0;
DWORD dwAbsVal = 0, dwTempVal;

bPreKeepLen = (ptFmt->bAlter) ? 2 : 0;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->lPrecision > 0 && ptFmt->lWidth < ptFmt->lPrecision + bPreKeepLen)

{
ptFmt->lWidth = ptFmt->lPrecision + bPreKeepLen;
}

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->bMod == 'h')
{
dwAbsVal = (WORD)ptFmt->dwReadVal;
}
else /* if (ptFmt->bMod != 'h') */
{
dwAbsVal = ptFmt->dwReadVal;
}

if (dwAbsVal == 0)
{
*(--pbOutBeg) = '0';
}
else for (dwTempVal = dwAbsVal; dwTempVal > 0; /* none */)
{
*(--pbOutBeg) = (BYTE)((dwTempVal & 1) + '0'), dwTempVal >>= 1;
}

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (ptFmt->bAlter)
{
*(--pbOutBeg) = ' ';
*(--pbOutBeg) = 'b';
}

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutChar() */
/* Description   : 按照打印格式符从相应的地址中取出字符并打印 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 17:31 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutChar(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
DWORD dwTempVal;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据,并检验取数据默认值 */
/*----------------------------------------------------------------------*/
if (!ptFmt->bTakeDataDecl)
{
ptFmt->wTakeBytes = PrnTakeCharBytesDft_M;
}
ptFmt->lPrecision = 0;

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

*(--pbOutBeg) = (char)ptFmt->dwReadVal;

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, 0);

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutString() */
/* Description   : 按照打印格式符从相应的地址中取出字符串并打印 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 17:31 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutString(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbReadData;
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M / 2 - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M / 2 - 1];
DWORD dwTempVal;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据 */
/*----------------------------------------------------------------------*/
ptFmt->lPrecision = 0;

for (pbReadData = *ppbDataAddr; pbReadData[0] != '\0'; /* none */)
{
if (pbOutEnd - sTempOutBuf < TEMP_BUF_SIZE_M - 1)
{
*pbOutEnd++ = *pbReadData++;
}
}

*ppbDataAddr = pbReadData;

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, 0);

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : zeroQword() */
/* Description   : 判断QWORD是否为0 */
/* Input         : qwVal - 待判断QWORD */
/* Output  : 无   */
/* Return        : 是或不是 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-24 12:12上午 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static LONG zeroQword(QWORD qwVal)
{
if (qwVal.dwH == 0 && qwVal.dwL == 0)
{
return 1;
}

return 0;
}

/*--------------------------------------------------------------------------*/

/* Function name : QwordPlus() */
/* Description   : 两个四字长的数据相加 */
/* Input         : qwVal1 - 第一个四字长操作数 */
/*   : qwVal2 - 第二个四字长操作数 */
/* Output  : 无   */
/* Return        : 两个四字长操作数的和 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 10:34下午 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static QWORD QwordPlus(QWORD qwVal1, QWORD qwVal2)
{
QWORD qwRet = {0, 0};

qwRet.dwL = qwVal1.dwL + qwVal2.dwL;
qwRet.dwH = qwVal1.dwH + qwVal2.dwH;

/*----------------------------------------------------------------------*/
/* 数据溢出校正 */
/*----------------------------------------------------------------------*/
qwRet.dwH += (qwVal1.dwL != 0 && ~qwVal1.dwL + 1 < qwVal2.dwL) ? 1 : 0;

return qwRet;
}

/*--------------------------------------------------------------------------*/

/* Function name : QwordMinus() */
/* Description   : 两个四字长的数据相减 */
/* Input         : qwVal1 - 第一个四字长操作数 */
/*   : qwVal2 - 第二个四字长操作数 */
/* Output  : 无   */
/* Return        : 两个四字长操作数的差 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 11:58下午 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static QWORD QwordMinus(QWORD qwVal1, QWORD qwVal2)
{
QWORD qwRet = {0, 0};

qwRet.dwL = qwVal1.dwL - qwVal2.dwL;
qwRet.dwH = qwVal1.dwH - qwVal2.dwH;

/*----------------------------------------------------------------------*/
/* 数据溢出校正 */
/*----------------------------------------------------------------------*/
qwRet.dwH -= (qwVal1.dwL < qwVal2.dwL) ? 1 : 0;

return qwRet;
}

/*--------------------------------------------------------------------------*/

/* Function name : QwordMultiNum() */
/* Description   : 四字长的数据乘以一个数 */
/* Input         : qwVal - 四字长操作数 */
/*   : BYTE - 乘数 */
/* Output  : 无   */
/* Return        : 乘积 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 10:48下午 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static QWORD QwordMultiNum(QWORD qwVal, BYTE bVal)
{
DWORD dwOverVal;
QWORD qwRet = {0, 0};

qwRet.dwH = qwVal.dwH * bVal;
qwRet.dwL = qwVal.dwL * bVal;

/*----------------------------------------------------------------------*/
/* 低阶数据溢出校正 */
/*----------------------------------------------------------------------*/
dwOverVal = ((qwVal.dwL & 0xffff) * bVal) >> 16;
dwOverVal = (dwOverVal + ((qwVal.dwL >> 16) * bVal)) >> 16;
qwRet.dwH += dwOverVal;

return qwRet;
}

/*--------------------------------------------------------------------------*/

/* Function name : QwordDividNum() */
/* Description   : 四字长的数据除以一个数 */
/* Input         : qwVal - 四字长操作数 */
/*   : bVal - 除数 */
/* Output  : 无   */
/* Return        : 商 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 10:34下午 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static QWORD QwordDividNum(QWORD qwVal, BYTE bVal)
{
DWORD dwResidue;
QWORD qwRet = {0, 0}, qwTemp = {0, 0};

/*----------------------------------------------------------------------*/
/* 特殊值快速处理 */
/*----------------------------------------------------------------------*/
if (bVal == 2)
{
qwRet.dwH = qwVal.dwH >> 1;
qwRet.dwL = ((qwVal.dwH & 1) << 31) | (qwVal.dwL >> 1);
return qwRet;
}

qwRet.dwH = qwVal.dwH / bVal;
qwRet.dwL = qwVal.dwL / bVal;

/*----------------------------------------------------------------------*/
/* 先计算高位四字节除以bVal之后的余数,即不足以在dwH上产生商值的余数 */
/*----------------------------------------------------------------------*/
dwResidue = qwVal.dwH % bVal;

if (qwVal.dwH == 0 || dwResidue == 0)
{
return qwRet;
}

/*----------------------------------------------------------------------*/
/* 将余数转加到dwL上求商及余数,先求得在dwL高阶双字节上可能产生的商 */
/*----------------------------------------------------------------------*/
qwTemp.dwL = ((dwResidue << 16) / bVal) << 16;

qwRet = QwordPlus(qwRet, qwTemp);

dwResidue = (dwResidue << 16) % bVal;

/*----------------------------------------------------------------------*/
/* 再将余数转加到dwL的低两位字节上,求得在dwL低阶双字节上可能产生的商 */
/*----------------------------------------------------------------------*/
qwTemp.dwL = ((dwResidue << 16) / bVal);

qwRet = QwordPlus(qwRet, qwTemp);

/*----------------------------------------------------------------------*/
/* 高位四字节计算后的余数与低位的余数累加,仍可能改变商的值 */
/*----------------------------------------------------------------------*/
dwResidue = (dwResidue << 16) % bVal + qwVal.dwL % bVal;

qwTemp.dwL = dwResidue / bVal;

qwRet = QwordPlus(qwRet, qwTemp);

return qwRet;
}

/*--------------------------------------------------------------------------*/

/* Function name : QwordModNum() */
/* Description   : 四字长的数据除以一个数的余数 */
/* Input         : qwVal - 四字长操作数 */
/*   : bVal - 除数 */
/* Output  : 无   */
/* Return        : 商 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-24 12:06上午 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static BYTE QwordModNum(QWORD qwVal, BYTE bVal)
{
BYTE bRet;
QWORD qwTemp = {0, 0};

qwTemp = QwordMinus(qwVal, QwordMultiNum(QwordDividNum(qwVal, bVal), bVal));

bRet = (BYTE)(qwTemp.dwL & 0xff);

return bRet;
}

/*--------------------------------------------------------------------------*/

/* Function name : FloatGetDecMantisFromBin() */
/* Description   : 将二进制的尾数转化为一个十进制的浮点数 */
/* Input         : qwBinMantis - 二进制尾数 */
/* Output  : 无   */
/* Return        : 十进制表示的浮点数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 07:44下午 */
/* Note          : 二进制尾数最高位有效,十进制尾数最低位有效(尾数是整数)   */

/*--------------------------------------------------------------------------*/

static PFLOAT FloatGetDecMantisFromBin(QWORD qwBinMantis)
{
int i = 0;
PFLOAT tDecF = {0, 0, {0, 0}}; /* 返回值, 以tDecF.dwL=1为整数起点 */
QWORD qwTemp1 = {0, 5}; /* (0.5^n)乘以(10^x)得到的整数部分 */

if (zeroQword(qwBinMantis))
{
return tDecF;
}

/*----------------------------------------------------------------------*/
/* 尾数计算是从小数点后开始,因此为-1次方 */
/*----------------------------------------------------------------------*/
tDecF.lPower = -1;

while (qwBinMantis.dwH != 0)
{
if (qwBinMantis.dwH & 0x80000000)
{
tDecF.qwMantis = QwordPlus(tDecF.qwMantis, qwTemp1);
}

qwBinMantis.dwH <<= 1, i++;
/*------------------------------------------------------------------*/
/* 确保尾数不会溢出 0x19999998 * 10 < 0xffffffff < 0x19999999 * 10 */
/*------------------------------------------------------------------*/
if (tDecF.qwMantis.dwH < 0x19999999)
{
tDecF.lPower--;
qwTemp1 = QwordMultiNum(qwTemp1, 5);
tDecF.qwMantis = QwordMultiNum(tDecF.qwMantis, 10);
}
else
{
qwTemp1 = QwordDividNum(qwTemp1, 2);
}
}

if (qwBinMantis.dwL == 0)
{
return tDecF;
}

/*----------------------------------------------------------------------*/
/* 双精度数,跳到2^(-32)之后 */
/*----------------------------------------------------------------------*/
for (/* none */; i < 32; i++)
{
if (zeroQword(tDecF.qwMantis) && qwTemp1.dwH < 0x19999999)
{
tDecF.lPower--;
qwTemp1 = QwordMultiNum(qwTemp1, 5);
}
else if (tDecF.qwMantis.dwH < 0x19999999)
{
tDecF.lPower--;
qwTemp1 = QwordMultiNum(qwTemp1, 5);
tDecF.qwMantis = QwordMultiNum(tDecF.qwMantis, 10);
}
else
{
qwTemp1 = QwordDividNum(qwTemp1, 2);
}
}

/*----------------------------------------------------------------------*/
/* 计算后11个比特位产生的有效精度 */
/*----------------------------------------------------------------------*/
while (qwBinMantis.dwL != 0)
{
if (qwBinMantis.dwL & 0x80000000)
{
tDecF.qwMantis = QwordPlus(tDecF.qwMantis, qwTemp1);
}

qwBinMantis.dwL <<= 1, i++;
if (tDecF.qwMantis.dwH < 0x19999999)
{
tDecF.lPower--;
qwTemp1 = QwordMultiNum(qwTemp1, 5);
tDecF.qwMantis = QwordMultiNum(tDecF.qwMantis, 10);
}
else
{
qwTemp1 = QwordDividNum(qwTemp1, 2);
}
}

return tDecF;
}

/*--------------------------------------------------------------------------*/

/* Function name : FloatDecMultiBinPower() */
/* Description   : 将十进制的浮点数乘以2的某次方 */
/* Input         : tDecF - 十进制表示的浮点数 */
/* Output  : 无   */
/* Return        : 十进制表示的浮点数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 07:44下午 */
/* Note          : 二进制尾数最高位有效,十进制尾数最低位有效(尾数是整数)   */

/*--------------------------------------------------------------------------*/

static PFLOAT FloatDecMultiBinPower(PFLOAT tDecF, LONG lPower)
{
if (lPower == 0 || zeroQword(tDecF.qwMantis))
{
return tDecF;
}

if (lPower < 0) for (/* none */; lPower != 0; lPower++)
{
tDecF.qwMantis = QwordDividNum(tDecF.qwMantis, 2);
if (tDecF.qwMantis.dwH < 0x19999999)
{
tDecF.lPower--;
tDecF.qwMantis = QwordMultiNum(tDecF.qwMantis, 10);
}
}
else for (/* none */; lPower != 0; lPower--)
{
if (tDecF.qwMantis.dwH & 0x80000000)
{
tDecF.lPower++;
tDecF.qwMantis = QwordDividNum(tDecF.qwMantis, 10);
}
tDecF.qwMantis = QwordMultiNum(tDecF.qwMantis, 2);
}

return tDecF;
}

/*--------------------------------------------------------------------------*/

/* Function name : FloatBinToDec() */
/* Description   : 将以二进制表示的浮点数转化为以十进制表示的浮点数 */
/* Input         : tBinF - 二进制表示的浮点数 */
/* Output  : 无   */
/* Return        : 十进制表示的浮点数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 07:14下午 */
/* Note          : 二进制尾数最高位有效,十进制尾数最低位有效(尾数是整数)   */

/*--------------------------------------------------------------------------*/

static PFLOAT FloatBinToDec(PFLOAT tBinF)
{
PFLOAT tDecF = {0, 0, {0, 0}};
QWORD qwTemp = {0, 0};

/*----------------------------------------------------------------------*/
/* 首先得到十进制的尾数,并计算递减的阶差 */
/*----------------------------------------------------------------------*/
tDecF = FloatGetDecMantisFromBin(tBinF.qwMantis);

/*----------------------------------------------------------------------*/
/* 十进制到二进制的阶差转换 */
/*----------------------------------------------------------------------*/
tDecF = FloatDecMultiBinPower(tDecF, tBinF.lPower);

/*----------------------------------------------------------------------*/
/* 十进制的尾数都是用整数表示的,下面进行数值调整 */
/*----------------------------------------------------------------------*/
if (!zeroQword(tDecF.qwMantis)) while (QwordModNum(tDecF.qwMantis, 10) == 0)
{
tDecF.lPower++;
tDecF.qwMantis = QwordDividNum(tDecF.qwMantis, 10);
}

/*----------------------------------------------------------------------*/
/* 四舍五入调整,53位有效位,11位无效位,在低10个比特位上进行舍弃补偿 */
/*----------------------------------------------------------------------*/
if (tDecF.qwMantis.dwH > 0x1fffff)
{
qwTemp.dwL = 0x3ff;
tDecF.qwMantis = QwordPlus(tDecF.qwMantis, qwTemp);
tDecF.lPower++;
tDecF.qwMantis = QwordDividNum(tDecF.qwMantis, 10);
tDecF.lPower++;
tDecF.qwMantis = QwordDividNum(tDecF.qwMantis, 10);
tDecF.lPower++;
tDecF.qwMantis = QwordDividNum(tDecF.qwMantis, 10);
while (QwordModNum(tDecF.qwMantis, 10) == 0)
{
tDecF.lPower++;
tDecF.qwMantis = QwordDividNum(tDecF.qwMantis, 10);
}
}

tDecF.bNegtive = tBinF.bNegtive;

return tDecF;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutFloat() */
/* Description   : 输出浮点数 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-22 10:11下午 */
/* Note          :                                                          */

/* 单精度实数: */
/*    +--+---------------+------------------------------------------------+ */

/*    |b |b b b b b b b b|b b b b b b b b b b b b b b b b b b b b b b b b | */

/*    +--+---------------+------------------------------------------------+ */

/*    |±|指数阶码, 8比特| 尾数, 23比特, 共32比特                         | */

/*    +--+---------------+------------------------------------------------+ */

/* 双精度实数: */
/*    +--+-----------+----------------------------------------------------+ */

/*    |b |bbbbbbbbbbb|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| */

/*    +--+-----------+----------------------------------------------------+ */

/*    |±|阶码,11比特| 尾数, 52比特, 共64比特                             | */

/*    +--+-----------+----------------------------------------------------+ */

/*--------------------------------------------------------------------------*/

static ULONG OutPutFloat(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
DWORD dwTempVal;
QWORD qwTemp;
LONG lValLen = 0; /* 有效数据长度 */
BYTE bScientDisp = 0; /* 科学计数法显示数据 */
BYTE bPreKeepLen = 0; /* 保留输出数据长度 */
PFLOAT tBinF = {0, 0, {0, 0}}; /* 二进制表示浮点数 */
PFLOAT tDecF = {0, 0, {0, 0}}; /* 十进制表示浮点数 */
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据,并检验取数据默认值 */
/*----------------------------------------------------------------------*/
if (ptFmt->lPrecision < 0)
{
ptFmt->lPrecision = PrnPreciDft_M;
}
if (!ptFmt->bTakeDataDecl)
{
ptFmt->wTakeBytes = PrnTakeFloatBytesDft_M;
}

/*----------------------------------------------------------------------*/
/* 按双精度或者单精度数据定义取数,二进制尾数上的最高有效'1'往往被省略 */
/*----------------------------------------------------------------------*/
if (ptFmt->wTakeBytes <= 4)
{
ptFmt->bBitTake = 0;
ptFmt->wTakeBytes = 4;
TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

tBinF.bNegtive = (ptFmt->dwReadVal >> 31) ? 1 : 0;
tBinF.lPower = (LONG)((ptFmt->dwReadVal >> 23) & 0xff);
tBinF.qwMantis.dwH = (ptFmt->dwReadVal & 0x7fffff) << 8;
tBinF.qwMantis.dwL = 0;
tBinF.qwMantis.dwH |= (tBinF.lPower == 0) ? 0 : 0x80000000;
tBinF.lPower = tBinF.lPower - FloatZeroPowerRef_M + 1;
}
else
{
ptFmt->bBitTake = 0;
ptFmt->wTakeBytes = 4;

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);
if (ptFmt->bBigEndian)
{
tBinF.bNegtive = (ptFmt->dwReadVal >> 31) ? 1 : 0;
tBinF.lPower = ((ptFmt->dwReadVal >> 20) & 0x7ff);
tBinF.qwMantis.dwH = (ptFmt->dwReadVal << 12) >> 1;
}
else
{
tBinF.qwMantis.dwH = (ptFmt->dwReadVal) >> 21;
tBinF.qwMantis.dwL = (ptFmt->dwReadVal) << 11;
}

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);
if (ptFmt->bBigEndian)
{
tBinF.qwMantis.dwH |= (ptFmt->dwReadVal) >> 21;
tBinF.qwMantis.dwL = (ptFmt->dwReadVal) << 11;
}
else
{
tBinF.bNegtive = (ptFmt->dwReadVal >> 31) ? 1 : 0;
tBinF.lPower = ((ptFmt->dwReadVal >> 20) & 0x7ff);
tBinF.qwMantis.dwH |= (ptFmt->dwReadVal << 12) >> 1;
}

ptFmt->wTakeBytes = 8;

tBinF.qwMantis.dwH |= (tBinF.lPower == 0) ? 0 : 0x80000000;
tBinF.lPower = tBinF.lPower - DoubleZeroPowerRef_M + 1;
}

/*----------------------------------------------------------------------*/
/* 将二进制表示的浮点数转化为十进制表示的浮点数,并计算有效数据长度 */
/*----------------------------------------------------------------------*/
tDecF = FloatBinToDec(tBinF);
for (qwTemp = tDecF.qwMantis; !zeroQword(qwTemp); lValLen++)
{
qwTemp = QwordDividNum(qwTemp, 10);
}

qwTemp = tDecF.qwMantis, dwTempVal = 0;

/*----------------------------------------------------------------------*/
/* 判断是直接以小数点形式显示数据还是按科学计数法显示数据 */
/*----------------------------------------------------------------------*/
if (tDecF.lPower > 16 || /* 整数阶太高, 16位 */
tDecF.lPower < -35 || /* 小数前缀零太多, 约35-19=16个 */
ptFmt->bType == 'e' ||  /* 指明科学计数法显示 */
ptFmt->bType == 'E' ||  /* 选择进科学计数法显示 */
((ptFmt->bType == 'g' || ptFmt->bType == 'G') && lValLen > 10))
{
lValLen = (lValLen > 0) ? (lValLen - 1) : lValLen;
/*------------------------------------------------------------------*/
/* 数据位只有一位是整数,其它都是小数,所以 lValLen-1 就是小数长度 */
/*------------------------------------------------------------------*/
for (/**/; (pbOutEnd - pbOutBeg) < ptFmt->lPrecision - lValLen; /**/)
{
*(--pbOutBeg) = '0';
}
/*------------------------------------------------------------------*/
/* 数据长度不够时补'0',超过时就剔除有效数据 */
/*------------------------------------------------------------------*/
for (/**/; dwTempVal + ptFmt->lPrecision < (DWORD)lValLen; dwTempVal++)
{
qwTemp = QwordDividNum(qwTemp, 10);
}

for (/**/; dwTempVal < (DWORD)lValLen; dwTempVal++)
{
*(--pbOutBeg) = '0' + QwordModNum(qwTemp, 10);
qwTemp = QwordDividNum(qwTemp, 10);
}

*(--pbOutBeg) = '.';
*(--pbOutBeg) = '0' + QwordModNum(qwTemp, 10);

lValLen = tDecF.lPower + lValLen;
(*pbOutEnd++) = (ptFmt->bType == 'E' || ptFmt->bType == 'G') ? 'E' : 'e';
(*pbOutEnd++) = lValLen < 0 ? '-' : '+';
lValLen = (lValLen < 0) ? -lValLen : lValLen;
(*pbOutEnd++) = '0' + (lValLen / 100) % 10;
(*pbOutEnd++) = '0' + (lValLen / 10) % 10;
(*pbOutEnd++) = '0' + lValLen % 10;
}
else
{ /*------------------------------------------------------------------*/
/* 阶码的值小于0,那么它的绝对值就是小数长度(精度数) */
/*------------------------------------------------------------------*/
if (tDecF.lPower <= 0)
{
lValLen = -tDecF.lPower;
while ((pbOutEnd - pbOutBeg) < ptFmt->lPrecision + tDecF.lPower)
{
*(--pbOutBeg) = '0';
}
for (/* none */; lValLen - ptFmt->lPrecision > 0; lValLen--)
{
qwTemp = QwordDividNum(qwTemp, 10);
}

for (/* none */; lValLen > 0; lValLen--)
{
*(--pbOutBeg) = '0' + QwordModNum(qwTemp, 10);
qwTemp = QwordDividNum(qwTemp, 10);
}

*(--pbOutBeg) = '.';
}
/*------------------------------------------------------------------*/
/* 纯整数,直接用'0'补齐小数长度,并补齐整数部分 */
/*------------------------------------------------------------------*/
else
{
for (/* */; (pbOutEnd - pbOutBeg) < ptFmt->lPrecision; /* */)
{
*(--pbOutBeg) = '0';
}

*(--pbOutBeg) = '.';

for (lValLen = 0; lValLen < tDecF.lPower; lValLen++)
{
*(--pbOutBeg) = '0';
}
}

if (zeroQword(qwTemp))
{
*(--pbOutBeg) = '0';
}
else while (!zeroQword(qwTemp))
{
*(--pbOutBeg) = '0' + QwordModNum(qwTemp, 10);
qwTemp = QwordDividNum(qwTemp, 10);
}
}

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
if (ptFmt->bAlter || !ptFmt->bRight)
{
bPreKeepLen = (tDecF.bNegtive || ptFmt->bPlus) ? 1 : 0;
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (tDecF.bNegtive)
{
*(--pbOutBeg) = '-';
}
else if (ptFmt->bPlus)
{
*(--pbOutBeg) = '+';
}
}
else
{
if (tDecF.bNegtive)
{
*(--pbOutBeg) = '-';
}
else if (ptFmt->bPlus)
{
*(--pbOutBeg) = '+';
}

OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, 0);
}

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutImsi() */
/* Description   : 输出IMSI */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-22 12:33上午 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutImsi(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE bPreKeepLen, *pbData = *ppbDataAddr;
DWORD dwTempVal;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据,并检验取数据默认值 */
/*----------------------------------------------------------------------*/
if (!ptFmt->bTakeDataDecl)
{
ptFmt->wTakeBytes = 8;
}

for (dwTempVal = 0; dwTempVal < 16; dwTempVal++)
{
if (dwTempVal % 2 == 0)
{
if ((pbData[0] & 0xf) > 9 && !ptFmt->bAlter)
{
break;
}
else if ((pbData[0] & 0xf) > 9)
{
pbOutEnd[0] = (pbData[0] & 0xf) - 10 + 'a';
}
else
{
pbOutEnd[0] = (pbData[0] & 0xf) + '0';
}
}
else
{
if ((pbData[0] >> 4) > 9 && !ptFmt->bAlter)
{
break;
}
else if ((pbData[0] >> 4) > 9)
{
pbOutEnd[0] = (pbData[0] >> 4) - 10 + 'a';
}
else
{
pbOutEnd[0] = (pbData[0] >> 4) + '0';
}

pbData++;

if (pbData > *ppbDataAddr + ptFmt->wTakeBytes)
{
pbOutEnd++;
break;
}
}

pbOutEnd++;
}

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
bPreKeepLen = ptFmt->bAlter ? 6 : 0;
ptFmt->lPrecision = 0, ptFmt->bPreChar = ' ';
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (ptFmt->bAlter)
{
*(--pbOutBeg) = ' ';
*(--pbOutBeg) = ':';
*(--pbOutBeg) = 'I';
*(--pbOutBeg) = 'S';
*(--pbOutBeg) = 'M';
*(--pbOutBeg) = 'I';
}

pbOutEnd[0] = '\0';

*ppbDataAddr += ptFmt->wTakeBytes;

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutIp() */
/* Description   : 输出IP地址 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-22 12:33上午 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutIp(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbOutBeg = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[TEMP_BUF_SIZE_M - 1];
BYTE bIpVal, bPreKeepLen, *pbTemp;
DWORD dwTempVal;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据,并检验取数据默认值 */
/*----------------------------------------------------------------------*/
if (!ptFmt->bTakeDataDecl)
{
ptFmt->wTakeBytes = 4;
}

TakeDataByFormat(ptFmt, ppbDataAddr, wDataLen);

for (dwTempVal = 0; dwTempVal < 4; dwTempVal++)
{
bIpVal = (BYTE)((ptFmt->dwReadVal >> (dwTempVal * 8)) & 0xff);

pbTemp = pbOutBeg;

if (bIpVal == 0)
{
*(--pbOutBeg) = '0';
}
else while (bIpVal > 0)
{
*(--pbOutBeg) = bIpVal % 10 + '0', bIpVal /= 10;
}

while (ptFmt->lPrecision > 0 && pbTemp - pbOutBeg < 10 &&
pbTemp - pbOutBeg < ptFmt->lPrecision)
{
*(--pbOutBeg) = ptFmt->bPreChar;
}

*(--pbOutBeg) = '.';
}

pbOutBeg++;

/*----------------------------------------------------------------------*/
/* 输出字符宽度检验 */
/*----------------------------------------------------------------------*/
bPreKeepLen = ptFmt->bAlter ? 4 : 0;
ptFmt->lPrecision = 0, ptFmt->bPreChar = ' ';
OutPutWidthCheck(&pbOutBeg, &pbOutEnd, ptFmt, bPreKeepLen);

if (ptFmt->bAlter)
{
*(--pbOutBeg) = ' ';
*(--pbOutBeg) = ':';
*(--pbOutBeg) = 'P';
*(--pbOutBeg) = 'I';
}

pbOutEnd[0] = '\0';

dwTempVal = PutString(pbOutLoc, wBufLen, pbOutBeg);

return dwTempVal;
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutZteTypeData() */
/* Description   : 打印中兴公司自定义格式 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 10:04下午 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutZteTypeData(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
switch (ptFmt->bSubType)
{
case 'M':
return OutPutImsi(pbOutLoc, wBufLen, ptFmt, ppbDataAddr, wDataLen);
case 'I':
return OutPutIp(pbOutLoc, wBufLen, ptFmt, ppbDataAddr, wDataLen);
default:
return 0;
}
}

/*--------------------------------------------------------------------------*/

/* Function name : OutPutSkip() */
/* Description   : 跳过参数列表处理 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 打印格式控制结构 */
/*  : ppbDataAddr - 可供取数的内存地址指针 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 10:11下午 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

static ULONG OutPutSkip(BYTE *pbOutLoc,
WORD wBufLen, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbReadData = *ppbDataAddr;

pbReadData += ptFmt->wTakeBytes;

if (ptFmt->bBitTake)
{
if (ptFmt->bRemainBits > ptFmt->wTakeBits)
{
ptFmt->bRemainBits -= ptFmt->wTakeBits;
if (ptFmt->bBigEndian && ptFmt->bRemainBits < 32)
{
ptFmt->dwRemainVal &= (1 << ptFmt->bRemainBits) - 1;
}
else if (!ptFmt->bBigEndian)
{
ptFmt->dwRemainVal >>= ptFmt->wTakeBits;
}
}
else
{
ptFmt->bRemainBits = 0;
ptFmt->dwRemainVal = 0;
}
}

*ppbDataAddr = pbReadData;

return 0;
}

/*--------------------------------------------------------------------------*/

/* Function name : tprintf1() */
/* Description   : 格式化控制打印函数总入口 */
/* Input         : pbBuf - 输出字符串地址指针 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 格式化控制字符串 */
/*  : pbAddr - 数据内存起始地址 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数统计,字串尾字符'\0'不参加计数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-19 20:11 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

ULONG tprintf1(BYTE *pbBuf, WORD wBufLen, char *pbFmt, BYTE *pbDataAddr, WORD 
wDataLen)
{
char *pbReadFmt = pbFmt;
BYTE bAmongPercentFmt = 0;
BYTE *pbReadData = pbDataAddr;
BYTE *pbOutLoc = pbBuf;

DWORD dwPrnCount = 0;

PrnFormatGlb_T tFmtStatus;

if (pbOutLoc == NULL)
{
return dwPrnCount;
}

tFmtStatus.bRemainBits = 0;
tFmtStatus.dwRemainVal = 0;

while (pbReadFmt[0] != '\0' && pbOutLoc - pbBuf < wBufLen)
    {
if (pbReadFmt[0] != '%' && !bAmongPercentFmt)
{
pbOutLoc += PutChar(pbOutLoc, pbReadFmt[0]);
pbReadFmt++; continue;
}
else if (pbReadFmt[0] == '%' && !bAmongPercentFmt)
{
bAmongPercentFmt = 1;
pbReadFmt++; continue;
}

        pbReadFmt = ParsePercentFormat(pbReadFmt, &tFmtStatus, &pbReadData);
if (pbReadData > pbDataAddr + wDataLen)
{
break;
}

        /*------------------------------------------------------------------*/

        /* 支持的百分符"%"打印控制格式:                                     */

        /*------------------------------------------------------------------*/

        /*  a     -   取数控制符(不在打印输出中处理)                        */

        /*  b     -   二进制数                                              */

        /*  c     -   一个字符                                              */

        /*  d     -   带符号的十进制数                                      */

/*  e,E   -   科学计数法形式的浮点数输出,指数符'e'小写或大写       */
/*  f     -   浮点数输出,默认小数点后6位精度                       */
/*  g,G   -   选择进行的浮点数输出,采用"e,E"格式时指数符相应改变   */
/*  h     -   整数长度限定,两字节长度(附加控制)                    */
        /*  k     -   跳过数个字节或者比特位数据                            */

        /*  l     -   整数长度限定,四字节长度(附加控制, 作为默认值)        */

        /*  o     -   八进制数                                              */

        /*  u     -   无符号的十进制数                                      */

        /*  p     -   指针                                                  */

        /*  s     -   字符串                                                */

        /*  x,X   -   十六进制数,'a-f'根据'x,X'决定是采用小写还是大写      */

        /*  zI    -   中兴自定义IP地址                                      */

        /*  zM    -   中兴自定义IMSI                                        */

        /*------------------------------------------------------------------*/

switch (tFmtStatus.bType)
{
case 'd':
case 'u':
pbOutLoc += OutPutDecimal(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'p':
case 'x':
case 'X':
pbOutLoc += OutPutHex(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'o':
pbOutLoc += OutPutOctet(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'b':
pbOutLoc += OutPutBinary(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'c':
pbOutLoc += OutPutChar(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 's':
pbOutLoc += OutPutString(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'k':
pbOutLoc += OutPutSkip(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
pbOutLoc += OutPutFloat(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
case 'z':
pbOutLoc += OutPutZteTypeData(
pbOutLoc, wBufLen, &tFmtStatus, &pbReadData, wDataLen);
break;
default:
pbOutLoc += PutChar(pbOutLoc, pbReadFmt[0]), pbReadFmt++;
break;
}

bAmongPercentFmt = 0;
}

return (dwPrnCount = pbOutLoc - pbBuf);
}

/*--------------------------------------------------------------------------*/

/* Function name : tprintf2() */
/* Description   : 含输出长度控制的格式化控制打印函数入口 */
/* Input         : pbBuf - 输出字符串地址指针 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbFmt - 格式化控制字符串 */
/*  : pbAddr - 数据内存起始地址 */
/* Output  : none   */
/* Return        : 打印的字符个数统计,字串尾字符'\0'不参加计数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-24 09:30 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

ULONG tprintf2(BYTE *pbBuf, WORD wBufLen, char *pbFmt, BYTE *pbDataAddr)
{
return tprintf1(pbBuf, wBufLen, pbFmt, pbDataAddr, 0x7fff);
}

/*--------------------------------------------------------------------------*/

/* Function name : tprintf3() */
/* Description   : 含数据长度控制的格式化控制打印函数入口 */
/* Input         : pbBuf - 输出字符串地址指针 */
/*  : pbFmt - 格式化控制字符串 */
/*  : pbAddr - 数据内存起始地址 */
/*  : wDataLen - 数据长度 */
/* Output  : none   */
/* Return        : 打印的字符个数统计,字串尾字符'\0'不参加计数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-24 09:31 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

ULONG tprintf3(BYTE *pbBuf, char *pbFmt, BYTE *pbDataAddr, WORD wDataLen)
{
return tprintf1(pbBuf, 0x7fff, pbFmt, pbDataAddr, wDataLen);
}

/*--------------------------------------------------------------------------*/

/* Function name : tprintf() */
/* Description   : 格式化控制打印函数入口 */
/* Input         : pbBuf - 输出字符串地址指针 */
/*  : pbFmt - 格式化控制字符串 */
/*  : pbAddr - 数据内存起始地址 */
/* Output  : none   */
/* Return        : 打印的字符个数统计,字串尾字符'\0'不参加计数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-23 13:31 */
/* Note          :                                                          */

/*--------------------------------------------------------------------------*/

ULONG tprintf(BYTE *pbBuf, char *pbFmt, void *pbDataAddr)
{
return tprintf1(pbBuf, 0x7fff, pbFmt, (BYTE *)pbDataAddr, 0x7fff);
}

/*----------------------------------文件结束--------------------------------*/


────────────────────────────────────────
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:1,215.018毫秒