支持windows linux下将指定内存段转为16进制与ascii码的日志输出类
来源:http://blog.csdn.net/lezhiyong
1. 简单介绍
将指定内存段转为16进制与asci码的输出到日志文件的类。
2. 功能介绍
1) 支持window与linus双系统。
2) 可指定输出文件夹。
3) 日志能输出的时间精确到毫秒,日志能输出线程号。
4) 提供字符串输出。
5) 提供指定内存转换为16进制输出。
6) 提供指定内存转换为16进制和ascii码同一时候输出。
7) 可调整16进制输出间距。
3. 原理和算法
1) 模块是基于C++语言编写。
2) 通过条件定义同一时候支持window与linus双系统
4. 编译和链接
将源程序增加到project中
5. 执行环境
windows、linux操作系统验证同一时候支持。
6. 限制条件
无
7. 接口
1.构造函数: CViTrace(char*szPathName,//路径名
char* szAppName,//文件名称
_APP_INFO_OUT_CALLBACK pInfoOutCallback=NULL,//额外的输出回调
void *pInfoOutCallbackParam=NULL);//回调函数參数
/*************************************************************************************
功能:设置日志输出路径和额外的输出回调:
參数:
char*szPathName://路径名
char* szAppName,//文件名称
_APP_INFO_OUT_CALLBACK pInfoOutCallback:额外的输出回调
**************************************************************************************/
3. UINT trace(char* szFormat,...);
/*************************************************************************************
功能:字符串输出:
參数:
char* szFormat:可变參数。类似printf的使用
**************************************************************************************/
4. trace_bin(char*pBuffer,UINT nLength,bool bPrintAsci=false)
/******************************************************************************************
功能:转换为16进制和ascii码输出:
參数:
void *Buf:内存片地址。
UINT nLength:内存片长度
bool bPrintAsci: false:左側不输出ascii码信息,true:左側输出ascii码信息
******************************************************************************************/
8. 演示样例
8.1. Linux Demo
#include "vitrace.h"
CViTrace vilog("/mds6800","1234");
vilog.trace("log out put demo,%s","string inf");
char* szName= "1234567asdfghddffgeerrtyuiopasdfgghhjjzxcvbbbnnnmn";
vilog.trace_bin(szName, 50);
vilog.trace_bin(szName, 100,true);
日志输出:
<2015-06-09,15:18:48-124, tId=134597956>log out put demo,string inf
<2015-06-09,15:18:48-124, tId=134597956>
num address :bufferContent
0 0x807370c:31323334 35363761 73646667 68646466 66676565 72727479 75696F70 61736466
32 0x807372c:67676868 6A6A7A78 63766262 626E6E6E 6D6E
<2015-06-09,15:18:48-124, tId=134597956>
num address :bufferContent
0 0x807370c:31323334 35363761 73646667 68646466 66676565 72727479 75696F70 61736466 1234567asdfghddffgeerrtyuiopasdf
32 0x807372c:67676868 6A6A7A78 63766262 626E6E6E 6D6E000D 0A20696E 70757420 77726F6E gghhjjzxcvbbbnnnmn... input wron
64 0x807374c:67212075 73616765 3A257320 25730000 0D0A2069 6E707574 2077726F 6E672120 g! usage:%s %s.... input wrong!
96 0x807376c:75736167 usag
8.2. Window Demo
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <string>
#include <stdarg.h>
#include <direct.h>
#include "vitrace.h"
#include <windows.h>
#include <tchar.h>
#include "targetver.h"
char* szName= "1234567asdfghjklqwertyuiopasdfghjklzxcvbnm1234567asdfghjklqwertyuiopasdfghjklzxcvbnm";
int _tmain(int argc, _TCHAR* argv[])
{
char buffer[MAX_PATH];
getcwd(buffer, MAX_PATH);
CViTrace viLog(buffer,"buffer_print_test");
viLog.trace("字符串信息输出:");
viLog.trace("that's why with other flash applications you just don't get the expected results. the best option for each photo.");
viLog.trace("按进制编码输出指定内存的前字节内容:");
viLog.trace_bin(szName,50);
Sleep(100);
viLog.trace("输出指定内存的前字节内容,左边为进制值。右边为assci码:");
viLog.trace_bin(szName,100,true);
getchar();
return 0;
}
<2015-06-09,15:23:18-526, tId=20451738>字符串信息输出:
<2015-06-09,15:23:18-526, tId=20451738>that's why with other flash applications you just don't get the expected results. the best option for each photo.
<2015-06-09,15:23:18-526, tId=20451738>按16进制编码输出指定内存的前300字节内容:
<2015-06-09,15:23:18-526, tId=20451738>
num address :bufferContent
0 01387740:31323334 35363761 73646667 686A6B6C 71776572 74797569 6F706173 64666768
32 01387760:6A6B6C7A 78637662 6E6D3132 33343536 3761
<2015-06-09,15:23:18-635, tId=20451738>输出指定内存的前1000字节内容,左边为16进制值,右边为assci码:
<2015-06-09,15:23:18-635, tId=20451738>
num address :bufferContent
0 01387740:31323334 35363761 73646667 686A6B6C 71776572 74797569 6F706173 64666768 1234567asdfghjklqwertyuiopasdfgh
32 01387760:6A6B6C7A 78637662 6E6D3132 33343536 37617364 6667686A 6B6C7177 65727479 jklzxcvbnm1234567asdfghjklqwerty
64 01387780:75696F70 61736466 67686A6B 6C7A7863 76626E6D 00000000 00000000 00000000 uiopasdfghjklzxcvbnm............
96 013877A0:00000000
/** * @file Vitrace.h * @brief 支持windows linux下将指定内存段转为16进制与ascii码的日志输出类 * * @writer longf * @version 1.00 * @date 2015-01-27 * @history */ //#include "XAutoLock.h" //#include "rcs_public.h" #ifdef WIN32 #include <windows.h> #else #endif #ifndef UINT typedef unsigned int UINT; #endif // UINT #ifndef NULL #define NULL 0 #endif // NULL #define MAX_PATH 512 UINT vi_bin2ascii(char* pDstBuf,UINT nDstBufLen,char*pSrcBuf,UINT nSrcBufLen); UINT vi_bin2hex(char* pDstBuf,UINT nDstBufLen,char*pSrcBuf,UINT nSrcBufLen); typedef void (*_APP_INFO_OUT_CALLBACK)(char*szInfo,void*pCallParam); class CViTrace { public: CViTrace(char*szPathName,//路径名 char* szAppName,//文件名称 _APP_INFO_OUT_CALLBACK pInfoOutCallback=NULL,//额外的输出回调 void *pInfoOutCallbackParam=NULL);//回调函数參数 ~CViTrace(void); public: UINT trace(char* szFormat,...); void trace_bin(char*pBuffer,UINT nLength,bool bPrintAsci=false); public: //方便应用层取出输出信息。在不同的输出设备打入自己的输出队列 _APP_INFO_OUT_CALLBACK m_pInfoOutCallback; void* m_pInfoOutCallbackParam; private: char m_szFileName[MAX_PATH];//拼接好的路径名和文件名称 //XCritSec m_Lock; };
/** * @file Vitrace.cpp * @brief 支持windows linux下将指定内存段转为16进制与ascii码的日志输出类 * * @writer longf * @version 1.00 * @date 2015-01-27 * @history */ #include "vitrace.h" #include <time.h> #include <stdio.h> #include <string.h> #include <stdarg.h> #ifdef WIN32 #include <windows.h> #else #include <pthread.h> #include <sys/time.h> #endif #ifdef CON_DEBUG #define CON_PRINTF printf #else #define CON_PRINTF/\ /printf #endif #ifdef WIN32 #define PATH_CHAR "\\" #else #define PATH_CHAR "/" #endif inline unsigned int PthreadSelf() { #ifdef WIN32 return ::GetCurrentThreadId(); #else return pthread_self(); #endif } #define VITRACE_BUFFER_LENGTH 10000 //TRACE缓冲区大小 #define VITRACE_HEX_PRINTBYTES_PERLINE 32 #define VITRACE_HEX_SPACE 4 static UINT safe_printf(char*pDst,UINT nDstSize,char*szFormat,...) { UINT nListCount=0; va_list pArgList; if (!pDst) goto _EXIT_FUN; va_start(pArgList,szFormat); nListCount+=vsnprintf(pDst+nListCount,nDstSize-nListCount,szFormat,pArgList); va_end(pArgList); if (nListCount>(nDstSize-1)) nListCount = nDstSize-1; *(pDst+nListCount)='\0'; _EXIT_FUN: return nListCount; } void GetFullFileName(char* pBufFullname,UINT nBufSize,char* path,char* name,char* ext_name) { if (strlen(path)) { if (strlen(ext_name)) safe_printf(pBufFullname,nBufSize, "%s%s%s.%s",path,PATH_CHAR,name,ext_name); else safe_printf(pBufFullname,nBufSize, "%s%s%s",path,PATH_CHAR,name,name); } else { if (strlen(ext_name)) safe_printf(pBufFullname,nBufSize, "%s.%s",name,ext_name); else safe_printf(pBufFullname,nBufSize, "%s",name); } } UINT get_timestamp(char* szBuf,UINT nMaxLength) { UINT nLength=0; #ifdef WIN32 SYSTEMTIME tm; GetLocalTime(&tm); nLength= safe_printf(szBuf,nMaxLength,"%02d-%02d-%02d,%02d:%02d:%02d-%03d",tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond,tm.wMilliseconds ); #else /* time_t t; struct tm*pTM=NULL; time(&t); pTM= localtime(&t); nLength= safe_printf(szBuf,nMaxLength,"%s",asctime(pTM)); */ struct timeval tv; struct timezone tz; struct tm *p; gettimeofday(&tv, &tz); p = localtime(&tv.tv_sec); nLength= safe_printf(szBuf,nMaxLength,"%02d-%02d-%02d,%02d:%02d:%02d-%03d", 1900+p->tm_year, 1+p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, tv.tv_usec/1000); #endif return nLength; } ////以ascii显示指定数据区内容 UINT vi_bin2ascii(char* pDstBuf,UINT nDstBufLen,char*pSrcBuf,UINT nSrcBufLen) { if (nSrcBufLen>nDstBufLen) { nSrcBufLen = nDstBufLen; } UINT i; UINT nCount=0; for (i=0;i<nSrcBufLen;i++) { //ascii字符表中可显示字符代码>32 if (32<=*(pSrcBuf+i)) { nCount+= safe_printf(pDstBuf+nCount,nDstBufLen-nCount,"%c",pSrcBuf[i]); } else { nCount+= safe_printf(pDstBuf+nCount,nDstBufLen-nCount,"."); } } return nCount; } //以16进制显示指定数据区内容 UINT vi_bin2hex(char* pDstBuf,UINT nDstBufLen,char*pSrcBuf,UINT nSrcBufLen) { if (nSrcBufLen>nDstBufLen) { nSrcBufLen = nDstBufLen; } UINT i=0; UINT j=0; UINT nCount=0; for (i=0;i<nSrcBufLen;i++) { nCount+= safe_printf(pDstBuf+nCount,nDstBufLen-nCount,"%02X",(unsigned char)pSrcBuf[i]); j++; if (VITRACE_HEX_SPACE==j) { j=0; nCount+= safe_printf(pDstBuf+nCount,nDstBufLen-nCount," "); } } if (VITRACE_HEX_PRINTBYTES_PERLINE>nSrcBufLen)//每行打印VITRACE_PRINTBYTES_PER_LINE字节,不足补充空格 { for (;i<VITRACE_HEX_PRINTBYTES_PERLINE;i++) { nCount+= safe_printf(pDstBuf+nCount,nDstBufLen-nCount," ");//一个字符占用两个字节 j++; if (VITRACE_HEX_SPACE==j) { j=0; nCount+= safe_printf(pDstBuf+nCount,nDstBufLen-nCount," "); } } } return nCount; } //用户指定的输出文件,文件打开方式,一般“a+”。返回输出字符总数 UINT vi_trace(char* szFileName,char*szMode,char*strBuf) { UINT nListCount =0; char szTime[256]; get_timestamp(szTime,256); char tmp[VITRACE_BUFFER_LENGTH+256]; sprintf(tmp, "\r\n<%s, tId=%d>",szTime,PthreadSelf); FILE* fp; fp=fopen(szFileName,szMode); if (fp) { nListCount += fwrite(tmp, strlen(tmp), 1, fp); } nListCount += fwrite(strBuf, strlen(strBuf), 1, fp); fclose(fp); return nListCount; } /* Vint32 vi_trace(char* szFileName,char*szMode,char*szFormat,...) { char szBuf[LODEBUG_BUFFER_LENGTH]; char szTime[256]; Vint32 nListCount=0; va_list pArgList; va_start(pArgList,szFormat); nListCount+=_vsnprintf(szBuf+nListCount,LODEBUG_BUFFER_LENGTH-nListCount,szFormat,pArgList); va_end(pArgList); if (nListCount>(LODEBUG_BUFFER_LENGTH-1)) { nListCount=LODEBUG_BUFFER_LENGTH-1; } *(szBuf+nListCount)='\0'; nListCount = vi_trace(szFileName,szMode,szBuf); return nListCount; } */ //调用函数。VITRACE_HEX_PRINTBYTES_PERLINE字节为一行,格式化输出二进制内容 void vi_trace_bin(char* szFileName,char*szMode,char*pBuffer,UINT nLength,bool bPrintAsci=false) { if (nLength>VITRACE_BUFFER_LENGTH) { nLength =VITRACE_BUFFER_LENGTH; } int nAddr=0; int nLineValidCount=0; int nLineSpaceCount=0; int nBufferCount =nLength; int n=0; char szLine[VITRACE_BUFFER_LENGTH+1]={0}; int iLineNum=0; if(0<nLength) { n+=safe_printf(szLine+n,VITRACE_BUFFER_LENGTH-n,"\r\n%4s %8s:%s","num","address ","bufferContent "); if (bPrintAsci) { n+=vi_bin2ascii(szLine+n,VITRACE_BUFFER_LENGTH-n,pBuffer+nAddr,nLineValidCount); } while (1) { if (nBufferCount>=VITRACE_HEX_PRINTBYTES_PERLINE) { nLineValidCount = VITRACE_HEX_PRINTBYTES_PERLINE; nLineSpaceCount = 0; } else { nLineValidCount = nBufferCount; nLineSpaceCount = VITRACE_HEX_PRINTBYTES_PERLINE- nLineValidCount; } n+=safe_printf(szLine+n,VITRACE_BUFFER_LENGTH-n,"\r\n%4d %p:",iLineNum*VITRACE_HEX_PRINTBYTES_PERLINE,pBuffer+nAddr); n+=vi_bin2hex(szLine+n,VITRACE_BUFFER_LENGTH-n,pBuffer+nAddr,nLineValidCount); if (bPrintAsci) { n+=vi_bin2ascii(szLine+n,VITRACE_BUFFER_LENGTH-n,pBuffer+nAddr,nLineValidCount); } nAddr+=VITRACE_HEX_PRINTBYTES_PERLINE; nBufferCount-=VITRACE_HEX_PRINTBYTES_PERLINE; iLineNum++; if (0>=nBufferCount) break; } } vi_trace(szFileName,szMode,szLine); } /************************************************************************************* 功能:设置日志输出路径和额外的输出回调: 參数: char*szPathName://路径名 char* szAppName,//文件名称 _APP_INFO_OUT_CALLBACK pInfoOutCallback:额外的输出回调 **************************************************************************************/ CViTrace::CViTrace(char*szPathName,char* szAppName,_APP_INFO_OUT_CALLBACK pInfoOutCallback, void *pInfoOutCallbackParam) { m_pInfoOutCallback=pInfoOutCallback; m_pInfoOutCallbackParam=pInfoOutCallbackParam; if (szAppName) { GetFullFileName(m_szFileName,MAX_PATH,szPathName,szAppName,"log"); } else m_szFileName[0]='\0'; remove(m_szFileName); } CViTrace::~CViTrace(void) { } /************************************************************************************* 功能:字符串输出: 參数: char* szFormat:可变參数,相似printf的使用 **************************************************************************************/ UINT CViTrace::trace(char* szFormat,...) { //XAutoLock xLock(m_Lock); char szBuff[VITRACE_BUFFER_LENGTH]={0}; FILE *fp=NULL; UINT nListCount=0; va_list pArgList; va_start(pArgList,szFormat); nListCount+= vsnprintf(szBuff+nListCount,VITRACE_BUFFER_LENGTH-nListCount,szFormat,pArgList); va_end(pArgList); if (nListCount>(VITRACE_BUFFER_LENGTH-1)) { nListCount = VITRACE_BUFFER_LENGTH-1; } *(szBuff+nListCount)='\0'; nListCount = vi_trace(m_szFileName,"a+",szBuff); //回调输出; if(m_pInfoOutCallback) { char szTime[256]; get_timestamp(szTime,256); char tmp[256]; sprintf(tmp, "\r\n<%s, tId=%d>\t",szTime,PthreadSelf); char szInfoOut[VITRACE_BUFFER_LENGTH]; safe_printf(szInfoOut,VITRACE_BUFFER_LENGTH,"%s%s",tmp,szBuff); m_pInfoOutCallback(szInfoOut,m_pInfoOutCallbackParam); //CON_PRINTF("%s",szInfoOut); } return nListCount; } /****************************************************************************************** 功能:转换为16进制和ascii码输出: 參数: void *Buf:内存片地址。 UINT nLength:内存片长度 bool bPrintAsci: false:左側不输出ascii码信息,true:左側输出ascii码信息 ******************************************************************************************/ void CViTrace::trace_bin(char*pBuffer,UINT nLength,bool bPrintAsci) { if (nLength>1000) { nLength = 1000; } //XAutoLock xLock(m_Lock); vi_trace_bin(m_szFileName,"a+",pBuffer,nLength,bPrintAsci); }