您的位置:首页 > 运维架构 > Linux

支持windows linux下将指定内存段转为16进制与ascii码的日志输出类

2015-06-30 16:43 531 查看
来源: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. 编译和链接

将源程序加入到工程中

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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: