Programming 版 (精华区)

发信人: jiaxuan (笑十子), 信区: Programming
标  题: Re: 一个自由打印函数,欢迎测试!--最新的代码
发信站: 哈工大紫丁香 (Tue May 27 01:47:32 2003) , 转信

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

/* Module Name: COMMON                        File Name: zprintf.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 PrnTakeDataBytesDft_M 4 /* 默认取数据的字节长度 */
#define PrnTakeFloatBytesDft_M 8 /* 默认取浮点数的字节数 */
#define PrnTakePtrBytesDft_M 4 /* 默认取指针数据字节数 */
#define PrnTakeCharBytesDft_M 4 /* 默认取字符数据字节数 */
#define PrnTakeImsiBytesDft_M 8 /* 默认取IMSI的字节数 */
#define PrnTakeIpBytesDft_M 4 /* 默认取IP地址的字节数 */

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

/* 数据串长度限制定义 */
/*--------------------------------------------------------------------------*/

#define MaxPrnBufDftLen_M 1600 /* 最大的打印缓存长度 */
#define MaxPrnDataArrayLen_M 1024 /* 默认数据参数列表长度 */
#define MaxBinDigitLen_M 70 /* 最大的二进制数串长度 */
#define MaxOctDigitLen_M 30 /* 最大的八进制数串长度 */
#define MaxDecDigitLen_M 22 /* 最大的十进制数串长度 */
#define MaxHexDigitLen_M 16 /* 最大的十六进制数串长度 */
#define MaxFltDigitLen_M 30 /* 最大的浮点数串长度 */
#define MaxCharDigitLen_M 4 /* 最大的字符值数串长度 */
#define MaxImsiDigitLen_M 20 /* 最大IMSI数值串长度 */
#define MaxIpDigitLen_M 40 /* 最大IP数值串长度 */
#define FltE_FmtPowerLen_M 3 /* 浮点数科学计数法指数长度*/

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

/* 浮点数移码定义,可根据需要进行宏定义或切换 */
/*--------------------------------------------------------------------------*/

#define MostSigBitHiden_M 1 /* 隐含最高有效位 */
#define FloatZeroShift_M 0x7f /* 浮点数指数0移码数 */
#define FloatPowerBits_M 8 /* 浮点数指数有效比特数 */
#define FloatMantisBits_M 23 /* 浮点数尾数有效比特数 */
#define DoublePowerBits_M 11 /* 双精度数指数有效比特数 */
#define DoubleZeroShift_M 0x3ff /* 双精度数指数0移码数 */
#define DoubleMantisBits_M 52 /* 浮点数尾数有效比特数 */

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

/* 数据宽度定义 */
/*--------------------------------------------------------------------------*/

#define PrnWidthDft_M -1 /* 默认输出数据宽度,不限 */
#define PrnPreciDft_M 6 /* 默认输出数据(小数)精度 */

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

/* 普通数据类型定义 */
/*--------------------------------------------------------------------------*/

#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

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

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

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; /* 正负数标识 */
BYTE bMantisBits; /* 尾数有效长度 */
LONG lPower; /* 数值阶 */
QWORD qwMantis; /* 尾数 */
} PFLOAT;

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

/* 宏函数 */
/*--------------------------------------------------------------------------*/

#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') || \
 ((a) == 'n') || ((a) == 'i'))

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

/* 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 = isBigEndian() ? 1 : 0;
ptFmt->wTakeBytes = PrnTakeCharBytesDft_M;
ptFmt->bTakeDataDecl= 1;

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] == '-' || pbRead[0] == '+')
{
if (bTakeStep == 0)
{
bTakeStep = 1;
ptFmt->bBigEndian = (pbRead[0] == '-') ? 0 : 1;
}
else if (bTakeStep == 3)
{
bTakeStep = 4;
ptFmt->bBitBigEndian = (pbRead[0] == '-') ? 0 : 1;
}
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)(*(char *)(*ppbData)), *ppbData++, 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);
}

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->bRemainBits = 0;
ptFmt->dwRemainVal = 0;
ptFmt->wTakeBytes = (ptFmt->wTakeBits + 7) / 8;
}
else if (!bTakeBytesDecl)
{
ptFmt->wTakeBytes = 0;
}
}

return pbRead;
}

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

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

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

static BYTE *TakeDataByFormat(PrnFormatGlb_T *ptFmt, BYTE *pbDataAddr, WORD wD
ataLen)
{
int i;
WORD wTakeBytes = ptFmt->wTakeBytes;
WORD wTakeBits = ptFmt->wTakeBits, wReadBits;
BYTE *pbData = pbDataAddr, 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;

return pbData;
}

/*----------------------------------------------------------------------*/
/* 检验要取的比特数的有效性 */
/*----------------------------------------------------------------------*/
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;

return pbData;
}

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

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

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

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

ptFmt->dwReadVal = dwReadVal;

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

return pbData;
}

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

/* Function name : TakeFloatDataByFormat() */
/* Description   : 按照格式控制符从内存地址中取数据 */
/* Input         : ptFmt - 控制格式结构地址 */
/*  : pbDataAddr - 取数开始位置 */
/*  : wDataLen - 有限的数据长度 */
/* Output  : ptBinf - 二进制浮点数据 */
/* Return        : 下一个取数地址指针      */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-25 13:03 */
/* Note          : 二进制尾数, 最高位是有效的                               */

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

BYTE *TakeFloatDataByFormat(
PrnFormatGlb_T *ptFmt, BYTE *pbDataAddr, WORD wDataLen, PFLOAT *ptBinF)
{
BYTE *pbData = pbDataAddr;

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

ptFmt->bBitTake = 0;
ptFmt->wTakeBytes = 4;
pbData = TakeDataByFormat(ptFmt, pbData, wDataLen);

ptBinF->bNegtive = (ptFmt->dwReadVal >> 31) ? 1 : 0;
ptBinF->lPower = (LONG)
((ptFmt->dwReadVal >> FloatMantisBits_M) & ((1 << FloatPowerBits_M) - 1));

ptBinF->qwMantis.dwH = 0;
ptBinF->qwMantis.dwL = (DWORD)
(ptFmt->dwReadVal & ((1 << FloatMantisBits_M) - 1));

if (MostSigBitHiden_M && ptBinF->lPower != 0)
{
ptBinF->qwMantis.dwL |= 1 << FloatMantisBits_M;
}
ptBinF->lPower -= FloatMantisBits_M + FloatZeroShift_M;
}
else
{
ptBinF->bMantisBits = DoubleMantisBits_M;

ptFmt->bBitTake = 0;
ptFmt->wTakeBytes = 4;

pbData = TakeDataByFormat(ptFmt, pbData, wDataLen);
if (ptFmt->bBigEndian)
{
ptBinF->bNegtive = (ptFmt->dwReadVal >> 31) ? 1 : 0;
ptBinF->lPower = (LONG)
((ptFmt->dwReadVal >> (DoubleMantisBits_M - 32)) &
((1 << DoublePowerBits_M) - 1));

ptBinF->qwMantis.dwH= (DWORD)
(ptFmt->dwReadVal & ((1 << (DoubleMantisBits_M - 32)) - 1));
}
else
{
ptBinF->qwMantis.dwL = ptFmt->dwReadVal;
}

pbData = TakeDataByFormat(ptFmt, pbData, wDataLen);
if (ptFmt->bBigEndian)
{
ptBinF->qwMantis.dwL = ptFmt->dwReadVal;
}
else
{
ptBinF->bNegtive = (ptFmt->dwReadVal >> 31) ? 1 : 0;
ptBinF->lPower = (LONG)
((ptFmt->dwReadVal >> (DoubleMantisBits_M - 32)) &
((1 << DoublePowerBits_M) - 1));

ptBinF->qwMantis.dwH= (DWORD)
(ptFmt->dwReadVal & ((1 << (DoubleMantisBits_M - 32)) - 1));
}

ptFmt->wTakeBytes = 8;

if (MostSigBitHiden_M && ptBinF->lPower != 0)
{
ptBinF->qwMantis.dwH |= 1 << (DoubleMantisBits_M - 32);
}
ptBinF->lPower -= DoubleMantisBits_M + DoubleZeroShift_M;
}

return pbData;
}

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

/* 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 if (bParseStep != 5)
{
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] == '*' && ptFmt->bBigEndian)
{
lFmtVal = (LONG)(*(char *)(*ppbData)++);
lFmtVal = (lFmtVal << 8) + (LONG)(*(char *)(*ppbData)++);
lFmtVal = (lFmtVal << 8) + (LONG)(*(char *)(*ppbData)++);
lFmtVal = (lFmtVal << 8) + (LONG)(*(char *)(*ppbData)++);
pbRead++;
}
else if (pbRead[0] == '*'/* && ptFmt->bBigEndian */)
{
lFmtVal = (LONG)(*(char *)(*ppbData)++);
lFmtVal += (LONG)((*(char *)(*ppbData)++) << 8);
lFmtVal += (LONG)((*(char *)(*ppbData)++) << 16);
lFmtVal += (LONG)((*(char *)(*ppbData)++) << 24);
pbRead++;
}
else for (lFmtVal = 0; isDigit(pbRead[0]); pbRead++)
{
lFmtVal = lFmtVal * 10 + (pbRead[0] - '0');
}

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

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 - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : bChar - 待输出字符(可以是宽字符格式) */
/*  : wNum - 重复输出字符个数 */
/* Output  : none   */
/* Return        : 打印的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 16:16 */
/* Note          :                                                          */

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

static ULONG PutChar(BYTE *pbOutLoc, WORD wBufLen, BYTE bChar, WORD wNum)
{
BYTE *pbPut = pbOutLoc;
ULONG dwPrnCount = 0;

while (dwPrnCount < wNum && dwPrnCount < wBufLen)
{
*pbPut++ = bChar, dwPrnCount++;
}

pbPut[0] = '\0';

dwPrnCount = pbPut - pbOutLoc;

return dwPrnCount;
}

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

/* Function name : PutString() */
/* Description   : 向特定内存输出一个字符串 */
/* Input         : pbOutLoc - 打印字符输出地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : pbString - 待输出字符串 */
/*  : wStrLen - 字符串长度 */
/* 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, WORD wStr
Len)
{
BYTE *pbPut = pbOutLoc, *pbRead = pbString;
ULONG dwPrnCount = 0;

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

pbPut[0] = '\0';

return dwPrnCount;
}

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

/* Function name : OutPutWidthCheck() */
/* Description   : 进行宽度校验并输出本体字符串 */
/* Input         : pbOutLoc - 输出字符起始地址 */
/*  : wBufLen - 打印缓存长度 */
/*  : ppbS - 本体字符输出起始地址 */
/*  : ppbE - 本体字符输出终止地址 */
/*  : pbFmt - 打印格式控制结构 */
/*  : pbPromtStr - 提示符地址 */
/*  : wPromtLen - 提示符长度 */
/* Output  : ppbBegin - 输出起始地址 */
/*  : ppbEnd - 输出终止地址 */
/* Return        : 未补足的字符个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-21 9:24 */
/* Note          : 左对齐,左边数字或字符有效,右对齐,右边数字或字符有效   */

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

ULONG OutPutWidthCheck(BYTE *pbOutLoc, WORD wBufLen, BYTE *pbOutBeg,
BYTE *pbOutEnd, PrnFormatGlb_T *ptFmt, BYTE *pbPromtStr, WORD wPromtLen)
{
ULONG dwPrnCount = 0; /* 打印字符个数 */
WORD wWidthPad = 0; /* 数据宽度补充长度 */
WORD wPrecPad = 0; /* 数据精度补充长度 */

if (!ptFmt->bPlus)
{
pbPromtStr[0] = '\0', wPromtLen = 0;
}

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

/*----------------------------------------------------------------------*/
/* 无输出宽度,直接返回 */
/*----------------------------------------------------------------------*/
if (ptFmt->lWidth == 0)
{
return dwPrnCount;
}
/*----------------------------------------------------------------------*/
/* 无输出宽度限制,将提示字符及本体字符串直接输出 */
/*----------------------------------------------------------------------*/
else if (ptFmt->lWidth < 0)
{
goto PrnWidthCheckOutPut_ToDo;
}

/*----------------------------------------------------------------------*/
/* 要输出提示字符串但限定宽度却比提示字符串宽度短,打印部分提示符 */
/*----------------------------------------------------------------------*/
if (ptFmt->lWidth < wPromtLen)
{
dwPrnCount = PutString(
pbOutLoc, (WORD)min(wPromtLen, wBufLen), pbPromtStr, wPromtLen);
return dwPrnCount;
}

/*----------------------------------------------------------------------*/
/* 实际输出长度比限定长度超长,根据对齐方式在前面或后面选择打上'*'标记 */
/*----------------------------------------------------------------------*/
if (ptFmt->lWidth < wPromtLen + (pbOutEnd - pbOutBeg))
{
if (ptFmt->bAlter)
{
goto PrnWidthCheckOutPut_ToDo;
}

if (ptFmt->bRight)
{
pbOutBeg = pbOutEnd + wPromtLen - ptFmt->lWidth;
pbOutBeg[0] =  '*';
}
else
{
pbOutEnd = pbOutBeg - wPromtLen + ptFmt->lWidth;
*(pbOutEnd - 1) = '*';
}

goto PrnWidthCheckOutPut_ToDo;
}

/*----------------------------------------------------------------------*/
/* 计算数据填充长度 */
/*----------------------------------------------------------------------*/
if ((ptFmt->lPrecision > 0) && (ptFmt->lPrecision > pbOutEnd - pbOutBeg))
{
wPrecPad = (WORD)((pbOutEnd - pbOutBeg) - ptFmt->lPrecision);
}
wWidthPad = (WORD)(ptFmt->lWidth - (wPromtLen + (pbOutEnd - pbOutBeg)));

/*----------------------------------------------------------------------*/
/* 含宽度校准的输出, 含6步, 其中1, 3不并选, 2, 6不并选: */
/* (1, Prompt)(2, WidthPad)(3, Promt)(4, PreciPad)(5, Body)(6, WidthPad)*/
/*----------------------------------------------------------------------*/
PrnWidthCheckOutPut_ToDo:

if (!ptFmt->bRight || ptFmt->bAlter) /* 1*/
{
dwPrnCount = PutString(pbOutLoc, wBufLen, pbPromtStr, wPromtLen);
pbOutLoc += dwPrnCount, wBufLen -= (WORD)dwPrnCount;
}

if (ptFmt->bRight) /* 2*/
{
dwPrnCount = PutChar(pbOutLoc, wBufLen, ptFmt->bPreChar, wWidthPad);
pbOutLoc += dwPrnCount, wBufLen -= (WORD)dwPrnCount;
}

if (ptFmt->bRight && !ptFmt->bAlter) /* 3*/
{
dwPrnCount = PutString(pbOutLoc, wBufLen, pbPromtStr, wPromtLen);
pbOutLoc += dwPrnCount, wBufLen -= (WORD)dwPrnCount;
}

dwPrnCount = PutChar(pbOutLoc, wBufLen, '0', wPrecPad); /* 4*/
pbOutLoc += dwPrnCount, wBufLen -= (WORD)dwPrnCount;

dwPrnCount += PutString( /* 5*/
pbOutLoc, wBufLen, pbOutBeg, (WORD)(pbOutEnd - pbOutBeg));
pbOutLoc += dwPrnCount, wBufLen -= (WORD)dwPrnCount;

if (!ptFmt->bRight) /* 6*/
{
dwPrnCount = PutChar(pbOutLoc, wBufLen, ptFmt->bPreChar, wWidthPad);
}

return dwPrnCount;
}

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

/* 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 sTempOutBuf[MaxDecDigitLen_M], sPromtStr[2] = "+";
BYTE *pbOutBeg = &sTempOutBuf[MaxDecDigitLen_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[MaxDecDigitLen_M - 1];
DWORD dwAbsVal = 0, dwTempVal = 0;

*ppbDataAddr = 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,i' && */ ptFmt->bMod == 'h')
{
if ((SHORT)ptFmt->dwReadVal < 0)
{
dwAbsVal = -((SHORT)ptFmt->dwReadVal);
ptFmt->bPlus = 1, sPromtStr[0] = '-';
}
else
{
dwAbsVal = (SHORT)ptFmt->dwReadVal;
}
}
else /* if (ptFmt->bType == 'd,i' && ptFmt->bMod != 'h') */
{
if ((LONG)ptFmt->dwReadVal < 0)
{
dwAbsVal = -((LONG)ptFmt->dwReadVal);
ptFmt->bPlus = 1, sPromtStr[0] = '-';
}
else
{
dwAbsVal = (LONG)ptFmt->dwReadVal;
}
}

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

/*----------------------------------------------------------------------*/
/* 检验输出字符宽度并进行输出 */
/*----------------------------------------------------------------------*/
dwTempVal = OutPutWidthCheck(
pbOutLoc, wBufLen, pbOutBeg, pbOutEnd, ptFmt, sPromtStr, 1);

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 sTemp[MaxHexDigitLen_M], sPromtStr[4] = "0x ", baHexTbl[16];
BYTE *pbOutBeg = &sTemp[MaxHexDigitLen_M - 1];
BYTE *pbOutEnd = &sTemp[MaxHexDigitLen_M - 1];
DWORD dwAbsVal = 0, dwTempVal = 0;
BYTE bChar = '0';

*ppbDataAddr = TakeDataByFormat(ptFmt, *ppbDataAddr, wDataLen);

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

if (ptFmt->bType == 'x')
{
bChar = 'a';
}
else
{
bChar = 'A', sPromtStr[1] = 'X';
}

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;
}

/*----------------------------------------------------------------------*/
/* 检验输出字符宽度并进行输出 */
/*----------------------------------------------------------------------*/
dwTempVal = OutPutWidthCheck(
pbOutLoc, wBufLen, pbOutBeg, pbOutEnd, ptFmt, sPromtStr, 3);

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 sTempOutBuf[MaxOctDigitLen_M], sPromtStr[3] = "O ";
BYTE *pbOutBeg = &sTempOutBuf[MaxOctDigitLen_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[MaxOctDigitLen_M - 1];
DWORD dwAbsVal = 0, dwTempVal = 0;

*ppbDataAddr = 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;
}

/*----------------------------------------------------------------------*/
/* 检验输出字符宽度并进行输出 */
/*----------------------------------------------------------------------*/
dwTempVal = OutPutWidthCheck(
pbOutLoc, wBufLen, pbOutBeg, pbOutEnd, ptFmt, sPromtStr, 2);

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 sTempOutBuf[MaxBinDigitLen_M], sPromtStr[3] = "b ";
BYTE *pbOutBeg = &sTempOutBuf[MaxBinDigitLen_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[MaxBinDigitLen_M - 1];
DWORD dwAbsVal = 0, dwTempVal = 0;

*ppbDataAddr = 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;
}

/*----------------------------------------------------------------------*/
/* 检验输出字符宽度并进行输出 */
/*----------------------------------------------------------------------*/
dwTempVal = OutPutWidthCheck(
pbOutLoc, wBufLen, pbOutBeg, pbOutEnd, ptFmt, sPromtStr, 2);

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 sTempOutBuf[MaxCharDigitLen_M], sPromtStr[1] = "";
BYTE *pbOutBeg = &sTempOutBuf[MaxCharDigitLen_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[MaxCharDigitLen_M - 1];
DWORD dwTempVal;

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

*ppbDataAddr = TakeDataByFormat(ptFmt, *ppbDataAddr, wDataLen);

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

/*----------------------------------------------------------------------*/
/* 检验输出字符宽度并进行输出 */
/*----------------------------------------------------------------------*/
dwTempVal = OutPutWidthCheck(
pbOutLoc, wBufLen, pbOutBeg, pbOutEnd, ptFmt, sPromtStr, 0);

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, sPromtStr[3] = "";
BYTE *pbOutBeg;
BYTE *pbOutEnd;
DWORD dwTempVal;

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

/*----------------------------------------------------------------------*/
/* 字符串在参数表中 */
/*----------------------------------------------------------------------*/
if (ptFmt->bTakeDataDecl)
{
pbReadData = *ppbDataAddr;
}
/*----------------------------------------------------------------------*/
/* 字符串在参数表指针指向的位置 */
/*----------------------------------------------------------------------*/
else
{
*ppbDataAddr = TakeDataByFormat(ptFmt, *ppbDataAddr, wDataLen);
pbReadData = (BYTE *)ptFmt->dwReadVal;
}

pbOutBeg = pbOutEnd = pbReadData;

while (*pbOutEnd != '\0') pbOutEnd++;

*ppbDataAddr = (ptFmt->bTakeDataDecl) ? (pbOutEnd + 1) : (*ppbDataAddr);

/*----------------------------------------------------------------------*/
/* 检验输出字符宽度并进行输出 */
/*----------------------------------------------------------------------*/
dwTempVal = OutPutWidthCheck(
pbOutLoc, wBufLen, pbOutBeg, pbOutEnd, ptFmt, sPromtStr, 0);

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 : QwordBitsNum() */
/* Description   : QWORD所含的有效比特位个数 */
/* Input         : qwVal - 待计算QWORD */
/* Output  : 无   */
/* Return        : 有效比特位个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-25 14:32 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

static LONG QwordBitsNum(QWORD qwVal)
{
LONG lRet = 0;

if (zeroQword(qwVal))
{
return lRet;
}

if (qwVal.dwH != 0) for (/* */; lRet < 32; lRet++)
{
if ((qwVal.dwH & (0x80000000 >> lRet)) != 0)
{
return 64 - lRet;
}
}

for (lRet = 0; lRet < 32; lRet++)
{
if ((qwVal.dwL & (0x80000000 >> lRet)) != 0)
{
return 32 - lRet;
}
}

return 32 - lRet;
}

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

/* Function name : QwordBitsNum() */
/* Description   : QWORD所含的有效比特位个数 */
/* Input         : qwVal - 待计算QWORD */
/* Output  : 无   */
/* Return        : 有效比特位个数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-25 14:51 */
/* Note          :  */
/*--------------------------------------------------------------------------*/

QWORD QwordNumBitsSet(LONG lBitsNum)
{
QWORD qwRet = {0, 0};

if (lBitsNum == 0)
{
return qwRet;
}

if (lBitsNum < 32)
{
qwRet.dwL = (1 << lBitsNum) - 1;
return qwRet;
}

qwRet.dwL = 0xffffffff;

if (lBitsNum < 64)
{
qwRet.dwH = (1 << (lBitsNum - 32)) - 1;
return qwRet;
}

qwRet.dwH = 0xffffffff;
return qwRet;
}

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

/* 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 : 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, 0}};
QWORD qwTemp = {0, 5};

if (tBinF.lPower == 0 || zeroQword(tBinF.qwMantis))
{
return tDecF;
}

while (tBinF.qwMantis.dwL % 2 == 0)
{
tBinF.qwMantis = QwordDividNum(tBinF.qwMantis, 2);
tBinF.lPower++;
}

tDecF.bNegtive = tBinF.bNegtive;
tDecF.qwMantis = tBinF.qwMantis;

/*----------------------------------------------------------------------*/
/* 使二进制浮点数的阶转化为0 */
/*----------------------------------------------------------------------*/
if (tBinF.lPower < 0) for (/* none */; tBinF.lPower != 0; tBinF.lPower++)
{
tDecF.qwMantis = QwordDividNum(tDecF.qwMantis, 2);
if (tDecF.qwMantis.dwH < 0x19999999)
{
tDecF.lPower--;
tDecF.qwMantis = QwordMultiNum(tDecF.qwMantis, 10);
}
}
else for (/* none */; tBinF.lPower != 0; tBinF.lPower--)
{
if (tDecF.qwMantis.dwH & 0x80000000)
{
tDecF.lPower++;
tDecF.qwMantis = QwordDividNum(tDecF.qwMantis, 10);
}
tDecF.qwMantis = QwordMultiNum(tDecF.qwMantis, 2);
}

tDecF.bMantisBits = (BYTE)(QwordBitsNum(tDecF.qwMantis) * 3 / 10 + 1);

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 bMantisBits = 0; /* 尾数比特数 */
PFLOAT tBinF = {0, 0, 0, {0, 0}}; /* 二进制表示浮点数 */
PFLOAT tDecF = {0, 0, 0, {0, 0}}; /* 十进制表示浮点数 */
BYTE sTempOutBuf[MaxFltDigitLen_M], sPromtStr[2] = "+", bMod = 0;
BYTE *pbOutBeg = &sTempOutBuf[MaxFltDigitLen_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[MaxFltDigitLen_M - 1];

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

*ppbDataAddr = TakeFloatDataByFormat(ptFmt, *ppbDataAddr, wDataLen, &tBinF);

if (tBinF.bNegtive)
{
ptFmt->bPlus = 1, sPromtStr[0] = '-';
}

/*----------------------------------------------------------------------*/
/* 将二进制表示的浮点数转化为十进制表示的浮点数 */
/*----------------------------------------------------------------------*/
tDecF = FloatBinToDec(tBinF);

qwTemp = tDecF.qwMantis, dwTempVal = 0;

/*----------------------------------------------------------------------*/
/* 计算采用非科学计数法输出可能产生的数据串长度 */
/*----------------------------------------------------------------------*/
if (tDecF.lPower >= 0)
{
dwTempVal = tDecF.lPower + tDecF.bMantisBits;
}
else if (tDecF.bMantisBits + tDecF.lPower > 0)
{
dwTempVal = tDecF.bMantisBits + tDecF.lPower;
}
else
{
dwTempVal = 2 - tDecF.bMantisBits - tDecF.lPower; /* 含"0." */
}

if (ptFmt->lPrecision < 0)
{
ptFmt->lPrecision = -ptFmt->lPrecision;
}

/*----------------------------------------------------------------------*/
/* 生成本体串, 判断是直接以小数点形式显示数据还是按科学计数法显示数据 */
/*----------------------------------------------------------------------*/
if (ptFmt->bType == 'e' || ptFmt->bType == 'E' ||
((ptFmt->bType == 'g' || ptFmt->bType == 'G') &&
dwTempVal > (DWORD)(ptFmt->lPrecision + FltE_FmtPowerLen_M + 4)) ||
((!ptFmt->bAlter) &&
(dwTempVal > MaxFltDigitLen_M - 1 ||
ptFmt->lPrecision > MaxFltDigitLen_M - 1)))
{
lValLen = tDecF.lPower + tDecF.bMantisBits - 1;
dwTempVal = (DWORD)(lValLen > 0 ? lValLen : -lValLen);
while (pbOutEnd - pbOutBeg < FltE_FmtPowerLen_M)
{
*(--pbOutBeg) = '0' + (BYTE)(dwTempVal % 10), dwTempVal /= 10;
}
*(--pbOutBeg) = (lValLen < 0) ? '-' : '+';
*(--pbOutBeg) = (ptFmt->bType == 'E' || ptFmt->bType == 'G') ? 'E' : 'e';

if (ptFmt->lPrecision > MaxFltDigitLen_M - (FltE_FmtPowerLen_M + 4))
{
ptFmt->lPrecision = MaxFltDigitLen_M - (FltE_FmtPowerLen_M + 4);
}

lValLen = tDecF.bMantisBits - 1;
/*------------------------------------------------------------------*/
/* 数据位只有一位是整数, 其它都是小数, 所以lValLen就是小数长度 */
/*------------------------------------------------------------------*/
for (/**/;(pbOutEnd - pbOutBeg) < ptFmt->lPrecision - lValLen; /**/)
{
*(--pbOutBeg) = '0';
}
/*------------------------------------------------------------------*/
/* 数据长度不够时补'0',超过时就剔除有效数据 */
/*------------------------------------------------------------------*/
for (/**/; dwTempVal + ptFmt->lPrecision < (DWORD)lValLen; dwTempVal++)
{
bMod = QwordModNum(qwTemp, 10);
qwTemp = QwordDividNum(qwTemp, 10);
}

/*------------------------------------------------------------------*/
/* 四舍五入处理 */
/*------------------------------------------------------------------*/
if (bMod >= 5 && qwTemp.dwL != 0xffffffff)
{
qwTemp.dwL++;
}
else if (bMod >= 5 /* && qwTemp.dwL == 0xffffffff */)
{
qwTemp.dwH++, qwTemp.dwL = 0;
}

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

*(--pbOutBeg) = '.';
*(--pbOutBeg) = '0' + QwordModNum(qwTemp, 10);
}
else
{ /*------------------------------------------------------------------*/
/* 阶码的值小于0,那么它的绝对值就是小数长度(精度数) */
/*------------------------------------------------------------------*/
if (tDecF.lPower <= 0)
{
lValLen = -tDecF.lPower;
while (pbOutEnd - pbOutBeg < ptFmt->lPrecision + tDecF.lPower &&
pbOutEnd - pbOutBeg < MaxFltDigitLen_M - 1)
{
*(--pbOutBeg) = '0';
}
for (/* none */; lValLen > ptFmt->lPrecision; lValLen--)
{
bMod = QwordModNum(qwTemp, 10);
qwTemp = QwordDividNum(qwTemp, 10);
}

/*--------------------------------------------------------------*/
/* 四舍五入处理 */
/*--------------------------------------------------------------*/
if (bMod >= 5 && qwTemp.dwL != 0xffffffff)
{
qwTemp.dwL++;
}
else if (bMod >= 5 /* && qwTemp.dwL == 0xffffffff */)
{
qwTemp.dwH++, qwTemp.dwL = 0;
}

while (lValLen > 0 &&
pbOutEnd - pbOutBeg < MaxFltDigitLen_M - 1)
{
*(--pbOutBeg) = '0' + QwordModNum(qwTemp, 10);
qwTemp = QwordDividNum(qwTemp, 10);
lValLen--;
}

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

if (pbOutEnd - pbOutBeg < MaxFltDigitLen_M - 2)
{
*(--pbOutBeg) = '.';
}

lValLen = 0;
while (lValLen < tDecF.lPower &&
pbOutEnd - pbOutBeg < MaxFltDigitLen_M - 1)
{
*(--pbOutBeg) = '0', lValLen++;
}
}

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

/*----------------------------------------------------------------------*/
/* 精度已经校验, 不再检查 */
/*----------------------------------------------------------------------*/
ptFmt->lPrecision = 0;

/*----------------------------------------------------------------------*/
/* 检验输出字符宽度并进行输出 */
/*----------------------------------------------------------------------*/
dwTempVal = OutPutWidthCheck(
pbOutLoc, wBufLen, pbOutBeg, pbOutEnd, ptFmt, sPromtStr, 1);

return dwTempVal;
}

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

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

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

static ULONG FeedBackPrnBytes(
WORD wPrnCount, PrnFormatGlb_T *ptFmt, BYTE **ppbDataAddr, WORD wDataLen)
{
BYTE *pbData;

ptFmt->wTakeBytes = 4;

*ppbDataAddr = TakeDataByFormat(ptFmt, *ppbDataAddr, wDataLen);

pbData = (BYTE *)ptFmt->dwReadVal;

if (ptFmt->bMod == 'h' && !ptFmt->bTakeDataDecl)
{
*pbData++ = (ptFmt->bBigEndian) ? (wPrnCount >> 8) : (wPrnCount & 0xff);
*pbData++ = (ptFmt->bBigEndian) ? (wPrnCount & 0xff) : (wPrnCount >> 8);
}
else
{
*pbData++ = (ptFmt->bBigEndian) ? 0 : (wPrnCount & 0xff);
*pbData++ = (ptFmt->bBigEndian) ? 0 : (wPrnCount >> 8);
*pbData++ = (ptFmt->bBigEndian) ? (wPrnCount >> 8) : 0;
*pbData++ = (ptFmt->bBigEndian) ? (wPrnCount & 0xff) : 0;
}

*ppbDataAddr += ptFmt->wTakeBytes;

return 0;
}

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

/* 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 sTempOutBuf[MaxImsiDigitLen_M], sPromtStr[6] = "IMSI ";
BYTE *pbOutBeg = &sTempOutBuf[0];
BYTE *pbOutEnd = &sTempOutBuf[0];
DWORD dwTempVal = 0;
BYTE bEle, *pbData = *ppbDataAddr, *pbImsiBeg;

/*----------------------------------------------------------------------*/
/* 按照格式符调整取得的数据,并检验取数据默认值 */
/*----------------------------------------------------------------------*/
if (!ptFmt->bTakeDataDecl)
{
ptFmt->wTakeBytes = PrnTakePtrBytesDft_M;
*ppbDataAddr = TakeDataByFormat(ptFmt, *ppbDataAddr, wDataLen);
pbData = pbImsiBeg = (BYTE *)ptFmt->dwReadVal;
ptFmt->wTakeBytes = PrnTakeImsiBytesDft_M;
}
else
{
pbData = pbImsiBeg = *ppbDataAddr;
}

/*----------------------------------------------------------------------*/
/* 求得目标字符本体 */
/*----------------------------------------------------------------------*/
for (/**/; dwTempVal < 16 && dwTempVal < MaxImsiDigitLen_M; dwTempVal++)
{
bEle = (dwTempVal % 2 == 0) ? (pbData[0] & 0xf) : (pbData[0] >> 4);
if (bEle > 9 && !ptFmt->bAlter)
{
break;
}

*pbOutEnd++ = bEle + ((bEle > 9) ? ('a' - 10) : '0');

if (dwTempVal % 2 != 0 &&
++pbData > pbImsiBeg + ptFmt->wTakeBytes)
{
break;
}
}

ptFmt->lPrecision = 0;
*ppbDataAddr += (!ptFmt->bTakeDataDecl) ? 0 : ptFmt->wTakeBytes;

/*----------------------------------------------------------------------*/
/* 检验输出字符宽度并进行输出 */
/*----------------------------------------------------------------------*/
dwTempVal = OutPutWidthCheck(
pbOutLoc, wBufLen, pbOutBeg, pbOutEnd, ptFmt, sPromtStr, 5);

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 sTempOutBuf[MaxIpDigitLen_M], sPromtStr[5] = "IP: ";
BYTE *pbOutBeg = &sTempOutBuf[MaxIpDigitLen_M - 1];
BYTE *pbOutEnd = &sTempOutBuf[MaxIpDigitLen_M - 1];
BYTE bIpVal, *pbTemp;
DWORD dwTempVal = 0;

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

*ppbDataAddr = 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 < MaxIpDigitLen_M / 4 - 1 &&
pbTemp - pbOutBeg < ptFmt->lPrecision)
{
*(--pbOutBeg) = '0';
}

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

pbOutBeg++, ptFmt->lPrecision = 0;

/*----------------------------------------------------------------------*/
/* 检验输出字符宽度并进行输出 */
/*----------------------------------------------------------------------*/
dwTempVal = OutPutWidthCheck(
pbOutLoc, wBufLen, pbOutBeg, pbOutEnd, ptFmt, sPromtStr, 4);

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:
PutChar(pbOutLoc, wBufLen, '\0', 1);
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 : zprintf0() */
/* 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 zprintf0(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;
WORD wBufRemainLen = wBufLen;

PrnFormatGlb_T tFmtStatus;

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

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

while (pbReadFmt[0] != '\0' && wBufRemainLen > 0)
    {
if (pbReadFmt[0] != '%' && !bAmongPercentFmt)
{
dwPrnCount = PutChar(pbOutLoc, wBufRemainLen, pbReadFmt[0], 1);
if (wBufRemainLen >= (WORD)dwPrnCount)
{
wBufRemainLen -= (WORD)dwPrnCount, pbOutLoc += dwPrnCount;
}
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     -   整数长度限定,两字节长度(附加控制)                    */
        /*  i     -   带符号的十进制数                                      */

        /*  k     -   从参数列中跳过数个字节或者比特位数据                  */

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

/* n     -   向给定的内存地址填充当前打印了的字符计数              */
        /*  o     -   八进制数                                              */

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

        /*  p     -   指针                                                  */

        /*  s     -   字符串                                                */

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

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

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

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

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

if (wBufRemainLen >= (WORD)dwPrnCount)
{
wBufRemainLen -= (WORD)dwPrnCount, pbOutLoc += dwPrnCount;
}
bAmongPercentFmt = 0;
}

return (dwPrnCount = pbOutLoc - pbBuf);
}

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

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

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

ULONG zprintf1(BYTE *pbBuf, WORD wBufLen, char *pbFmt, BYTE *pbDataAddr)
{
return zprintf0(pbBuf, wBufLen, pbFmt, pbDataAddr, MaxPrnDataArrayLen_M);
}

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

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

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

ULONG zprintf2(BYTE *pbBuf, char *pbFmt, BYTE *pbDataAddr, WORD wDataLen)
{
return zprintf0(pbBuf, MaxPrnBufDftLen_M, pbFmt, pbDataAddr, wDataLen);
}

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

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

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

ULONG zprintf(BYTE *pbBuf, char *pbFmt, void *pbDataAddr)
{
return zprintf0(pbBuf,
MaxPrnBufDftLen_M, pbFmt, (BYTE *)pbDataAddr, MaxPrnDataArrayLen_M);
}

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

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

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

ULONG vzprintf1(BYTE *pbBuf, WORD wBufLen, char *pbFmt, ...)
{
char *ptArg = (char *)&pbFmt + sizeof(pbFmt);

return zprintf0(pbBuf, wBufLen, pbFmt, (BYTE *)ptArg, MaxPrnDataArrayLen_M);
}

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

/* Function name : vzprintf() */
/* Description   : 变参数格式化控制打印函数入口 */
/* Input         : pbBuf - 输出字符串地址指针 */
/*  : pbFmt - 格式化控制字符串 */
/* Output  : none   */
/* Return        : 打印的字符个数统计,字串尾字符'\0'不参加计数 */
/* Global Var    : 无 */
/* Author/Date   : R.Z.Tian/2003-5-25 16:10 */
/* Note          :                                                          */

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

ULONG vzprintf(BYTE *pbBuf, char *pbFmt, ...)
{
char *ptArg = (char *)&pbFmt + sizeof(pbFmt);

return zprintf0(pbBuf,
MaxPrnBufDftLen_M, pbFmt, (BYTE *)ptArg, MaxPrnDataArrayLen_M);
}

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





--

※ 来源:.哈工大紫丁香 http://bbs.hit.edu.cn [FROM: 210.52.238.66]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:621.248毫秒