一段项目开发时候用的调试代码 二 --代码分析器(基于表驱动直接访问)

有时候项目中会有很多同级抽象的对象,每种对象有自己的属性。在程序调试过程中需要输出一些数据结构来表征这些对象的组织结构。

利用了《代码大全》中介绍的,表驱动法来建立数据结构表,使用直接访问表来输出这些对象相关的信息。


该方法基于上一篇的调试代码用于将数据结构输出到文件。

1. 直接访问法

UT_analyzer.h

/*Analyzer module header file
This module is designed to to analyze the complex data structure such as piecetable, fragement, attr, doclayout, change record
run and so on.
It will support to output the data structure defined by these complex structures.
*/
#ifndef UT_ANALYZER_H
#define UT_ANALYZER_H



#if ((defined(DEBUG) || (TEST_LOG)))
#include "pt_Types.h"

class pt_PieceTable;
class pf_Frag;

//Member function
//For the pf_Frag object;
void printFrag(pf_Frag* pf);
void printFragStrux(pf_Frag* pf);
void printFragObject(pf_Frag* pf);

//Some algorithm to analyze the data structure of the ABISource.
//The abstract class analyzer which determine the basic interface for the analyzer.
class Analyzer
{
public:
	Analyzer(){};
	~Analyzer(){};
	virtual void printDataStructure(void) = 0;
	virtual void printDataStructure(PT_DocPosition dpos) = 0;
};

//1.The analyzer to print the structure of the m_piecetable.
class Analyzer_Piecetable : public Analyzer
{
public:
	explicit Analyzer_Piecetable(pt_PieceTable* t) :m_pPieceTable(t){}
	~Analyzer_Piecetable(){};
	void printDataStructure(void);
	void printDataStructure(PT_DocPosition dpos);

private:


	//Member Variable
	pt_PieceTable* m_pPieceTable;
};

//2.The analyzer to print the structure of the doc_layout

//3.The analyzer to print the structure of the fp_page ->fp_run.

//4.The analyzer to print the properties of the fragment.

//5.The analyzer to print the structure of the change record.
#endif

#endif


UT_analyzer.cpp

/*Analyzer module source file
This module is designed to to analyze the complex data structure such as piecetable, fragement, attr, fl_doclayout, changerecord
fp_run and so on.
It will support to output the data structure defined by these complex structures.*/

#include "ut_analyzer.h"

#if ((defined(DEBUG) || (TEST_LOG)))

#include "pf_Frag.h"
#include "pf_Frag_Strux.h"
#include "pf_Frag_Object.h"
#include "pt_PieceTable.h"
#include <iostream>

//define the table driven method for the piecetable structure.
//Begin definition
typedef void(*func_ptr)(pf_Frag *);
typedef struct{
	pf_Frag::PFType sType;
	char szFmt[255];
	func_ptr fun;	//whether we need to do further processing
}MethodFragTable;

typedef struct{
	PTStruxType sType;
	char szFmt[255];
	func_ptr fun;
}MethodFragStruxTable;

typedef struct{
	PTObjectType sType;
	char szFmt[255];
	func_ptr fun;
}MethodFragObjectTable;

static const MethodFragTable g_MethodFragTable[] = {
	pf_Frag::PFT_Text,		"pos: %d\tPFT_Text\t length\t%d",		NULL,
	pf_Frag::PFT_Object, "pos: %d\tPFT_Object\t length\t%d", 		printFragObject,
	pf_Frag::PFT_Strux,		"pos: %d\tPFT_Strux\t length\t%d",		printFragStrux,
	pf_Frag::PFT_EndOfDoc,	"pos: %d\tPFT_EndOfDoc\t length\t%d",	NULL,
	pf_Frag::PFT_FmtMark,	"pos: %d\tPFT_FmtMark\t length\t%d",	NULL
};

static const MethodFragStruxTable g_MethodFragStruxTable[] = {
	PTX_Section,			"\tStrux Type PTX_Section",				NULL,// 0 -- maker sure that we can cast into uint
	PTX_Block,				"\tStrux Type PTX_Block",				NULL,// 1			
	PTX_SectionHdrFtr,		"\tStrux Type PTX_SectionHdrFtr",		NULL,// 2
	PTX_SectionEndnote,		"\tStrux Type PTX_SectionEndnote",		NULL,// 3
	PTX_SectionTable,		"\tStrux Type PTX_SectionTable",		NULL,// 4
	PTX_SectionCell,		"\tStrux Type PTX_SectionCell",			NULL,// 5
	PTX_SectionFootnote,	"\tStrux Type PTX_SectionFootnote",		NULL,// 6
	PTX_SectionMarginnote,	"\tStrux Type PTX_SectionMarginnote",	NULL,// 7
	PTX_SectionAnnotation,	"\tStrux Type PTX_SectionAnnotation",	NULL,// 8
	PTX_SectionFrame,		"\tStrux Type PTX_SectionFrame",		NULL,// 9
	PTX_SectionControl,		"\tStrux Type PTX_SectionControl",		NULL,// 10
	PTX_EndCell,			"\tStrux Type PTX_EndCell",				NULL,// 11
	PTX_EndTable,			"\tStrux Type PTX_EndTable",			NULL,
	PTX_EndFootnote,		"\tStrux Type PTX_EndFootnote",			NULL,
	PTX_EndMarginnote,		"\tStrux Type PTX_EndMarginnote",		NULL,
	PTX_EndEndnote,			"\tStrux Type PTX_EndEndnote",			NULL,
	PTX_EndAnnotation,		"\tStrux Type PTX_EndAnnotation",		NULL,
	PTX_EndFrame,			"\tStrux Type PTX_EndFrame",			NULL,
	PTX_EndControl,			"\tStrux Type PTX_EndControl",			NULL
};

static const MethodFragObjectTable g_MethodFragObjectTable[] = {
	PTO_Image, 			"\tObject Type PTO_Image",		NULL,//= 0,
	PTO_Field,			"\tObject Type PTO_Field",		NULL,
	PTO_Bookmark,		"\tObject Type PTO_Bookmark",	NULL,
	PTO_Hyperlink,		"\tObject Type PTO_Hyperlink",	NULL,
	PTO_Math,			"\tObject Type PTO_Math",		NULL,
	PTO_Embed,			"\tObject Type PTO_Embed",		NULL,
	PTO_Annotation,		"\tObject Type PTO_Annotation", NULL,
	PTO_Control,		"\tObject Type PTO_Control",	NULL,
	PTO_Horizental,		"\tObject Type PTO_Horizental", NULL
};

#define ARRAY_LENGTH(arr) (sizeof arr / sizeof arr[0])

//End definition.
void printFrag(pf_Frag* pfrag)
{
	UT_DEBUGMSG(("The type of pf_Frag is :%d and the Array length is :%d", pfrag->getType(), ARRAY_LENGTH(g_MethodFragTable)));
	UT_ASSERT(pfrag->getType()<ARRAY_LENGTH(g_MethodFragTable));
	char		szBuffer[255]	= {0};
	std::string szFormat		= g_MethodFragTable[pfrag->getType()].szFmt;
	func_ptr	pFun			= g_MethodFragTable[pfrag->getType()].fun;

	sprintf(szBuffer, szFormat.c_str(), pfrag->getPos(), pfrag->getLength());
	if (pFun)
	{
		UT_TestLog::GetInstance()->printlogA(szBuffer);
		pFun(pfrag);
	}
	else
	{
		UT_TestLog::GetInstance()->printlnlogA(szBuffer);
	}	
}

void printFragStrux(pf_Frag* pfrag)
{
	char				szBuffer[255]	= { 0 };
	pf_Frag_Strux *		pfs				= dynamic_cast<pf_Frag_Strux*>(pfrag);

	UT_DEBUGMSG(("The type of pf_Frag_Strux is :%d and the Array length is :%d", pfs->getStruxType(), ARRAY_LENGTH(g_MethodFragStruxTable)));
	UT_ASSERT(pfrag->getType() < ARRAY_LENGTH(g_MethodFragTable));

	std::string			szFormat		= g_MethodFragStruxTable[pfs->getStruxType()].szFmt;
	func_ptr			pFun			= g_MethodFragStruxTable[pfs->getStruxType()].fun;

	sprintf(szBuffer, szFormat.c_str());
	if (pFun)
	{
		UT_TestLog::GetInstance()->printlogA(szBuffer);
		pFun(pfs);
	}
	else
	{
		UT_TestLog::GetInstance()->printlnlogA(szBuffer);
	}
}

void printFragObject(pf_Frag* pfrag)
{
	char				szBuffer[255]	= { 0 };
	pf_Frag_Object *	pfo				= dynamic_cast<pf_Frag_Object*>(pfrag);

	UT_DEBUGMSG(("The type of pf_Frag_Object is :%d and the Array length is :%d", pfo->getObjectType(), ARRAY_LENGTH(g_MethodFragObjectTable)));
	UT_ASSERT(pfrag->getType() < ARRAY_LENGTH(g_MethodFragTable));

	std::string			szFormat		= g_MethodFragObjectTable[pfo->getObjectType()].szFmt;
	func_ptr			pFun			= g_MethodFragObjectTable[pfo->getObjectType()].fun;

	sprintf(szBuffer, szFormat.c_str());
	if (pFun)
	{
		UT_TestLog::GetInstance()->printlogA(szBuffer);
		pFun(pfo);
	}
	else
	{
		UT_TestLog::GetInstance()->printlnlogA(szBuffer);
	}
}

void Analyzer_Piecetable::printDataStructure(void)
{
	if (m_pPieceTable == NULL)
		return;
	pf_Frag * pfrag = m_pPieceTable->getFragments().getFirst();
	while (pfrag)
	{
		printFrag(pfrag);
		pfrag = pfrag->getNext();
	}
}

void Analyzer_Piecetable::printDataStructure(PT_DocPosition dpos)
{
	if (m_pPieceTable == NULL)
		return;
	pf_Frag * pfrag = m_pPieceTable->getFragments().getFirst();
	pf_Frag * pCurrentFrag = NULL;
	m_pPieceTable->getFragFromPosition(dpos, &pCurrentFrag, 0);
	while (pfrag)
	{
		//Get the current frag.
		if (pCurrentFrag != NULL &&
			pCurrentFrag == pfrag)
			UT_TestLog::GetInstance()->printlogA("*->");
		printFrag(pfrag);
		pfrag = pfrag->getNext();
	}

}

#endif


------------------------------------------------------------------------------------------------------------------------------------------------------------------------

另外表驱动法还有索引访问和阶梯访问两种方法。这里顺便做一下笔记


2. 索引访问

有时候无法把数据直接转换为键值,比如对象的数据不是连续的,需要使用一种索引表技术将离散的数据转换为一种连续的数据索引。

然后再用索引值来查询出相关的处理数据和过程。


3. 阶梯范围

数据可能是非离散的,而是连续的浮点数(类比信号中的analog signal). 这时候可以使用阶梯访问技术一个例子

#define ARRAY_LENGTH(arr) (sizeof arr / sizeof arr[0])

typedef char GradeType;

GradeType testGrade(double studentScore)
{
	double rangeLimit[] = { 50.0, 65.0, 75.0, 90.0, 100.0 };
	GradeType grade[] = { 'F', 'D', 'C', 'B', 'A' };
	const int MAX_GRADE_LEVEL = ARRAY_LENGTH(rangeLimit) -1;
	int gradeLevel = 0;
	GradeType studentGrade = 'F';

	while (gradeLevel <= MAX_GRADE_LEVEL)
	{
		if (studentScore < rangeLimit[gradeLevel])
		{
			studentGrade = grade[gradeLevel];
		}
		gradeLevel++;
	}

	return studentGrade;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值