www.pudn.com > tvctrl.rar > epg.c


/*  
 *	filename: epg.c  
 */  
  
/*  
	***added cheng   
	请注意:	progid > 0  
			playid > 0  
*/  
#include   
#include   
#include "atvdtv.h"  
#include "predefine.h"  
  
#include "channeldb.h"  
#include "epg.h"  
  
#define EPGDB_CTRL_ALLOC_NUM		1  
#define GET_EPGDB_SAVE_PATH(file)		"/extra/database/"#file  
  
#define GET_STINDEX_INSERT_POS(last_index_item,search_des)	get_insert_pos_time(last_index_item,search_des)  
#define GET_TVINDEX_INSERT_POS(last_index_item,search_des)	get_insert_pos_tv(last_index_item,search_des)  
  
#define GET_STSTART_POS(sdes,p_spos,last)	\  
			search_start_pos_time(sdes,p_spos,last)  
#define GET_TVIDSTART_POS(tvid, sdes,p_spos,last)	\  
			search_start_pos_tvtime(tvid, sdes, p_spos, last)  
//#define GET_TVSTARTEND_POS(s,ps,e,pe,c)	search_pos(s,ps,e,pe,0x1,c)  
  
/*  
声明:  
 EPGRECORD中的con_time的最高位(15位)被作为定时控制,置1为定时,置0为非定时  
*/  
#define GET_CON_TIME(flags)	((flags)&0x7fff)  
#define SET_TIMER(flags)	(flags=((flags)|0x8000))  
#define SET_NOTTIMER(flags)	(flags=((flags)&0x7fff))  
#define IS_TIMER(flags)		((flags)&0x8000)  
#define IS_NOTTIMER(flags)	(!((flags)&0x8000))  
  
enum  
{  
	STATUS_NORMAL        = 0 ,  
	STATUS_DELETED		 = -1 ,  
} ;  
  
typedef struct tagEpgDbCtrl  
{  
	struct  
	{  
		INT32  allocCount ;  //申请的总项数  
		INT32  itemCount ;  //已使用的项数  
		EPGRECORD * records ;  
		INT8  * flagArray ;    
		INT32 * timeIndex ;  //时间索引表   
		INT32 * tvIndex ;  //电视台索引表  
  
		INT32 * returnArray ;  
	} playInfo ; // 节目播放信息,对应电视台  
  
	struct  
	{  
		INT32  allocCount ;  //申请的总项数  
		INT32	itemCount ;  //已使用的项数  
		PROGRAMRECORD * records ;  
		INT8  * flagArray ;  
	} programInfo ; // 节目表  
  
	struct  
	{  
		INT32  allocCount ;  //申请的总项数  
		INT32  usedCount ;  //已使用的项数  
		INT8 * head ;  
	} nameField ;  //  集中存放节目名  
  
	struct  
	{  
		INT32  allocCount ;  //申请的总项数  
		INT32  usedCount ;  //已使用的项数  
		INT8 * head ;  
	} textField ;  //  集中存入节目描述信息  
  
} EpgDbCtrl_t ;  
  
static EpgDbCtrl_t * pEpgDbCtrl = NULL ;  
  
static UINT32 get_utc_time(UINT32 mjd_time_1, UINT32 mjd_time_0) ;  
static int pack(void) ;  
static int reindexall() ;  
  
static void * GetMemory(UINT32 size_t)  
{  
	return malloc(size_t) ;  
}  
  
static void FreeMemory(void *ptr)  
{  
	if(ptr != NULL)  
	{  
		free(ptr) ;  
	}  
}  
  
  
/* =============================cheng added================================= */  
/* 按照播放表id取得其在节目表中的对应关系 */  
static int PlayId2ProgIndex(int playid)  
{  
	return (pEpgDbCtrl->playInfo.records[playid-1].programid-1) ;  
}  
  
static int ProgId2ProgIndex(int progid)  
{  
	return (progid-1) ;  
}  
  
static int IsProgTitleMatch(int playid, char *title)  
{  
	if (pEpgDbCtrl->nameField.head)  
		return (int) strstr(pEpgDbCtrl->nameField.head+(int)(pEpgDbCtrl->programInfo.records[PlayId2ProgIndex(playid)].name), title) ;  
	else  
		return (0) ;  
}  
  
static int IsProgDescMatch(int playid, char *desc)  
{  
	if (pEpgDbCtrl->textField.head)  
		return (int) strstr(pEpgDbCtrl->textField.head+(int)(pEpgDbCtrl->playInfo.records[playid-1].infoindex), desc) ;  
	else  
		return (0) ;  
}  
/* =============================cheng added================================= */  
  
  
/* --------------- 用于测试的函数 --------------- */  
#ifdef ___EITTEST___  
//#ifdef _DEBUG  
  
void test_pack()  
{  
	pack() ;  
}  
void test_ReIndexAll()  
{  
	assert(pEpgDbCtrl) ;  
	memset(pEpgDbCtrl->playInfo.timeIndex,0x0,sizeof(INT32)*pEpgDbCtrl->playInfo.allocCount) ;  
	memset(pEpgDbCtrl->playInfo.tvIndex,0x0,sizeof(INT32)*pEpgDbCtrl->playInfo.allocCount) ;  
  
	reindexall() ;  
}  
  
void test_GetNameAndText(event_information_section_t * p_eit,int event_num,char **ppname, char **pptext)  
{  
	int index = 0 ;  
	int num = 0 ;  
	assert(ppname != NULL && pptext != NULL) ;  
	assert(p_eit->events_number != 0) ;  
  
	for(index=0;index<(int)p_eit->p_events[event_num].descriptor_number;index++)  
	{  
		if( GetDescriptorTag(((void**)p_eit->p_events[event_num].p_pDescriptor)[index]) == 0x4d )  
		{  
			num = ((short_event_descriptor_t *)((void**)p_eit->p_events[event_num].p_pDescriptor)[index])->event_name_length ;  
			if(	num > 0  
				&& ((short_event_descriptor_t *)((void**)p_eit->p_events[event_num].p_pDescriptor)[index])->p_event_name_char  
				)  
			{  
				*ppname = GetMemory(1 + num ) ;  
				memcpy(*ppname,((short_event_descriptor_t *)((void**)p_eit->p_events[event_num].p_pDescriptor)[index])->p_event_name_char,num) ;  
				(*ppname)[num] = '\0' ;  
			}  
			num = ((short_event_descriptor_t *)((void**)p_eit->p_events[event_num].p_pDescriptor)[index])->text_length ;  
			if( num > 0  
				&& ((short_event_descriptor_t *)((void**)p_eit->p_events[event_num].p_pDescriptor)[index])->p_text_char  
				)  
			{  
				*pptext = GetMemory(1 + num ) ;  
				memcpy(*pptext,((short_event_descriptor_t *)((void**)p_eit->p_events[event_num].p_pDescriptor)[index])->p_text_char,num) ;  
				(*pptext)[num] = '\0' ;  
			}  
		}  
	}  
}  
void test_GetStartAndContTime(event_information_section_t * p_eit,int event_num,int *pstart, int *pcont)  
{  
	assert( pstart && pcont) ;  
  
	*pstart = get_utc_time(p_eit->p_events[event_num].start_time_1,p_eit->p_events[event_num].start_time_0) ;  
	*pcont = p_eit->p_events[event_num].duration ;  
}  
void test_DisplayItem(int item_num)  
{  
	assert(pEpgDbCtrl && item_num<(int)pEpgDbCtrl->playInfo.itemCount) ;  
	if(pEpgDbCtrl->playInfo.flagArray[item_num]==STATUS_DELETED)  
		return ;  
	printf("\nMainType: %d\tSubType: %d\t",  
		pEpgDbCtrl->programInfo.records[pEpgDbCtrl->playInfo.records[item_num].programid].maintype,  
		pEpgDbCtrl->programInfo.records[pEpgDbCtrl->playInfo.records[item_num].programid].subtype  
		) ;  
	printf("StartTime: %d\tDuring: %d\n",  
		pEpgDbCtrl->playInfo.records[item_num].playtime ,  
		GET_CON_TIME(pEpgDbCtrl->playInfo.records[item_num].con_time)  
		) ;  
	printf("Name: %s\n",  
		pEpgDbCtrl->nameField.head?(pEpgDbCtrl->nameField.head+(int)pEpgDbCtrl->programInfo.records[pEpgDbCtrl->playInfo.records[item_num].programid].name):"") ;  
	printf("Description: %s\n",  
		pEpgDbCtrl->textField.head?(pEpgDbCtrl->textField.head+(int)pEpgDbCtrl->playInfo.records[pEpgDbCtrl->playInfo.records[item_num].programid].infoindex):"") ;  
}  
void test_DisplayPrograms(UINT8 display_order)  
{  
	int index = 0 ;  
	int cur_pos ;  
	if( !pEpgDbCtrl )  
		return ;  
  
	if( display_order == 0x0 )  
	{  
		printf("\n\n---- Now Display Programs (No Order)---- \n") ;  
		for(index=0;index<(int)pEpgDbCtrl->playInfo.itemCount;index++)  
		{  
			if(pEpgDbCtrl->playInfo.flagArray[index]==STATUS_DELETED)  
				continue ;  
			printf("PROGRAM_NUM = %d\nMainType: %d\tSubType: %d\t",  
				index,  
				pEpgDbCtrl->programInfo.records[pEpgDbCtrl->playInfo.records[index].programid].maintype,  
				pEpgDbCtrl->programInfo.records[pEpgDbCtrl->playInfo.records[index].programid].subtype  
				) ;  
			printf("StartTime: %d\tDuring: %d\n",  
				pEpgDbCtrl->playInfo.records[index].playtime ,  
				GET_CON_TIME(pEpgDbCtrl->playInfo.records[index].con_time)  
				) ;  
			printf("Name: %s\n",  
				pEpgDbCtrl->nameField.head?(pEpgDbCtrl->nameField.head+(int)pEpgDbCtrl->programInfo.records[pEpgDbCtrl->playInfo.records[index].programid].name):"") ;  
			printf("Description: %s\n",  
				pEpgDbCtrl->textField.head?(pEpgDbCtrl->textField.head+(int)pEpgDbCtrl->playInfo.records[pEpgDbCtrl->playInfo.records[index].programid].infoindex):"") ;  
		}  
	}  
	else if (display_order == 0x01)  
	{  
		printf("\n\n---- Now Display Programs (Ordered By Start Time) ---- \n") ;  
		for(index=0;index<(int)pEpgDbCtrl->playInfo.itemCount;index++)  
		{  
			cur_pos = pEpgDbCtrl->playInfo.timeIndex[index] ;  
			if(pEpgDbCtrl->playInfo.flagArray[cur_pos]==STATUS_DELETED)  
				continue ;  
			printf("PROGRAM_NUM = %d\tIndex_table[%d] = %d\nMainType = %d\tSubType: %d\t",  
				index,  
				index,  
				cur_pos,  
				pEpgDbCtrl->programInfo.records[pEpgDbCtrl->playInfo.records[cur_pos].programid].maintype,  
				pEpgDbCtrl->programInfo.records[pEpgDbCtrl->playInfo.records[cur_pos].programid].subtype  
				) ;  
			printf("StartTime: %d\tDuring: %d\n",  
				pEpgDbCtrl->playInfo.records[cur_pos].playtime ,  
				GET_CON_TIME(pEpgDbCtrl->playInfo.records[cur_pos].con_time)  
				) ;  
			printf("Name: %s\n",  
				pEpgDbCtrl->nameField.head?(pEpgDbCtrl->nameField.head+(int)pEpgDbCtrl->programInfo.records[pEpgDbCtrl->playInfo.records[cur_pos].programid].name):"") ;  
			printf("Description: %s\n",  
				pEpgDbCtrl->textField.head?(pEpgDbCtrl->textField.head+(int)pEpgDbCtrl->playInfo.records[pEpgDbCtrl->playInfo.records[cur_pos].programid].infoindex):"") ;  
		}	  
	}  
}  
//#endif  
#endif /* end #ifdef ___EITTEST___ */  
  
/* --------------- 辅助函数 --------------- */  
  
/*   
 *说明:辅助函数,只是自己调用而已  
 *	函数只是简单地实现了根据time_t时间检索的功能,如果以后还要增加其它的检索的话,应该再定义与之相对应的函数  
 *	该函数只是进行简单的time_t检索,尽量提高效率  
 */  
static void search_start_pos_time(int start_des,INT32 *p_start_pos,INT32 last_item)  
{  
	INT32 small,large ;  
	INT32 *index_table ;  
	assert(pEpgDbCtrl && pEpgDbCtrl->playInfo.records) ;  
	assert(last_item>=0 && last_itemplayInfo.itemCount) ;  
  
	*p_start_pos = -1 ;  
	index_table = pEpgDbCtrl->playInfo.timeIndex ;  
  
	 /* start_des==0: 忽略该参数 */  
	if( start_des != 0   
		&& start_des >= pEpgDbCtrl->playInfo.records[index_table[0]].playtime  
		)  
	{  
		int i ;  
		  
		small = 0 ;  
		large = last_item ;  
		/*  
		while( large-small > 1 )  
		{  
			if(start_des <= pEpgDbCtrl->playInfo.records[index_table[(large+small)/2]].playtime)  
				large = (large + small)/2 ;  
			else  
				small = (large + small)/2 ;  
		}  
		*p_start_pos = large ;  
		*/  
		while( large-small > 1)  
		{  
			if(start_des < pEpgDbCtrl->playInfo.records[index_table[(large+small)/2]].playtime)  
				large = (large + small)/2 ;  
			else  
			if(start_des > pEpgDbCtrl->playInfo.records[index_table[(large+small)/2]].playtime)  
				small = (large + small)/2 ;  
			else  
			{  
				large = (large + small)/2 ;  
				break ;  
			}  
		}  
		  
		i = large ;  
		while (i >= small)  
		{  
			if (pEpgDbCtrl->playInfo.records[index_table[i]].playtime < start_des)  
			{  
				if (i < large)  
				{  
					if (pEpgDbCtrl->playInfo.records[index_table[i+1]].playtime > start_des)  
					{  
						*p_start_pos = i+1 ;  
					}  
					else  
					if (pEpgDbCtrl->playInfo.records[index_table[i+1]].playtime == start_des)  
					{  
						*p_start_pos = i+1 ;  
					}  
				}  
				else  
				{  
					/* *p_start_pos = i ; */  
				}  
				break ;	  
			}  
			else  
			if (i == small)  
			{  
				if (pEpgDbCtrl->playInfo.records[index_table[i]].playtime == start_des)  
					*p_start_pos = i ;  
			}  
			i-- ;  
		}  
	}  
	else  
	if (start_des == 0)  
	{  
		*p_start_pos = 0 ;  
	}  
}  
  
/*   
 *说明:辅助函数,只是自己调用而已  
 *	函数只是简单地实现了根据tvid及时间检索的功能,如果以后还要增加其它的检索的话,应该再定义与之相对应的函数  
 *	该函数只是进行简单的tvid及时间检索,尽量提高效率  
 */  
static void search_start_pos_tvtime(int tvid, int start_des, INT32 *p_start_pos,INT32 last_item)  
{  
	INT32 small,large ;  
	INT32 *index_table ;  
	assert(pEpgDbCtrl && pEpgDbCtrl->playInfo.records) ;  
	assert(last_item>=0 && last_itemplayInfo.itemCount) ;  
  
	*p_start_pos = -1 ;  
	index_table = pEpgDbCtrl->playInfo.tvIndex ;  
  
	 /* start_des==0: 忽略该参数 */  
	if( tvid != 0   
		&& tvid >= pEpgDbCtrl->playInfo.records[index_table[0]].tvid  
		&& last_item >= 0  
		)  
	{  
		small = 0 ;  
		large = last_item ;  
		  
		while( large-small > 1)  
		{  
			if(tvid < pEpgDbCtrl->playInfo.records[index_table[(large+small)/2]].tvid)  
				large = (large + small)/2 ;  
			else  
			if(tvid > pEpgDbCtrl->playInfo.records[index_table[(large+small)/2]].tvid)  
				small = (large + small)/2 ;  
			else  
			{  
				int i ;  
				  
				i = (large+small)/2 ;  
				printf("get tvid, i=%d \n", i) ;  
				/* 向后顺序搜索 */  
				if (pEpgDbCtrl->playInfo.records[index_table[i]].playtime >= start_des)  
				{  
					for (;i>=0; i--)  
					{  
						if (pEpgDbCtrl->playInfo.records[index_table[i]].tvid != tvid)  
						{  
							*p_start_pos = i+1 ;  
							printf("tvid != tvid, i=%d start_des=%d \n", i, start_des) ;  
							break ;  
						}  
						else  
						if (pEpgDbCtrl->playInfo.records[index_table[i]].playtime <= start_des)  
						{  
							*p_start_pos = i ;  
							break ;  
						}  
					}  
					if (i<0)  
						*p_start_pos = 0 ;  
				}  
				/* 向前顺序搜索 */  
				else  
				if (pEpgDbCtrl->playInfo.records[index_table[i]].playtime < start_des)  
				{  
					for (;i<=last_item; i++)  
					{  
						if (pEpgDbCtrl->playInfo.records[index_table[i]].tvid != tvid)  
						{  
							*p_start_pos = i-1 ;  
							printf("tvid != tvid, i=%d start_des=%d \n", i, start_des) ;  
							break ;  
						}  
						else  
						if (pEpgDbCtrl->playInfo.records[index_table[i]].playtime > start_des)  
						{  
							*p_start_pos = i-1 ;  
							break ;  
						}  
						else  
						if (pEpgDbCtrl->playInfo.records[index_table[i]].playtime == start_des)  
						{  
							*p_start_pos = i ;  
							break ;  
						}  
					}  
					if (i>last_item)  
						*p_start_pos = last_item ;  
				}  
					  
				goto done ;  
			}  
		}  
		/* 不能进行二分查找,顺序查找之 */  
		if (last_item == 0)  
		{  
			if (pEpgDbCtrl->playInfo.records[index_table[0]].tvid == tvid  
				&& pEpgDbCtrl->playInfo.records[index_table[0]].playtime <= start_des  
				)  
				*p_start_pos = 0 ;  
		}  
		else  
		if (last_item == 1)  
		{  
			if (pEpgDbCtrl->playInfo.records[index_table[0]].tvid == tvid  
				&& pEpgDbCtrl->playInfo.records[index_table[1]].tvid == tvid  
				)  
			{  
				if (pEpgDbCtrl->playInfo.records[index_table[1]].playtime <= start_des)  
					*p_start_pos = 1 ;  
				else  
				if (pEpgDbCtrl->playInfo.records[index_table[0]].playtime <= start_des)  
					*p_start_pos = 0 ;  
			}  
			else  
			if (pEpgDbCtrl->playInfo.records[index_table[0]].tvid == tvid)  
			{  
				if (pEpgDbCtrl->playInfo.records[index_table[0]].playtime <= start_des)  
					*p_start_pos = 0 ;  
			}  
			else  
			if (pEpgDbCtrl->playInfo.records[index_table[1]].tvid == tvid)  
			{  
				if (pEpgDbCtrl->playInfo.records[index_table[1]].playtime <= start_des)  
					*p_start_pos = 1 ;  
			}  
		}  
	}  
	  
done:  
	return  ;  
}  
  
static int get_insert_pos_time(INT32 last_index_item,INT32 search_des)  
{  
	INT32 *index_table ;  
	int  small,large ;  
	assert(pEpgDbCtrl && pEpgDbCtrl->playInfo.itemCount>0) ;  
  
	/* 节目信息表的索引表中没有元素,返回最前面的位置便可以了 */  
	if(pEpgDbCtrl->playInfo.itemCount <= 1)  
		return 0 ;  
 	index_table = pEpgDbCtrl->playInfo.timeIndex ;  
	  
	if(search_des < pEpgDbCtrl->playInfo.records[index_table[0]].playtime)  
		return 0 ;  
	else if(search_des >= pEpgDbCtrl->playInfo.records[index_table[last_index_item]].playtime)  
		return (last_index_item+1) ;  
	else  
	{  
		small = 0 ;  
		large = last_index_item ;  
		while(large-small > 1)  
		{  
			if(search_des >= pEpgDbCtrl->playInfo.records[index_table[(large+small)/2]].playtime)  
				small = (large+small)/2 ;  
			else  
				large = (large+small)/2 ;  
		}  
	}  
	return small ;  
}  
static int get_insert_pos_tv(int last_index_item,int search_des)  
{  
	INT32 *index_table ;  
	int  small,large ;  
	assert(pEpgDbCtrl && pEpgDbCtrl->playInfo.itemCount>0) ;  
  
	/* 节目信息表的索引表中没有元素,返回最前面的位置便可以了 */  
	if(pEpgDbCtrl->playInfo.itemCount <= 1)  
		return 0 ;  
	index_table = pEpgDbCtrl->playInfo.tvIndex ;  
  
	if(search_des < pEpgDbCtrl->playInfo.records[index_table[0]].tvid)  
		return 0 ;  
	else if(search_des >= pEpgDbCtrl->playInfo.records[index_table[last_index_item]].tvid)  
		return (last_index_item+1) ;  
	else  
	{  
		small = 0 ;  
		large = last_index_item ;  
		while(large-small>1)  
		{  
			if(search_des >= pEpgDbCtrl->playInfo.records[index_table[(small+large)/2]].tvid)  
				small = (large+small)/2 ;  
			else  
				large = (large+small)/2 ;  
		}  
	}  
	return small ;  
}  
  
/*  
 *说明:改动索引表,该函数的调用是在AddEPGPlay函数体中,在所有过添加操作完成之后,此时records中元素个数已  
 *	比index表中元素个数多1个,即在index表中元素 "个数" 是itemCount-1个  
 *	                                             ~~~~                                                 
 */  
static int modify_index_tables()  
{  
	int result = -1 ;  
	int index ,insert_pos ;  
	assert(pEpgDbCtrl) ;  
  
	/* time_index */  
	insert_pos = GET_STINDEX_INSERT_POS(pEpgDbCtrl->playInfo.itemCount-2,  
		pEpgDbCtrl->playInfo.records[pEpgDbCtrl->playInfo.itemCount-1].playtime) ;   
	for(index=pEpgDbCtrl->playInfo.itemCount-1;index>insert_pos;index--)  
	{  
		pEpgDbCtrl->playInfo.timeIndex[index] = pEpgDbCtrl->playInfo.timeIndex[index-1] ;  
	}  
	pEpgDbCtrl->playInfo.timeIndex[insert_pos] = pEpgDbCtrl->playInfo.itemCount-1 ;  
  
	/* tv_index */  
	insert_pos = GET_TVINDEX_INSERT_POS(pEpgDbCtrl->playInfo.itemCount-2,  
		pEpgDbCtrl->playInfo.records[pEpgDbCtrl->playInfo.itemCount-1].tvid) ;   
	for(index=pEpgDbCtrl->playInfo.itemCount-1;index>insert_pos;index--)  
	{  
		pEpgDbCtrl->playInfo.tvIndex[index] = pEpgDbCtrl->playInfo.tvIndex[index-1] ;  
	}  
	pEpgDbCtrl->playInfo.tvIndex[insert_pos] = pEpgDbCtrl->playInfo.itemCount - 1 ;  
  
	result = 0 ;  
  
	return result ;  
}  
  
/* 获得UTC时间,是用从UTC 1/1/70到当前时间的秒数表示 */  
static UINT32 get_utc_time(UINT32 mjd_time_1, UINT32 mjd_time_0)  
{  
	UINT16	MJD ;  
	struct tm utc_time ;  
	int		y,m,k ;  
	  
	/* 0~7 bits */  
	utc_time.tm_sec = (0x0f & (UINT8)(mjd_time_0>>4))*0x0a + (UINT8)(0x0f & mjd_time_0) ;  
	/* 8~15 bits */  
	utc_time.tm_min = (0x0f & (UINT8)(mjd_time_0>>12))*0x0a + (UINT8)(0x0f & (mjd_time_0>>8)) ;  
	/* 16~23 bits */  
	utc_time.tm_hour = (0x0f & (UINT8)(mjd_time_0>>20))*0x0a + (0x0f & (UINT8)(mjd_time_0>>16)) ;  
  
	MJD = (UINT16)(0xffff & ( (((UINT16)(0xff & mjd_time_1))<<8) | (UINT16)(mjd_time_0>>24) ) ) ;  
  
	/* 转换为int类型时,直接丢弃小数部分 */  
	y = (int)((MJD-15078.2)/365.25) ;  
	m = (int)((MJD-14956.1-(int)(y*365.25))/30.6001) ;  
	utc_time.tm_mday = (int)(MJD-14956-(int)(y*365.25)-(int)(m*30.60001)) ;  
  
	k = ((m==14)||(m==15))?1:0 ;  
	utc_time.tm_year = y + k ;  
	utc_time.tm_mon = m - 1 - k*12 ;  
  
	utc_time.tm_isdst = 0 ;  
  
	return mktime(&utc_time) ;  
}  
  
  
static int pack(void)  
{  
	int		result = -1 ;  
	int		index, count, name_usedCount = 0, text_usedCount = 0 ;  
	char 	*pnameField = NULL, *ptextField = NULL ;  
	int		playInfoCount = 0,	programInfoCount = 0 ;  
  
	if(pEpgDbCtrl  
		|| (pEpgDbCtrl->playInfo.itemCount <= 0  
			&& pEpgDbCtrl->programInfo.itemCount <= 0)  
		)  
		goto done ;  
		  
	/* 如有必要,先申请两块内存 */  
	if (pEpgDbCtrl->playInfo.records  
		&& pEpgDbCtrl->textField.head  
		&& pEpgDbCtrl->textField.usedCount > 0  
		)  
	{  
		ptextField = (char *) GetMemory((UINT32)pEpgDbCtrl->textField.usedCount) ;  
		if (ptextField == NULL)  
			goto done ;  
	}  
	if (pEpgDbCtrl->programInfo.records  
		&& pEpgDbCtrl->nameField.head  
		&& pEpgDbCtrl->nameField.usedCount > 0  
		)  
	{  
		pnameField = (char *) GetMemory((UINT32)pEpgDbCtrl->nameField.usedCount) ;  
		if (pnameField == NULL)  
			goto done ;  
	}  
	  
	/* playInfo表整理 */  
	if( pEpgDbCtrl->playInfo.records  
		&& pEpgDbCtrl->playInfo.itemCount > 0  
		&& (pEpgDbCtrl->textField.usedCount <= 0  
			|| ptextField  
			)  
		)  
	{  
		for(count=0,index=0;indexplayInfo.itemCount;index++)  
		{  
			/* 查找有删除标志的记录 */  
			if( pEpgDbCtrl->playInfo.flagArray[index] == STATUS_DELETED )  
			{  
				continue ;	  
			}  
			/* 是否要移动记录? */  
			if (index > count)  
			{  
				memcpy(&(pEpgDbCtrl->playInfo.records[count]), &(pEpgDbCtrl->playInfo.records[index]), sizeof(EPGRECORD)) ;  
				pEpgDbCtrl->playInfo.flagArray[count] = pEpgDbCtrl->playInfo.flagArray[index] ;  
			}  
			/* 节目描述处理 */  
			if (pEpgDbCtrl->playInfo.records[count].infoindex != (char *)(-1))  
			{  
				int nn = strlen(pEpgDbCtrl->textField.head+(int)pEpgDbCtrl->playInfo.records[count].infoindex) ;  
				  
				if (nn > 0)  
				{  
					pEpgDbCtrl->playInfo.records[count].infoindex = (char *)text_usedCount ;  
					memcpy(ptextField+text_usedCount,  
							pEpgDbCtrl->textField.head+(int)pEpgDbCtrl->playInfo.records[count].infoindex,  
							nn+1) ;  
					text_usedCount += (nn+1) ;  
				}  
				else  
				{  
					/* 空串与没有描述作相同处理 */  
					pEpgDbCtrl->playInfo.records[count].infoindex = (char *)(-1) ;  
				}  
			}  
			count++ ;  
		}  
		playInfoCount = count ;  
		/* 有删除记录,需要重建立索引 */  
		if (pEpgDbCtrl->playInfo.itemCount > playInfoCount)  
		{  
			FreeMemory(pEpgDbCtrl->textField.head) ;  
			pEpgDbCtrl->textField.head = ptextField ;  
			pEpgDbCtrl->playInfo.itemCount = playInfoCount ;  
			pEpgDbCtrl->textField.usedCount = text_usedCount ;  
			ptextField = NULL ;  
			reindexall() ;  
		}  
		/* 数据可能被整理过,但不需对其进行重建立索引 */  
		else  
		{  
			FreeMemory(pEpgDbCtrl->textField.head) ;  
			pEpgDbCtrl->textField.head = ptextField ;  
			pEpgDbCtrl->playInfo.itemCount = playInfoCount ;  
			pEpgDbCtrl->textField.usedCount = text_usedCount ;  
			ptextField = NULL ;  
		}  
	}  
	  
	/* playInfo表整理 */  
	if( pEpgDbCtrl->programInfo.records  
		&& pEpgDbCtrl->programInfo.itemCount > 0  
		&& (pEpgDbCtrl->nameField.usedCount <= 0  
			|| pnameField  
			)  
		)  
	{  
		for(count=0,index=0;indexprogramInfo.itemCount;index++)  
		{  
			/* 查找有删除标志的记录 */  
			if( pEpgDbCtrl->programInfo.flagArray[index] == STATUS_DELETED )  
			{  
				continue ;	  
			}  
			/* 是否要移动记录? */  
			if (index > count)  
			{  
				memcpy(&(pEpgDbCtrl->programInfo.records[count]), &(pEpgDbCtrl->programInfo.records[index]), sizeof(PROGRAMRECORD)) ;  
				pEpgDbCtrl->programInfo.flagArray[count] = pEpgDbCtrl->programInfo.flagArray[index] ;  
			}  
			/* 节目名处理 */  
			if (pEpgDbCtrl->programInfo.records[count].name != (char *)(-1))  
			{  
				int nn = strlen(pEpgDbCtrl->nameField.head+(int)pEpgDbCtrl->programInfo.records[count].name) ;  
				  
				if (nn > 0)  
				{  
					pEpgDbCtrl->programInfo.records[count].name = (char *)name_usedCount ;  
					memcpy(pnameField+name_usedCount,  
							pEpgDbCtrl->nameField.head+(int)pEpgDbCtrl->programInfo.records[count].name,  
							nn+1) ;  
					name_usedCount += (nn+1) ;  
				}  
				else  
				{  
					/* 空串与没有节目名作相同处理 */  
					pEpgDbCtrl->programInfo.records[count].name = (char *)(-1) ;  
				}  
			}  
			count++ ;  
		}  
		/* 此表无相关索引 */  
		programInfoCount = count ;  
		FreeMemory(pEpgDbCtrl->nameField.head) ;  
		pEpgDbCtrl->nameField.head = pnameField ;  
		pEpgDbCtrl->programInfo.itemCount = programInfoCount ;  
		pEpgDbCtrl->nameField.usedCount = name_usedCount ;  
		pnameField = NULL ;  
	}  
	  
	result = 0 ;  
	  
done:  
	if (pnameField) free(pnameField) ;  
	if (ptextField) free(ptextField) ;  
	return (result) ;  
}  
  
#if 0  
/*  
 * 对所有的数据进行整理,从内存里清除打上了“删除标记”的项,在该函数同时加上对索引表的操作   
 * 因为这个时候的索引表都是有序的,比用reindexall的操作时间要少很多  
 */  
static int pack(void)  
{  
	int result = -1 ;  
	INT32	index, count, count2,del_num ;  
	INT32	name_usedCount = 0, text_usedCount = 0 ;  
	INT32	*delProgram = NULL, *delPlay = NULL ;  
  
	assert(pEpgDbCtrl) ;  
	if( !pEpgDbCtrl )  
		goto done ;  
  
	/*  
	 *说明:最后才处理playInfo,因为在programInfo中,打上了“删除标记”的项的个数不能确定,只有将在全  
	 *	部数据项遍历一遍之后才能确定  
	 */  
  
	/*  
	 *	先作programInfo的保存  
	 *因为在playInfo可能通过programid对应programInfo中的项,在保存playInfo之前应对programInfo的删除项  
	 *情况作个统计  
	 */  
  
	/* -- 数据整理 -- */  
  
	if( pEpgDbCtrl->programInfo.records )  
	{  
		delProgram = GetMemory(sizeof(INT32)*pEpgDbCtrl->programInfo.itemCount) ;  
		memset(delProgram,0x0,sizeof(INT32)*pEpgDbCtrl->programInfo.itemCount) ;  
  
		for(del_num=0,count=0,index=0;indexprogramInfo.itemCount;index++)  
		{  
			if( pEpgDbCtrl->programInfo.flagArray[index] == STATUS_DELETED )  
			{  
				delProgram[index] = del_num ;  
				del_num ++ ;   
				continue ;  
			}  
			/* ELSE  =>  DELETED, should be moved */  
  
			if( count == index )  
			{  
				name_usedCount += (INT32)pEpgDbCtrl->programInfo.records[count].name ;  
				text_usedCount += (INT32)pEpgDbCtrl->playInfo.records[count].infoindex ;  
				continue ;  
			}  
  
			memcpy(pEpgDbCtrl->programInfo.records+count,  
				pEpgDbCtrl->programInfo.records+index,  
				sizeof(PROGRAMRECORD)) ;  
  
			/* 修改指向nameField的索引号 */  
			if( pEpgDbCtrl->programInfo.records[index].name != (char *)-1 )  
			{  
				strcpy(pEpgDbCtrl->nameField.head+name_usedCount,  
					pEpgDbCtrl->nameField.head+(int)pEpgDbCtrl->programInfo.records[index].name  
					) ;  
				pEpgDbCtrl->programInfo.records[count].name = (char *)name_usedCount ;  
				name_usedCount +=   
					(1 + strlen(pEpgDbCtrl->nameField.head+(int)pEpgDbCtrl->programInfo.records[index].name) ) ;  
			}  
			else  
				pEpgDbCtrl->programInfo.records[count].name = (char *)-1 ;  
  
			delProgram[index] = del_num ;  
			  
			count ++ ;  
		}  
/* 删除项移动之后,数组后面空出来的空间,在此处不进行memset 0,不知是否会有问题? */  
		pEpgDbCtrl->programInfo.itemCount = count + 1 ;  
  
	}  
  
	/* playInfo的整理 */  
	if( pEpgDbCtrl->playInfo.records )  
	{  
		delPlay = GetMemory(sizeof(INT32)*pEpgDbCtrl->playInfo.itemCount) ;  
		memset(delPlay,0x0,sizeof(INT32)*pEpgDbCtrl->playInfo.itemCount) ;  
		  
		for(del_num=0,count=0,index=0;indexplayInfo.itemCount;index++)  
		{  
			if( pEpgDbCtrl->playInfo.flagArray[index] == STATUS_DELETED )  
			{  
				delPlay[index] = del_num ;  
				del_num ++ ;  
				continue ;  
			}  
  
			/* ELSE =>  DELETED: should be moved */  
			if( count == index )  
				continue ;  
  
			memcpy(pEpgDbCtrl->playInfo.records+count,  
				pEpgDbCtrl->playInfo.records+index,  
				sizeof(EPGRECORD) ) ;  
  
/* (outdate) 做法有待商讨 -------------- 如果节目表中的项被删除了,则与要删除掉播放表中的项 */  
/* 现在的做法是直接在pEpgDbCtrl中进行操作,改动了programInfo,在此要删除相应的播放表项有困难 */  
/*			if( pEpgDbCtrl->programInfo.flagArray[p->playInfo.records[count].programid] != STATUS_DELETED )  
			{  
				p->playInfo.records[count].programid = (UINT16)  
					(pEpgDbCtrl->playInfo.records[count].programid - (UINT16)delProgram[pEpgDbCtrl->playInfo.records[count].programid] ) ;  
			}  
			else  
				continue ;  
*/  
			/* 修改指向textField的索引号 */  
			if( pEpgDbCtrl->playInfo.records[index].infoindex != (char *)-1 )  
			{  
				strcpy(pEpgDbCtrl->textField.head + text_usedCount,  
					pEpgDbCtrl->textField.head + (int)pEpgDbCtrl->playInfo.records[index].infoindex  
					) ;  
				pEpgDbCtrl->playInfo.records[count].infoindex = (char *)text_usedCount ;  
				text_usedCount +=  
					(1 + strlen(pEpgDbCtrl->textField.head+(int)pEpgDbCtrl->playInfo.records[index].infoindex) ) ;  
			}  
			else  
				pEpgDbCtrl->playInfo.records[count].infoindex = (char *)-1 ;  
				  
			delPlay[index] = del_num ;  
			count ++ ;  
		}  
		pEpgDbCtrl->playInfo.itemCount = count + 1 ;  
  
		/* 在对playInfo的数据整理完成之后,再来进行索引表的整理 */  
		for(count=0,count2=0,index=0;indexplayInfo.itemCount;index++)  
		{				  
			/* timeIndex */  
			if( pEpgDbCtrl->playInfo.flagArray[pEpgDbCtrl->playInfo.timeIndex[index]] != STATUS_DELETED )  
			{  
				pEpgDbCtrl->playInfo.timeIndex[count] =   
					pEpgDbCtrl->playInfo.timeIndex[index] - delPlay[pEpgDbCtrl->playInfo.timeIndex[index]] ;  
				count ++ ;  
			}  
			/* tvIndex */  
			if( pEpgDbCtrl->playInfo.flagArray[pEpgDbCtrl->playInfo.tvIndex[index]] != STATUS_DELETED )  
			{  
				pEpgDbCtrl->playInfo.tvIndex[count] =   
					pEpgDbCtrl->playInfo.tvIndex[index] - delPlay[pEpgDbCtrl->playInfo.tvIndex[index]] ;  
				count2 ++ ;  
			}  
		}  
	}  
  
	/* 释放临时处理的内存 */  
	if( delProgram )  
		FreeMemory(delProgram) ;  
	if( delPlay )  
		FreeMemory(delPlay) ;  
   
	result = 0 ;  
done:  
	return result ;  
}  
#endif  
  
/* 将内存中的数据写入到磁盘文件中 */  
static int write_to_disk(UINT8 b_Packed)  
{  
	int	result = -1 ;  
	INT32	index ,count ;  
	INT8	bNameField = 0, bTextField = 0 ;  
	INT32	name_usedCount = 0, text_usedCount = 0 ;  
	FILE	*f_epgdb = NULL, *f0_playinfo = NULL , *f1_programinfo = NULL, *f2_name = NULL, *f3_text = NULL ;  
	EpgDbCtrl_t	*p_ctrl = NULL ;  
  
	if( !pEpgDbCtrl  
		)  
	{  
		fprintf(stderr,"\nERROR: Can't do any operations before initial!\n") ;  
		goto done ;  
	}  
  
	/*f_epgdb = fopen(GET_EPGDB_SAVE_PATH(epgdb.db),"w+b") ;  
	f0_playinfo = fopen(GET_EPGDB_SAVE_PATH(epgdb0.db),"w+b") ;  
	f1_programinfo = fopen(GET_EPGDB_SAVE_PATH(epgdb1.db),"w+b") ;  
	f2_name = fopen(GET_EPGDB_SAVE_PATH(epgdb2.db),"w+b") ;  
	f3_text = fopen(GET_EPGDB_SAVE_PATH(epgdb3.db),"w+b") ;  
	if( !f_epgdb  
		|| !f0_playinfo  
		|| !f1_programinfo  
		|| !f2_name  
		|| !f3_text  
		)  
	{  
		fprintf(stderr,"Error: fopen() failed! \nCan't Open EPGDataBase!\n") ;  
		goto done ;  
	}*/  
	  
	p_ctrl = GetMemory(sizeof(EpgDbCtrl_t)) ;  
	memset(p_ctrl,0x0,sizeof(EpgDbCtrl_t)) ;  
  
	/* 已经整理好的数据 */  
	if(b_Packed)  
	{  
		f2_name = fopen(GET_EPGDB_SAVE_PATH(epgdb2.db),"w+b") ;  
		if( pEpgDbCtrl->nameField.head )  
		{	  
			if(f2_name)  
			{  
				fwrite(pEpgDbCtrl->nameField.head,sizeof(INT8),pEpgDbCtrl->nameField.usedCount,f2_name) ;  
				fclose(f2_name);  
				f2_name = NULL;  
			}  
			p_ctrl->nameField.allocCount = pEpgDbCtrl->nameField.usedCount ;  
			p_ctrl->nameField.usedCount = pEpgDbCtrl->nameField.usedCount ;  
		}  
		else  
		{  
			fclose(f2_name);  
			f2_name = NULL;  
		}  
		/* ELSE set 0 */  
  
		f3_text = fopen(GET_EPGDB_SAVE_PATH(epgdb3.db),"w+b") ;  
		if( pEpgDbCtrl->textField.head )  
		{  
			  
			if(f3_text)  
			{  
				fwrite(pEpgDbCtrl->textField.head,sizeof(INT8),pEpgDbCtrl->textField.usedCount,f3_text) ;  
				fclose(f3_text);  
				f3_text = NULL;  
			}  
			p_ctrl->textField.allocCount = pEpgDbCtrl->textField.usedCount ;  
			p_ctrl->textField.usedCount = pEpgDbCtrl->textField.usedCount ;  
		}  
		else  
		{  
			fclose(f3_text);  
			f3_text = NULL;  
		}  
		/* ELSE set 0 */  
  
		f1_programinfo = fopen(GET_EPGDB_SAVE_PATH(epgdb1.db),"w+b") ;  
		if( pEpgDbCtrl->programInfo.records )  
		{  
			  
			if(f1_programinfo)  
			{  
				fwrite(pEpgDbCtrl->programInfo.records,sizeof(PROGRAMRECORD),pEpgDbCtrl->programInfo.itemCount,f1_programinfo) ;  
				fclose(f1_programinfo);  
				f1_programinfo = NULL;  
			}  
			p_ctrl->programInfo.allocCount = pEpgDbCtrl->programInfo.itemCount ;  
			p_ctrl->programInfo.itemCount = pEpgDbCtrl->programInfo.itemCount ;  
		}  
		else  
		{  
			fclose(f1_programinfo);  
			f1_programinfo = NULL;  
		}  
		/* ELSE set to 0 */  
		  
		f0_playinfo = fopen(GET_EPGDB_SAVE_PATH(epgdb0.db),"w+b") ;  
		if( pEpgDbCtrl->playInfo.records )  
		{  
			if(f0_playinfo)  
			{  
				fwrite(pEpgDbCtrl->playInfo.records,sizeof(EPGRECORD),pEpgDbCtrl->playInfo.itemCount,f0_playinfo) ;  
				fclose(f0_playinfo);  
				f0_playinfo = NULL;  
			}  
			p_ctrl->playInfo.allocCount = pEpgDbCtrl->playInfo.itemCount ;  
			p_ctrl->playInfo.itemCount = pEpgDbCtrl->playInfo.itemCount ;  
		}  
		else  
		{  
			fclose(f0_playinfo);  
			f0_playinfo = NULL;  
		}  
		  
		f_epgdb = fopen(GET_EPGDB_SAVE_PATH(epgdb.db),"w+b") ;  
		if(f_epgdb)  
		{  
			fwrite(p_ctrl,sizeof(EpgDbCtrl_t),1,f_epgdb) ;  
			fclose(f_epgdb);  
			f_epgdb = NULL;  
		}  
	}  
	else  /* 之前未整理的数据 */  
	{  
		if( pEpgDbCtrl->nameField.head )  
			bNameField = 1 ;  
		if( pEpgDbCtrl->textField.head )  
			bTextField = 1 ;  
  
		if( pEpgDbCtrl->programInfo.records )  
		{  
			/* 数据被更新时name'指针'有可能会变动 */  
			PROGRAMRECORD record ;  
			  
			for(count=0,index=0;indexprogramInfo.itemCount;index++)  
			{  
				if( pEpgDbCtrl->programInfo.flagArray[index] == STATUS_DELETED )  
					continue ;  
  
				/* programInfo */  
				memcpy(&record, pEpgDbCtrl->programInfo.records+index, sizeof(PROGRAMRECORD));  
				if ((int)record.name != -1)  
					record.name = (char *)name_usedCount ;  
				fwrite(&record,sizeof(PROGRAMRECORD),1,f1_programinfo) ;  
  
				/* name */  
				if( bNameField )  
				{  
					int nn = strlen(pEpgDbCtrl->nameField.head+(int)pEpgDbCtrl->programInfo.records[index].name) + 1 ;  
					  
					fwrite(pEpgDbCtrl->nameField.head+(int)pEpgDbCtrl->programInfo.records[index].name,  
					1,  
					nn,  
					f2_name  
					) ;  
					name_usedCount += nn ;  
				}  
  
				count ++ ;  
			}  
  
			p_ctrl->nameField.usedCount = name_usedCount ;  
			p_ctrl->nameField.allocCount = name_usedCount ;  
  
			p_ctrl->textField.usedCount = text_usedCount ;  
			p_ctrl->textField.allocCount = text_usedCount ;  
  
			p_ctrl->programInfo.itemCount = count ;  
			p_ctrl->programInfo.allocCount = count ;  
		}  
  
		if( pEpgDbCtrl->playInfo.records )  
		{  
			/* 数据被更新时infoindex'指针'有可能会变动 */  
			EPGRECORD record ;  
			  
			for(count=0,index=0;indexplayInfo.itemCount;index++)  
			{  
				if( pEpgDbCtrl->playInfo.flagArray[index] == STATUS_DELETED )  
					continue ;  
				  
				memcpy(&record, pEpgDbCtrl->playInfo.records+index, sizeof(EPGRECORD)) ;  
				if ((int)record.infoindex != -1)  
					record.infoindex = (char *)text_usedCount ;  
				fwrite(&record,sizeof(EPGRECORD),1,f0_playinfo) ;  
				  
				/* text */  
				if( bTextField )  
				{  
					int nn = strlen(pEpgDbCtrl->textField.head+(int)pEpgDbCtrl->playInfo.records[index].infoindex) + 1 ;  
					  
					fwrite(pEpgDbCtrl->textField.head+(int)pEpgDbCtrl->playInfo.records[index].infoindex,  
					sizeof(INT8),  
					nn,  
					f3_text  
					) ;  
					text_usedCount += nn ;  
				}  
  
				count ++ ;  
			}  
  
			p_ctrl->playInfo.itemCount = count ;  
			p_ctrl->playInfo.allocCount = count ;  
		}  
  
		fwrite(p_ctrl,sizeof(EpgDbCtrl_t),1,f_epgdb) ;  
	}  
  
	FreeMemory(p_ctrl) ;  
  
	result = 0 ;  
  
done:  
	if( f_epgdb )  
		fclose(f_epgdb) ;  
	if( f0_playinfo )  
		fclose(f0_playinfo) ;  
	if( f1_programinfo )  
		fclose(f1_programinfo) ;  
	if( f2_name )  
		fclose(f2_name) ;  
	if( f3_text )  
		fclose(f3_text) ;  
  
	return (result) ;  
}  
  
  
/*  
 *说明:根据内存里的数据,重建索引表。  
 *	要重建索引表,一定会有一个对数据排序的过程,最快速的方法当然是快排了  
 */  
static int _compare_time( const void *_elem1, const void *_elem2 )  
{  
	if(pEpgDbCtrl->playInfo.records[*(INT32*)_elem1].playtime   
		> pEpgDbCtrl->playInfo.records[*(INT32*)_elem2].playtime  
		)  
		return 1 ;  
	else if( pEpgDbCtrl->playInfo.records[*(INT32*)_elem1].playtime   
		== pEpgDbCtrl->playInfo.records[*(INT32*)_elem2].playtime  
		)  
	{  
		/* 若playtime相同则按tvid排序 */  
		if (pEpgDbCtrl->playInfo.records[*(INT32*)_elem1].tvid  
			> pEpgDbCtrl->playInfo.records[*(INT32*)_elem2].tvid  
			)  
			return 1 ;  
		else  
		if (pEpgDbCtrl->playInfo.records[*(INT32*)_elem1].tvid  
			== pEpgDbCtrl->playInfo.records[*(INT32*)_elem2].tvid  
			)  
			return 0 ;  
		else  
			return -1 ;  
	}  
	else  
		return -1 ;  
}  
static int _compare_tv( const void *_elem1, const void *_elem2 )  
{  
	if( pEpgDbCtrl->playInfo.records[*(INT32*)_elem1].tvid  
		> pEpgDbCtrl->playInfo.records[*(INT32*)_elem2].tvid  
		)  
		return 1 ;  
	else if( pEpgDbCtrl->playInfo.records[*(INT32*)_elem1].tvid  
		== pEpgDbCtrl->playInfo.records[*(INT32*)_elem2].tvid  
		)  
	{  
		/* 若tvid相同则按照playtime排序 */  
		if (pEpgDbCtrl->playInfo.records[*(INT32*)_elem1].playtime   
			> pEpgDbCtrl->playInfo.records[*(INT32*)_elem2].playtime  
			)  
			return 1 ;  
		else  
		if (pEpgDbCtrl->playInfo.records[*(INT32*)_elem1].playtime   
			== pEpgDbCtrl->playInfo.records[*(INT32*)_elem2].playtime  
			)  
			return 0 ;  
		else  
			return -1 ;  
	}  
	else  
		return -1 ;  
}  
  
static int reindexall()  
{  
	int result = -1 ;  
	int index ;  
  
	assert(pEpgDbCtrl) ;  
	if( pEpgDbCtrl->playInfo.itemCount == 0 )  
	{  
		result = 0 ;  
		goto done ;  
	}  
  
	memset(pEpgDbCtrl->playInfo.timeIndex,0x0,sizeof(INT32)*pEpgDbCtrl->playInfo.allocCount) ;  
	memset(pEpgDbCtrl->playInfo.tvIndex,0x0,sizeof(INT32)*pEpgDbCtrl->playInfo.allocCount) ;  
  
	/* 初始化 */  
	for(index=0;indexplayInfo.itemCount;index++)  
	{  
		pEpgDbCtrl->playInfo.timeIndex[index] = index ;  
		pEpgDbCtrl->playInfo.tvIndex[index] = index ;  
	}  
  
	qsort((void *)pEpgDbCtrl->playInfo.timeIndex,(size_t)pEpgDbCtrl->playInfo.itemCount,sizeof(INT32),_compare_time) ;  
	qsort((void *)pEpgDbCtrl->playInfo.tvIndex,(size_t)pEpgDbCtrl->playInfo.itemCount,sizeof(INT32),_compare_tv) ;  
  
	result = 0 ;  
done:  
	return result ;  
}  
  
  
/* ========================================================================= */  
/*初始化EPG数据库 */  
int InitEPGDB(void)   
{  
	int result = -1 ;  
	INT32	numread = 0 ;  
	FILE	*f_epgdb = NULL, *f0_playinfo = NULL , *f1_programinfo = NULL, *f2_name = NULL, *f3_text = NULL ;  
  
	if( pEpgDbCtrl )  
	{  
		fprintf(stderr,"Error: InitEPGDB() failed! \nEPG DB is open, You should close it first!\n") ;  
		goto done ;  
	}  
  
	pEpgDbCtrl = (EpgDbCtrl_t *) GetMemory(sizeof(EpgDbCtrl_t)) ;  
	memset(pEpgDbCtrl,0x0,sizeof(EpgDbCtrl_t)) ;  
  
	/*f_epgdb = fopen(GET_EPGDB_SAVE_PATH(epgdb.db),"rb") ;  
	f0_playinfo = fopen(GET_EPGDB_SAVE_PATH(epgdb0.db),"rb") ;  
	f1_programinfo = fopen(GET_EPGDB_SAVE_PATH(epgdb1.db),"rb") ;  
	f2_name = fopen(GET_EPGDB_SAVE_PATH(epgdb2.db),"rb") ;  
	f3_text = fopen(GET_EPGDB_SAVE_PATH(epgdb3.db),"rb") ;  
  
	if( !f_epgdb  
		|| !f0_playinfo  
		|| !f1_programinfo  
		|| !f2_name  
		|| !f3_text  
		)  
	{  
		fprintf(stdout,"NOTE: \nEPGDataBase isn't exist! Create New! \n") ;  
		goto done ;  
  
	}*/  
  
	/* 读取所有文件信息,如果中途读某文件出错,则直接舍弃读所有文件,并将pEpgDbCtrl置空 */  
	  
	f_epgdb = fopen(GET_EPGDB_SAVE_PATH(epgdb.db),"rb") ;  
	numread = 0;  
	if(f_epgdb)  
	{  
		numread = fread(pEpgDbCtrl,sizeof(EpgDbCtrl_t),1,f_epgdb) ;  
		fclose(f_epgdb);  
		f_epgdb = NULL;  
	}  
	  
	if(numread != 1)  
		goto ReadFileError ;  
	  
	pEpgDbCtrl->playInfo.allocCount =   
		(pEpgDbCtrl->playInfo.allocCount/EPGDB_CTRL_ALLOC_NUM + ((pEpgDbCtrl->playInfo.allocCount%EPGDB_CTRL_ALLOC_NUM)?1:0) )*EPGDB_CTRL_ALLOC_NUM ;  
	pEpgDbCtrl->programInfo.allocCount =   
		(pEpgDbCtrl->programInfo.allocCount/EPGDB_CTRL_ALLOC_NUM + ((pEpgDbCtrl->programInfo.allocCount%EPGDB_CTRL_ALLOC_NUM)?1:0) )*EPGDB_CTRL_ALLOC_NUM ;  
	pEpgDbCtrl->nameField.allocCount =   
		(pEpgDbCtrl->nameField.allocCount/EPGDB_CTRL_ALLOC_NUM + ((pEpgDbCtrl->nameField.allocCount%EPGDB_CTRL_ALLOC_NUM)?1:0) )*EPGDB_CTRL_ALLOC_NUM ;  
	pEpgDbCtrl->textField.allocCount =  
		(pEpgDbCtrl->textField.allocCount/EPGDB_CTRL_ALLOC_NUM + ((pEpgDbCtrl->textField.allocCount%EPGDB_CTRL_ALLOC_NUM)?1:0) )*EPGDB_CTRL_ALLOC_NUM ;  
  
	if( pEpgDbCtrl->playInfo.allocCount )  
	{  
		pEpgDbCtrl->playInfo.records = GetMemory(sizeof(EPGRECORD)*pEpgDbCtrl->playInfo.allocCount) ;  
		memset(pEpgDbCtrl->playInfo.records,0x0,sizeof(EPGRECORD)*pEpgDbCtrl->playInfo.allocCount) ;  
		f0_playinfo = fopen(GET_EPGDB_SAVE_PATH(epgdb0.db),"rb") ;  
		numread = pEpgDbCtrl->playInfo.itemCount-1;  
		if(f0_playinfo)  
		{  
		  
			numread = fread(pEpgDbCtrl->playInfo.records,sizeof(EPGRECORD),pEpgDbCtrl->playInfo.itemCount,f0_playinfo) ;  
			fclose(f0_playinfo);  
			f0_playinfo = NULL;  
		}  
		if( numread != pEpgDbCtrl->playInfo.itemCount )  
			goto ReadFileError ;  
	}  
	  
	if( pEpgDbCtrl->programInfo.allocCount )  
	{  
		pEpgDbCtrl->programInfo.records = GetMemory(sizeof(PROGRAMRECORD)*pEpgDbCtrl->programInfo.allocCount) ;  
		memset(pEpgDbCtrl->programInfo.records,0x0,sizeof(PROGRAMRECORD)*pEpgDbCtrl->programInfo.allocCount) ;  
		  
		f1_programinfo = fopen(GET_EPGDB_SAVE_PATH(epgdb1.db),"rb") ;  
		numread = pEpgDbCtrl->programInfo.itemCount-1;  
		if(f1_programinfo)  
		{  
			numread = fread(pEpgDbCtrl->programInfo.records,sizeof(PROGRAMRECORD),pEpgDbCtrl->programInfo.itemCount,f1_programinfo) ;  
			fclose(f1_programinfo);  
			f1_programinfo = NULL;  
			printf("\nIn InitEPGDB() -- read from file %d PROGRAMRECORD. \n",numread) ;  
		}  
		if( numread != pEpgDbCtrl->programInfo.itemCount )  
			goto ReadFileError ;  
	}  
	if( pEpgDbCtrl->nameField.allocCount )  
	{  
		pEpgDbCtrl->nameField.head = GetMemory(sizeof(INT8)*pEpgDbCtrl->nameField.allocCount) ;  
		memset(pEpgDbCtrl->nameField.head,0x0,sizeof(INT8)*pEpgDbCtrl->nameField.allocCount) ;  
		  
		f2_name = fopen(GET_EPGDB_SAVE_PATH(epgdb2.db),"rb") ;  
		numread = pEpgDbCtrl->nameField.usedCount-1;  
		if(f2_name)  
		{  
			numread = fread(pEpgDbCtrl->nameField.head,sizeof(INT8),pEpgDbCtrl->nameField.usedCount,f2_name) ;  
			fclose(f2_name);  
			f2_name = NULL;  
		}  
		  
		if( numread != pEpgDbCtrl->nameField.usedCount )  
			goto ReadFileError ;  
	}  
	if( pEpgDbCtrl->textField.allocCount )  
	{  
		pEpgDbCtrl->textField.head = GetMemory(sizeof(INT8)*pEpgDbCtrl->textField.allocCount) ;  
		memset(pEpgDbCtrl->textField.head,0x0,sizeof(INT8)*pEpgDbCtrl->textField.allocCount) ;  
		  
		f3_text = fopen(GET_EPGDB_SAVE_PATH(epgdb3.db),"rb") ;  
		numread = pEpgDbCtrl->textField.usedCount-1;  
		if(f3_text)  
		{  
			numread = fread(pEpgDbCtrl->textField.head,sizeof(INT8),pEpgDbCtrl->textField.usedCount,f3_text) ;  
			fclose(f3_text);  
			f3_text = NULL;  
		}  
		if( numread != pEpgDbCtrl->textField.usedCount )  
			goto ReadFileError ;  
	}  
  
	/* 整理索引表 */  
	pEpgDbCtrl->programInfo.flagArray = GetMemory(sizeof(INT8)*pEpgDbCtrl->programInfo.allocCount) ;  
	memset(pEpgDbCtrl->programInfo.flagArray,0x0,sizeof(INT8)*pEpgDbCtrl->programInfo.allocCount) ; /* 0 -- NORMAL*/  
	pEpgDbCtrl->playInfo.flagArray = GetMemory(sizeof(INT8)*pEpgDbCtrl->playInfo.allocCount) ;  
	memset(pEpgDbCtrl->playInfo.flagArray,0x0,sizeof(INT8)*pEpgDbCtrl->playInfo.allocCount) ;  /* 0 -- NORMAL*/  
  
	pEpgDbCtrl->playInfo.returnArray = GetMemory(sizeof(INT32)*pEpgDbCtrl->playInfo.allocCount) ;  
	memset(pEpgDbCtrl->playInfo.returnArray,0x0,sizeof(INT32)*pEpgDbCtrl->playInfo.allocCount) ;  
  
	pEpgDbCtrl->playInfo.timeIndex = GetMemory(sizeof(INT32)*pEpgDbCtrl->playInfo.allocCount) ;  
	pEpgDbCtrl->playInfo.tvIndex = GetMemory(sizeof(INT32)*pEpgDbCtrl->playInfo.allocCount) ;  
  
	reindexall() ;  
  
	/* add cheng */  
	{  
		int r ;  
		r = InitEPGTypeRecordDB() ;  
#ifdef __DEBUG__  
		printf("InitEPGTypeRecordDB() = %d \n", r) ;  
#endif  
	}  
	  
	  
	result = 0 ;  
	goto done ;  
  
ReadFileError:  
	if( pEpgDbCtrl->playInfo.records )  
		FreeMemory(pEpgDbCtrl->playInfo.records) ;  
	if( pEpgDbCtrl->programInfo.records )  
		FreeMemory(pEpgDbCtrl->programInfo.records) ;  
	if( pEpgDbCtrl->nameField.head )  
		FreeMemory(pEpgDbCtrl->nameField.head) ;  
	if( pEpgDbCtrl->textField.head )  
		FreeMemory(pEpgDbCtrl->textField.head) ;  
	memset(pEpgDbCtrl,0x0,sizeof(EpgDbCtrl_t)) ;  
	result = 0 ;  
done:  
	/*if( f_epgdb )  
		fclose(f_epgdb) ;  
	if( f0_playinfo )  
		fclose(f0_playinfo) ;  
	if( f1_programinfo )  
		fclose(f1_programinfo) ;  
	if( f2_name )  
		fclose(f2_name) ;  
	if( f3_text )  
		fclose(f3_text) ;  
	*/  
  
	return result ;  
}  
  
/* 关闭EPG数据库 */  
int CloseEPGDB(void)  
{  
	int result = -1 ;  
  
	if(pEpgDbCtrl)  
	{  
		if( pEpgDbCtrl->playInfo.itemCount>0  
			&& pEpgDbCtrl->playInfo.records  
			)  
		{  
			FreeMemory(pEpgDbCtrl->playInfo.records) ;  
			FreeMemory(pEpgDbCtrl->playInfo.flagArray) ;  
			FreeMemory(pEpgDbCtrl->playInfo.timeIndex) ;  
			FreeMemory(pEpgDbCtrl->playInfo.tvIndex) ;  
			FreeMemory(pEpgDbCtrl->playInfo.returnArray) ;  
		}  
  
		if( pEpgDbCtrl->programInfo.itemCount > 0  
			&& pEpgDbCtrl->programInfo.records  
			)  
		{  
			FreeMemory(pEpgDbCtrl->programInfo.records) ;  
			FreeMemory(pEpgDbCtrl->programInfo.flagArray) ;  
		}  
		  
		FreeMemory(pEpgDbCtrl->nameField.head) ;  
		FreeMemory(pEpgDbCtrl->textField.head) ;  
  
		FreeMemory(pEpgDbCtrl) ;  
		pEpgDbCtrl = NULL ;  
  
		/*add cheng */  
		CloseEPGTypeRecordDB() ;  
		  
		result = 0 ;  
	}  
  
	return result ;  
}  
  
/**  
 *  
 *    清空EPG数据库  
 *  
 **/  
int EmptyEPGDB(void)  
{  
	int ret = -1 ;  
	  
	if (pEpgDbCtrl)   
	{  
		if (pEpgDbCtrl->playInfo.itemCount > 0 && pEpgDbCtrl->playInfo.records)   
		{  
			FreeMemory(pEpgDbCtrl->playInfo.records) ;  
			FreeMemory(pEpgDbCtrl->playInfo.flagArray) ;  
			FreeMemory(pEpgDbCtrl->playInfo.timeIndex) ;  
			FreeMemory(pEpgDbCtrl->playInfo.tvIndex) ;  
			FreeMemory(pEpgDbCtrl->playInfo.returnArray) ;  
			  
			pEpgDbCtrl->playInfo.allocCount = pEpgDbCtrl->playInfo.itemCount = 0 ;  
			pEpgDbCtrl->playInfo.records = NULL ;  
			pEpgDbCtrl->playInfo.flagArray = NULL ;  
			pEpgDbCtrl->playInfo.timeIndex = NULL ;  
			pEpgDbCtrl->playInfo.tvIndex = NULL ;  
			pEpgDbCtrl->playInfo.returnArray = NULL ;  
		}  
		if (pEpgDbCtrl->programInfo.itemCount > 0 && pEpgDbCtrl->programInfo.records)   
		{  
			FreeMemory(pEpgDbCtrl->programInfo.records) ;  
			FreeMemory(pEpgDbCtrl->programInfo.flagArray) ;  
			  
			pEpgDbCtrl->programInfo.allocCount = pEpgDbCtrl->programInfo.itemCount = 0 ;  
			pEpgDbCtrl->programInfo.records = NULL ;  
			pEpgDbCtrl->programInfo.flagArray = NULL ;  
		}  
		  
		FreeMemory(pEpgDbCtrl->nameField.head) ;  
		pEpgDbCtrl->nameField.head = NULL ;  
		pEpgDbCtrl->nameField.allocCount = 0 ;  
		pEpgDbCtrl->nameField.usedCount = 0 ;  
		  
		FreeMemory(pEpgDbCtrl->textField.head) ;  
		pEpgDbCtrl->textField.head = NULL ;  
		pEpgDbCtrl->textField.allocCount = 0 ;  
		pEpgDbCtrl->textField.usedCount = 0 ;  
  
		ret = 0 ;  
	}  
	return (ret) ;  
}  
  
int AddEPGProgram(char * name,short maintype,short subtype)  
{  
	int result = -1 ;  
	PROGRAMRECORD * pProgramRecord = NULL ;  
	EPGRECORD *     pPlayRecord = NULL ;  
	INT8 *         pCharName = NULL ;  
	INT32          name_count = 0 ;  
	INT8 *         pProgramFlagArray = NULL ;  
	INT8 *         pPlayFlagArray = NULL ;  
	INT32 *        pTimeIndex = NULL ;  
	INT32 *        pTVIndex = NULL ;  
	INT32          currentItem = 0x0 ;  
  
	/* 参数合法性判断 */  
	// ...  
  
	if( !pEpgDbCtrl )  
		goto done ;  
  
	/* 判断存储空间是否足够 */  
  
	if( pEpgDbCtrl->programInfo.allocCount <= 0  
		|| pEpgDbCtrl->programInfo.itemCount >= pEpgDbCtrl->programInfo.allocCount  
		|| (name  
			&& strlen(name)+1+pEpgDbCtrl->nameField.usedCount > pEpgDbCtrl->nameField.allocCount  
			)  
		)  
	{  
		pProgramRecord = pEpgDbCtrl->programInfo.records ;  
		pEpgDbCtrl->programInfo.allocCount += EPGDB_CTRL_ALLOC_NUM ;  
  
		pEpgDbCtrl->programInfo.records =   
			(PROGRAMRECORD *) GetMemory(sizeof(PROGRAMRECORD)*pEpgDbCtrl->programInfo.allocCount) ;   
		if(pEpgDbCtrl->programInfo.records == NULL)  
			goto out_program_record ;  
  
		pProgramFlagArray = pEpgDbCtrl->programInfo.flagArray ;  
		pEpgDbCtrl->programInfo.flagArray =   
			(INT8 *) GetMemory(sizeof(UINT8)*pEpgDbCtrl->programInfo.allocCount) ;  
		if(pEpgDbCtrl->programInfo.flagArray == NULL)  
			goto out_program_flagarray ;  
  
		/* 若存储空间不够 */  
		if(name  
			&& strlen(name)+1+pEpgDbCtrl->nameField.usedCount > pEpgDbCtrl->nameField.allocCount  
			)  
		{  
/*			while(pEpgDbCtrl->nameField.usedCount+(INT32)strlen(name)+1 > pEpgDbCtrl->nameField.allocCount+name_count)  
			{  
				name_count += EPGDB_CTRL_ALLOC_NUM ;  
			}  
*/  
			name_count += ( EPGDB_CTRL_ALLOC_NUM *   
				( (strlen(name)+1)/EPGDB_CTRL_ALLOC_NUM + (((strlen(name)+1)%EPGDB_CTRL_ALLOC_NUM)?1:0) )  ) ;  
			if( name_count != 0 )  
			{  
				pCharName = pEpgDbCtrl->nameField.head ;  
				pEpgDbCtrl->nameField.allocCount += name_count ;  
				pEpgDbCtrl->nameField.head =   
					(INT8 *) GetMemory(sizeof(UINT8)*pEpgDbCtrl->nameField.allocCount) ;  
				if(pEpgDbCtrl->nameField.head == NULL)  
					goto out_namefield ;  
			}  
		}  
  
		/* 向大内存区域中复制小区域的内容 */  
		if(pProgramRecord)  
		{  
			memset(pEpgDbCtrl->programInfo.records,0x0,sizeof(PROGRAMRECORD)*pEpgDbCtrl->programInfo.allocCount) ;  
			memcpy(pEpgDbCtrl->programInfo.records,  
				pProgramRecord,  
				sizeof(PROGRAMRECORD)*pEpgDbCtrl->programInfo.itemCount  
				) ;  
			FreeMemory(pProgramRecord) ;  
  
			assert(pProgramFlagArray) ;  
			memset(pEpgDbCtrl->programInfo.flagArray,0x0,sizeof(UINT8)*pEpgDbCtrl->programInfo.allocCount) ;  
			memcpy(pEpgDbCtrl->programInfo.flagArray,  
				pProgramFlagArray,  
				sizeof(UINT8)*pEpgDbCtrl->programInfo.itemCount  
				) ;  
			FreeMemory(pProgramFlagArray) ;  
		}  
  
		if(pPlayRecord)  
		{  
			memset(pEpgDbCtrl->playInfo.records,0x0,sizeof(EPGRECORD)*pEpgDbCtrl->playInfo.allocCount) ;  
			memcpy(pEpgDbCtrl->playInfo.records,  
				pPlayRecord,  
				sizeof(EPGRECORD)*pEpgDbCtrl->playInfo.allocCount  
				) ;  
			FreeMemory(pPlayRecord) ;  
  
			assert(pPlayFlagArray) ;  
			memset(pEpgDbCtrl->playInfo.flagArray,0x0,sizeof(UINT8)*pEpgDbCtrl->playInfo.allocCount) ;  
			memcpy(pEpgDbCtrl->playInfo.flagArray,  
				pPlayFlagArray,  
				sizeof(UINT8)*pEpgDbCtrl->playInfo.itemCount  
				) ;  
			FreeMemory(pPlayFlagArray) ;  
  
			assert(pTimeIndex) ;  
			memset(pEpgDbCtrl->playInfo.timeIndex,0x0,sizeof(UINT32)*pEpgDbCtrl->playInfo.allocCount) ;  
			memcpy(pEpgDbCtrl->playInfo.timeIndex,  
				pTimeIndex,  
				sizeof(UINT32)*pEpgDbCtrl->playInfo.itemCount  
				) ;  
			FreeMemory(pTimeIndex) ;  
  
			assert(pTVIndex) ;  
			memset(pEpgDbCtrl->playInfo.tvIndex,0x0,sizeof(UINT32)*pEpgDbCtrl->playInfo.allocCount) ;  
			memcpy(pEpgDbCtrl->playInfo.tvIndex,  
				pTVIndex,  
				sizeof(UINT32)*pEpgDbCtrl->playInfo.itemCount  
				) ;  
			FreeMemory(pTVIndex) ;  
		}  
  
		if(pCharName)  
		{  
			memset(pEpgDbCtrl->nameField.head,0x0,sizeof(UINT8)*pEpgDbCtrl->nameField.allocCount) ;  
			memcpy(pEpgDbCtrl->nameField.head,pCharName,sizeof(UINT8)*pEpgDbCtrl->nameField.usedCount) ;  
			FreeMemory(pCharName) ;  
		}  
	}  
  
  
	/* -------- 以下开始进行ADD操作 -------- */  
  
	currentItem = pEpgDbCtrl->programInfo.itemCount ;  
	pEpgDbCtrl->programInfo.itemCount ++ ;  
  
	pEpgDbCtrl->programInfo.records[currentItem].programid = currentItem ;  
	pEpgDbCtrl->programInfo.records[currentItem].maintype = maintype ;  
	pEpgDbCtrl->programInfo.records[currentItem].subtype  = subtype  ;  
  
	if(name)  
	{  
		pEpgDbCtrl->programInfo.records[currentItem].name = (char *)pEpgDbCtrl->nameField.usedCount ;  
		strcpy(pEpgDbCtrl->nameField.head+pEpgDbCtrl->nameField.usedCount,name) ;  
		pEpgDbCtrl->nameField.usedCount += (strlen(name)+1) ;  
	}  
	else  
		pEpgDbCtrl->programInfo.records[currentItem].name = (char *)-1 ;  
  
	pEpgDbCtrl->programInfo.flagArray[currentItem] = STATUS_NORMAL ;  
  
	return currentItem+1 ;  
  
/* 异常退出前,进行的一些错误处理 */  
  
out_namefield:  
	pEpgDbCtrl->nameField.head = pCharName ;  
	pEpgDbCtrl->nameField.allocCount -= name_count ;  
	FreeMemory(pEpgDbCtrl->programInfo.flagArray) ;  
  
out_program_flagarray:  
	pEpgDbCtrl->programInfo.flagArray = pProgramFlagArray ;  
	FreeMemory(pEpgDbCtrl->programInfo.records) ;  
out_program_record:  
	pEpgDbCtrl->programInfo.records = pProgramRecord ;  
	pEpgDbCtrl->programInfo.allocCount -= EPGDB_CTRL_ALLOC_NUM ;  
  
done:  
	return result ;  
}  
  
/* 删除节目表中节目,programid:节目表中的索引 */  
void DelEPGProgram(int programid)  
{  
	if (pEpgDbCtrl && pEpgDbCtrl->programInfo.itemCount > 0)  
	{  
		if( programid > 0  
			&& programid <= (int)pEpgDbCtrl->programInfo.itemCount  
			)  
			pEpgDbCtrl->programInfo.flagArray[programid-1] = (INT8)STATUS_DELETED ;   
	}  
}  
  
/* 修改EPG节目信息表,programid:节目表中的索引 */  
int ModifyEPGProgram(int programid,char * name,short maintype,short subtype)  
{  
	int result = -1 ;  
	INT8 *  pChar = NULL ;  
  
	if(!pEpgDbCtrl  
			|| !pEpgDbCtrl->programInfo.records  
		)  
		goto done ;  
  
	/* 参数合法性判断 */  
	if(programid <= 0  
		|| programid > (int)pEpgDbCtrl->programInfo.itemCount  
		)  
		goto done ;  
  
	pEpgDbCtrl->programInfo.records[ProgId2ProgIndex(programid)].maintype = maintype ;  
	pEpgDbCtrl->programInfo.records[ProgId2ProgIndex(programid)].subtype  = subtype  ;  
	  
	if( !name )  
	{  
		result = 0 ;  
		goto done ;  
	}  
  
	/* 直接放弃保存节目名的内存区域中,对原来的不作修改 */  
  
	if( pEpgDbCtrl->nameField.usedCount+(INT32)strlen(name)+1 > pEpgDbCtrl->nameField.allocCount)  
	{  
		pChar = pEpgDbCtrl->nameField.head ;  
		pEpgDbCtrl->nameField.allocCount += ( EPGDB_CTRL_ALLOC_NUM *  
			( (strlen(name)+1)/EPGDB_CTRL_ALLOC_NUM + (((strlen(name)+1)%EPGDB_CTRL_ALLOC_NUM)?1:0) )  );  
		pEpgDbCtrl->nameField.head = (INT8 *)GetMemory(sizeof(UINT8)*pEpgDbCtrl->nameField.allocCount) ;  
		if(pEpgDbCtrl->nameField.head == NULL)  
		{  
			pEpgDbCtrl->nameField.head = pChar ;  
			pEpgDbCtrl->nameField.allocCount -= ( EPGDB_CTRL_ALLOC_NUM *   
				( (strlen(name)+1)/EPGDB_CTRL_ALLOC_NUM + (((strlen(name)+1)%EPGDB_CTRL_ALLOC_NUM)?1:0) )  );  
			goto done ;  
		}  
  
		memset(pEpgDbCtrl->nameField.head,0x0,sizeof(UINT8)*pEpgDbCtrl->nameField.allocCount ) ;  
		memcpy(pEpgDbCtrl->nameField.head,pChar,sizeof(UINT8)*pEpgDbCtrl->nameField.usedCount) ;  
		FreeMemory(pChar) ;  
	}  
  
	/* 添加到未尾部,原来的name被废除 */  
	strcpy(pEpgDbCtrl->nameField.head+(INT32)pEpgDbCtrl->nameField.usedCount,name) ;  
	pEpgDbCtrl->programInfo.records[ProgId2ProgIndex(programid)].name = (char*)pEpgDbCtrl->nameField.usedCount;  
	pEpgDbCtrl->nameField.usedCount += (strlen(name)+1) ;  
  
	result = 0 ;  
  
done:  
	return result ;  
}  
  
/* 增加EPG播放节目信息,programid:节目表中的索引,返回在播放表中的索引 */  
int AddEPGPlay(int programid,int tvid,time_t starttime,int conttime,char * info)  
{  
	int result = -1 ;  
	int currentItem ;  
	EPGRECORD       * pEpgRecord = NULL ;  
	INT8			* pFlagArray = NULL ;  
	INT32	* pTimeIndex = NULL ;  
	INT32	* pTVIndex = NULL ;  
	INT32  * pReturnArray = NULL ;  
	INT8	*pCharText = NULL ;  
	INT32	text_count = 0 ;  
  
	if( !pEpgDbCtrl  
			|| !pEpgDbCtrl->playInfo.records  
		)  
		goto done ;  
  
	/* 参数合法性判断 */  
	if (programid <= 0  
		|| tvid <= 0  
		|| starttime <= 0  
		)  
		goto done ;  
  
	/* 空间大小判断 */  
	if(pEpgDbCtrl->playInfo.allocCount <= 0  
		|| pEpgDbCtrl->playInfo.itemCount >= pEpgDbCtrl->playInfo.allocCount  
		)  
	{  
		pEpgRecord = pEpgDbCtrl->playInfo.records ;  
		pEpgDbCtrl->playInfo.allocCount += EPGDB_CTRL_ALLOC_NUM ;  
  
		pEpgDbCtrl->playInfo.records = (EPGRECORD*)GetMemory(sizeof(EPGRECORD)*pEpgDbCtrl->playInfo.allocCount) ;  
		if(pEpgDbCtrl->playInfo.records == NULL)  
			goto out_record ;  
  
		pFlagArray = pEpgDbCtrl->playInfo.flagArray ;  
		pEpgDbCtrl->playInfo.flagArray = (INT8 *)GetMemory(sizeof(UINT8)*pEpgDbCtrl->playInfo.allocCount) ;  
		if(pEpgDbCtrl->playInfo.flagArray == NULL)  
			goto out_flagarray ;  
  
		pTimeIndex = pEpgDbCtrl->playInfo.timeIndex ;  
		pEpgDbCtrl->playInfo.timeIndex = (INT32 *) GetMemory(sizeof(UINT32)*pEpgDbCtrl->playInfo.allocCount) ;  
		if(pEpgDbCtrl->playInfo.timeIndex == NULL)  
			goto out_timeindex ;  
  
		pTVIndex = pEpgDbCtrl->playInfo.tvIndex ;  
		pEpgDbCtrl->playInfo.tvIndex = (INT32 *) GetMemory(sizeof(UINT32)*pEpgDbCtrl->playInfo.allocCount) ;  
		if(pEpgDbCtrl->playInfo.tvIndex == NULL)  
			goto out_tvindex ;  
  
		pReturnArray = pEpgDbCtrl->playInfo.returnArray ;  
		pEpgDbCtrl->playInfo.returnArray = (INT32 *) GetMemory(sizeof(UINT32)*pEpgDbCtrl->playInfo.allocCount) ;  
		if(pEpgDbCtrl->playInfo.returnArray == NULL)  
			goto out_returnarray ;  
  
		/* 若内存不够 */  
		if(info  
			&& strlen(info)+1+pEpgDbCtrl->textField.usedCount > pEpgDbCtrl->textField.allocCount  
			)  
		{  
/*			while(pEpgDbCtrl->textField.usedCount+(INT32)strlen(info)+1 > pEpgDbCtrl->textField.allocCount+text_count)  
			{  
				text_count += EPGDB_CTRL_ALLOC_NUM ;  
			}  
*/  
			text_count += ( EPGDB_CTRL_ALLOC_NUM *   
				( (strlen(info)+1)/EPGDB_CTRL_ALLOC_NUM + (((strlen(info)+1)%EPGDB_CTRL_ALLOC_NUM)?1:0) )  ) ;  
			if( text_count != 0 )  
			{  
				pCharText = pEpgDbCtrl->textField.head ;  
				pEpgDbCtrl->textField.allocCount += text_count ;  
				pEpgDbCtrl->textField.head =   
					(INT8 *) GetMemory(sizeof(UINT8)*pEpgDbCtrl->textField.allocCount) ;  
				if(pEpgDbCtrl->textField.head == NULL)  
					goto out_textfiled ;  
			}  
		}  
		  
		/* 申请空间成功,复制原来各值 */  
		if(pEpgRecord)  
		{  
			memset(pEpgDbCtrl->playInfo.records,0x0,sizeof(EPGRECORD)*pEpgDbCtrl->playInfo.allocCount) ;  
			memcpy(pEpgDbCtrl->playInfo.records,pEpgRecord,sizeof(EPGRECORD)*pEpgDbCtrl->playInfo.itemCount) ;  
			FreeMemory(pEpgRecord) ;  
		}  
  
		if(pFlagArray)  
		{  
			memset(pEpgDbCtrl->playInfo.flagArray,0x0,sizeof(UINT8)*pEpgDbCtrl->playInfo.allocCount) ;  
			memcpy(pEpgDbCtrl->playInfo.flagArray,pFlagArray,sizeof(UINT8)*pEpgDbCtrl->playInfo.itemCount) ;  
			FreeMemory(pFlagArray) ;  
		}  
		  
		if(pTimeIndex)  
		{  
			memset(pEpgDbCtrl->playInfo.timeIndex,0x0,sizeof(UINT32)*pEpgDbCtrl->playInfo.allocCount) ;  
			memcpy(pEpgDbCtrl->playInfo.timeIndex,pTimeIndex,sizeof(UINT32)*pEpgDbCtrl->playInfo.itemCount) ;  
			FreeMemory(pTimeIndex) ;  
		}  
  
		if(pTVIndex)  
		{  
			memset(pEpgDbCtrl->playInfo.tvIndex,0x0,sizeof(UINT32)*pEpgDbCtrl->playInfo.allocCount) ;  
			memcpy(pEpgDbCtrl->playInfo.tvIndex,pTVIndex,sizeof(UINT32)*pEpgDbCtrl->playInfo.itemCount) ;  
			FreeMemory(pTVIndex) ;  
		}  
  
		if(pReturnArray)  
		{  
			memset(pEpgDbCtrl->playInfo.returnArray,0x0,sizeof(UINT32)*pEpgDbCtrl->playInfo.allocCount) ;  
			memcpy(pEpgDbCtrl->playInfo.returnArray,pReturnArray,sizeof(UINT32)*pEpgDbCtrl->playInfo.itemCount) ;  
			FreeMemory(pReturnArray) ;  
		}  
		if(pCharText)  
		{  
			memset(pEpgDbCtrl->textField.head,0x0,sizeof(UINT8)*pEpgDbCtrl->textField.allocCount) ;  
			memcpy(pEpgDbCtrl->textField.head,pCharText,sizeof(UINT8)*pEpgDbCtrl->textField.usedCount) ;  
			FreeMemory(pCharText) ;  
		}  
	}  
  
	/* 以下开始进行ADD_操作,如果索引表项数大于0,则还需根据索引表判断重复项 */  
//*	  
	/* 此处的重复判断是调用FilterEPGDB实现的,可能会有速度的问题,可能还需改动代码 */  
	if( pEpgDbCtrl->playInfo.itemCount > 0   
		&& FilterEPGDB(starttime,starttime,tvid,0,0,0,NULL,NULL,NULL) > 0 )  
	{  
		result = 0 ;  
		goto done ;  
	}  
//*/  
	currentItem = pEpgDbCtrl->playInfo.itemCount ;  
	pEpgDbCtrl->playInfo.itemCount ++ ;  
  
	pEpgDbCtrl->playInfo.records[currentItem].programid = (UINT16)programid ;  
	pEpgDbCtrl->playInfo.records[currentItem].tvid = (UINT16)tvid ;  
	pEpgDbCtrl->playInfo.records[currentItem].playtime = starttime ;  
	pEpgDbCtrl->playInfo.records[currentItem].con_time = (UINT16)conttime ;  
	SET_NOTTIMER(pEpgDbCtrl->playInfo.records[currentItem].con_time) ;  
	  
	if(info)  
	{  
		pEpgDbCtrl->playInfo.records[currentItem].infoindex = (char *)pEpgDbCtrl->textField.usedCount ;  
		strcpy(pEpgDbCtrl->textField.head+pEpgDbCtrl->textField.usedCount,info) ;  
		pEpgDbCtrl->textField.usedCount += (strlen(info)+1) ;  
	}  
	else  
		pEpgDbCtrl->playInfo.records[currentItem].infoindex = (char *)-1 ;  
  
	pEpgDbCtrl->playInfo.flagArray[currentItem] = STATUS_NORMAL ;  
  
	/* 改动索引表 */  
	modify_index_tables() ;  
  
	return currentItem+1 ;  
	  
out_textfiled:  
	pEpgDbCtrl->textField.head = pCharText ;  
	pEpgDbCtrl->textField.allocCount -= text_count ;  
	FreeMemory(pEpgDbCtrl->playInfo.returnArray) ;  
out_returnarray:  
	pEpgDbCtrl->playInfo.returnArray = pReturnArray ;  
	FreeMemory(pEpgDbCtrl->playInfo.tvIndex) ;  
out_tvindex:  
	pEpgDbCtrl->playInfo.tvIndex = pTVIndex ;  
	FreeMemory(pEpgDbCtrl->playInfo.timeIndex) ;  
out_timeindex:  
	pEpgDbCtrl->playInfo.timeIndex = pTimeIndex ;  
	FreeMemory(pEpgDbCtrl->playInfo.flagArray) ;  
out_flagarray:  
	pEpgDbCtrl->playInfo.flagArray = pFlagArray ;  
	FreeMemory(pEpgDbCtrl->playInfo.records) ;  
out_record:  
	pEpgDbCtrl->playInfo.records = pEpgRecord ;  
	pEpgDbCtrl->playInfo.allocCount -= EPGDB_CTRL_ALLOC_NUM ;  
done:  
	return result ;  
}  
  
/* 删除EPG播放节目信息,playid:播放的索引 */  
void DelEPGPlay(int playid)  
{  
	if(pEpgDbCtrl  
		&& playid > 0  
		&& playid <= (int)pEpgDbCtrl->playInfo.itemCount  
		)  
	{  
		pEpgDbCtrl->playInfo.flagArray[playid-1] = STATUS_DELETED ;  
	}  
}  
  
/* 修改EPG播放节目信息,playid:播放的索引 */  
int FullModifyEPGPlay(int playid,int tvid,time_t starttime,int conttime,char * info, int Timer, int flags)  
{  
	int result = -1 ;  
	char *pChar = NULL ;  
  
	if(pEpgDbCtrl  
		&& playid > 0  
		&& playid <= (int)pEpgDbCtrl->playInfo.itemCount  
		)  
	{  
		/* programid, tvid, starttime */  
		//pEpgDbCtrl->playInfo.records[playid].programid = (UINT16)programid ;  
		if (tvid > 0)  
			pEpgDbCtrl->playInfo.records[playid-1].tvid = (UINT16)tvid ;  
		if (starttime > 0)  
			pEpgDbCtrl->playInfo.records[playid-1].playtime = starttime ;  
  
		if (conttime != 0  
			|| Timer != 0  
			)  
		{  
			int isTimer = IS_TIMER(pEpgDbCtrl->playInfo.records[playid-1].con_time) ;  
			unsigned short setTime = GET_CON_TIME(pEpgDbCtrl->playInfo.records[playid-1].con_time) ;  
			  
			if (Timer != 0)  
				isTimer = ((Timer == 1)?1:0) ;  
  
			if (conttime != 0)  
				setTime = conttime ;  
				  
			/* con_time */  
			if (isTimer)  
			{  
				SET_TIMER(setTime) ;  
			}  
			else  
			{  
				SET_NOTTIMER(setTime) ;  
			}  
			pEpgDbCtrl->playInfo.records[playid-1].con_time = setTime ;  
		}  
		  
		if ((flags&FEPGDB_FLAGS_HOT_SET)  
			|| (flags&FEPGDB_FLAGS_HOT_RESET)  
			)  
		{  
			unsigned short chapter = pEpgDbCtrl->playInfo.records[playid-1].chapter ;  
			  
			if (flags&FEPGDB_FLAGS_HOT_SET)  
				chapter = (chapter|0x8000) ;  
			else  
			if (flags&FEPGDB_FLAGS_HOT_RESET)  
				chapter = (chapter&0x7fff) ;  
				  
			pEpgDbCtrl->playInfo.records[playid-1].chapter = chapter ;  
		}  
		  
		/* infoindex */  
		if( !info )  
		{  
			result = 0 ;  
			goto done ;  
		}  
		  
		if( pEpgDbCtrl->textField.usedCount+(INT32)strlen(info)+1 > pEpgDbCtrl->textField.allocCount )  
		{  
			pChar = pEpgDbCtrl->textField.head ;  
			pEpgDbCtrl->textField.allocCount += ( EPGDB_CTRL_ALLOC_NUM *   
				( (strlen(info)+1)/EPGDB_CTRL_ALLOC_NUM + (((strlen(info)+1)%EPGDB_CTRL_ALLOC_NUM)?1:0) )  );  
			pEpgDbCtrl->textField.head = (INT8 *)GetMemory(sizeof(UINT8)*pEpgDbCtrl->textField.allocCount ) ;  
			if(pEpgDbCtrl->textField.head == NULL)  
			{  
				pEpgDbCtrl->textField.head = pChar ;  
				pEpgDbCtrl->textField.allocCount -= ( EPGDB_CTRL_ALLOC_NUM *   
					( (strlen(info)+1)/EPGDB_CTRL_ALLOC_NUM + (((strlen(info)+1)%EPGDB_CTRL_ALLOC_NUM)?1:0) )  ) ;  
				goto done ;  
			}  
			memset(pEpgDbCtrl->textField.head,0x0,sizeof(UINT8)*pEpgDbCtrl->textField.allocCount ) ;  
			memcpy(pEpgDbCtrl->textField.head,pChar,sizeof(UINT8)*pEpgDbCtrl->textField.usedCount ) ;  
			FreeMemory(pChar) ;  
		}  
		strcpy(pEpgDbCtrl->textField.head+(INT32)pEpgDbCtrl->textField.usedCount,info) ;  
		pEpgDbCtrl->playInfo.records[playid-1].infoindex = (char*)pEpgDbCtrl->textField.usedCount ;  
		pEpgDbCtrl->textField.usedCount += (strlen(info)+1) ;  
  
		result = 0 ;  
	}  
  
done:  
	return result ;  
}  
  
int ModifyEPGPlay(int playid,int tvid,time_t starttime,int conttime,char * info, int Timer)  
{  
	return FullModifyEPGPlay(playid, tvid, starttime, conttime, info, Timer, 0x0000) ;  
}  
  
int ModifyEPGPlayEx(int playid,int tvid,time_t starttime,int conttime,char * info, int Timer, int flags)  
{  
	return FullModifyEPGPlay(playid, tvid, starttime, conttime, info, Timer, flags) ;  
}  
  
/* 获取EPG节目的详细信息,playid:节目表中的索引 */  
char * GetEPGProgramDesc(int playid)  
{  
	if(pEpgDbCtrl  
		&& playid > 0  
		&& playid < (int)pEpgDbCtrl->playInfo.itemCount  
		&& pEpgDbCtrl->textField.head  
		&& (int)pEpgDbCtrl->playInfo.records[playid-1].infoindex != -1  
		)  
	{  
		if( pEpgDbCtrl->playInfo.flagArray[playid-1] == STATUS_DELETED )  
			return NULL ;  
  
		return (pEpgDbCtrl->textField.head + (int)pEpgDbCtrl->playInfo.records[playid-1].infoindex ) ;  
	}  
  
	return NULL ;  
}  
  
/*   
 * 依据playid 取得完整的记录信息,返回值0表示正确   
 */  
int GetEpgDetailRec(int playid, EpgDetailRec_t *detail)  
{  
	int  result = -1 ;  
	int  i ;  
	EPGRECORD *epgRecord ;  
	PROGRAMRECORD *programRecord ;  
  
	if(!pEpgDbCtrl  
		|| !detail  
		|| playid <= 0  
		|| playid > pEpgDbCtrl->playInfo.itemCount  
		)  
		goto done ;  
  
	/* 该项已作了删除标记 */  
	if( pEpgDbCtrl->playInfo.flagArray[playid-1] == STATUS_DELETED )   
	{  
		result = 1 ;  
		goto done ;  
	}  
  
	epgRecord = pEpgDbCtrl->playInfo.records + playid - 1 ;  
	programRecord = pEpgDbCtrl->programInfo.records + ProgId2ProgIndex(epgRecord->programid) ;  
	/*  
	for (i=0,programRecord=NULL; iprogramInfo.itemCount; i++)  
	{  
		if (pEpgDbCtrl->programInfo.records[i].programid == epgRecord->programid)  
		{  
			programRecord = &(pEpgDbCtrl->programInfo.records[i]) ;  
			break ;  
		}  
	}  
	*/  
	  
	if (programRecord == NULL)  
		goto done ;  
  
	if( programRecord->name != (char *)-1 )  
	{  
		memset(detail->name, 0x00, sizeof(detail->name)) ;  
		strncpy(detail->name,pEpgDbCtrl->nameField.head+(INT32)programRecord->name, sizeof(detail->name)-1) ;  
	}  
	detail->playtime = epgRecord->playtime ;  
	detail->programid = epgRecord->programid ;  
	detail->con_time = GET_CON_TIME(epgRecord->con_time) ;  
	detail->tvid = epgRecord->tvid ;  
	detail->chapter = (epgRecord->chapter&0x7fff) ; /* 最高位用于其它控制 */  
	detail->maintype = programRecord->maintype ;  
	detail->subtype = programRecord->subtype ;  
	detail->istimer = (IS_TIMER(epgRecord->con_time)?1:0) ;  
  
	/* 对maintypename和subtypename不作任何处理,忽略 */  
  
	if( epgRecord->infoindex != (char *)-1 )  
	{  
		/* 先不作任何处理 */  
		/*  
		detail->descbuf = pEpgDbCtrl->textField.head + (INT32)epgRecord->infoindex ;  
		detail->descbuf_size = strlen(detail->descbuf) + 1 ;  
		*/  
	}  
	result = 0 ;  
  
done:  
	return result ;  
}  
  
/*  
 *说明:将文件存入到/extra/data/epgdb.db处  
 *	并在存入的过程中去掉已作“删除标记”的项  
 */  
int UpdateEPGDB(void)  
{  
	int result = -1 ;  
  
	if( !pEpgDbCtrl  
		)  
	{  
		fprintf(stderr,"\nERROR: Can't do any operations before initial!\n") ;  
		goto done ;  
	}  
  
	//pack() ;  
	write_to_disk(1) ;  
  
	result = 0 ;  
done:  
	return result ;  
}  
  
/* 以tvid为主健进行查找, tvid > 0 */  
int TvIdFilterEPGDB(time_t starttime,time_t endtime,int tvid,int mainkind,int subkind,int Timer,  
				char *title, char *desc, int flags,  
				int **result)  
{  
	int32 return_num = 0 ;  
	INT32 start_pos , end_pos , cur_pos ;  
  
	if( !pEpgDbCtrl  
		|| !pEpgDbCtrl->playInfo.returnArray  
		|| pEpgDbCtrl->playInfo.itemCount <= 0  
		)  
	{  
		if(result)  
			*result = NULL ;  
		goto done ;  
	}  
	  
	GET_TVIDSTART_POS(tvid, starttime, &start_pos, pEpgDbCtrl->playInfo.itemCount-1) ;  
	if (start_pos == -1)  
	{  
		if(result)  
			*result = NULL ;  
		goto done ;  
	}  
  
	end_pos = pEpgDbCtrl->playInfo.itemCount-1 ;  
	if(endtime == 0)  
		endtime = pEpgDbCtrl->playInfo.records[pEpgDbCtrl->playInfo.timeIndex[end_pos]].playtime ;  
  
	for(;start_pos<=end_pos;start_pos++)  
	{  
		cur_pos = pEpgDbCtrl->playInfo.tvIndex[start_pos] ;  
		if (0)  
		printf("start_pos=%d starttime=%d endtime=%d \t cur_pos=%d t[-1]=%d t[0]=%d t[1]=%d \n",  
				start_pos, starttime, endtime, cur_pos,   
				pEpgDbCtrl->playInfo.records[cur_pos-1].playtime,  
				pEpgDbCtrl->playInfo.records[cur_pos].playtime,  
				pEpgDbCtrl->playInfo.records[cur_pos+1].playtime  
				) ;  
		if( pEpgDbCtrl->playInfo.records[cur_pos].playtime > endtime )  
			break ;  
  
		if( (pEpgDbCtrl->playInfo.records[cur_pos].tvid == tvid)  
			&& (!mainkind || pEpgDbCtrl->programInfo.records[PlayId2ProgIndex(cur_pos+1)].maintype == mainkind)  
			&& (!subkind || pEpgDbCtrl->programInfo.records[PlayId2ProgIndex(cur_pos+1)].subtype == subkind)  
			&& (!Timer || (Timer == 1 && IS_TIMER(pEpgDbCtrl->playInfo.records[cur_pos].con_time))  
					|| (Timer == -1 && IS_NOTTIMER(pEpgDbCtrl->playInfo.records[cur_pos].con_time))  
				)  
			&& (!title || title[0] == 0x00 || IsProgTitleMatch(cur_pos+1, title))  
			&& (!desc || desc[0] == 0x00 || IsProgDescMatch(cur_pos+1, desc))  
			&& ((flags&FEPGDB_FLAGS_HOT) == 0 || (pEpgDbCtrl->playInfo.records[cur_pos].chapter&0x8000))  
			)  
		{  
			pEpgDbCtrl->playInfo.returnArray[return_num] = cur_pos+1 ;  
			return_num ++ ;  
		}  
	}  
  
	if(result)  
		*result = (int *)pEpgDbCtrl->playInfo.returnArray ;  
  
done:  
	return return_num ;  
}  
  
/* 以"时间"为主健进行查找 */  
int TimeFilterEPGDB(time_t starttime,time_t endtime,int tvid,int mainkind,int subkind,int Timer,  
				char *title, char *desc, int flags,  
				int **result)  
{  
	int32 return_num = 0 ;  
	INT32 start_pos = 0 , end_pos , cur_pos ;  
  
	if( !pEpgDbCtrl  
		|| !pEpgDbCtrl->playInfo.returnArray  
		|| pEpgDbCtrl->playInfo.itemCount <= 0  
		)  
	{  
		if(result)  
			*result = NULL ;  
		goto done ;  
	}  
	  
	GET_STSTART_POS(starttime,&start_pos,pEpgDbCtrl->playInfo.itemCount-1) ;  
	if (start_pos == -1)  
	{  
		if(result)  
			*result = NULL ;  
		goto done ;  
	}  
  
	end_pos = pEpgDbCtrl->playInfo.itemCount-1 ;  
	if(endtime == 0)  
		endtime = pEpgDbCtrl->playInfo.records[pEpgDbCtrl->playInfo.timeIndex[end_pos]].playtime ;  
  
	for(;start_pos<=end_pos;start_pos++)  
	{  
		cur_pos = pEpgDbCtrl->playInfo.timeIndex[start_pos] ;  
		if (0)  
		printf("start_pos=%d starttime=%d endtime=%d \t cur_pos=%d t[-1]=%d t[0]=%d t[1]=%d \n",  
				start_pos, starttime, endtime, cur_pos,   
				pEpgDbCtrl->playInfo.records[cur_pos-1].playtime,  
				pEpgDbCtrl->playInfo.records[cur_pos].playtime,  
				pEpgDbCtrl->playInfo.records[cur_pos+1].playtime  
				) ;  
		if( pEpgDbCtrl->playInfo.records[cur_pos].playtime > endtime )  
			break ;  
  
		if( (tvid <= 0 || pEpgDbCtrl->playInfo.records[cur_pos].tvid == tvid)  
			&& (!mainkind || pEpgDbCtrl->programInfo.records[PlayId2ProgIndex(cur_pos+1)].maintype == mainkind)  
			&& (!subkind || pEpgDbCtrl->programInfo.records[PlayId2ProgIndex(cur_pos+1)].subtype == subkind)  
			&& (!Timer || (Timer == 1 && IS_TIMER(pEpgDbCtrl->playInfo.records[cur_pos].con_time))  
					|| (Timer == -1 && IS_NOTTIMER(pEpgDbCtrl->playInfo.records[cur_pos].con_time))  
				)  
			&& (!title || title[0] == 0x00 || IsProgTitleMatch(cur_pos+1, title))  
			&& (!desc || desc[0] == 0x00 || IsProgDescMatch(cur_pos+1, desc))  
			&& ((flags&FEPGDB_FLAGS_HOT) == 0 || (pEpgDbCtrl->playInfo.records[cur_pos].chapter&0x8000))  
			)  
		{  
			pEpgDbCtrl->playInfo.returnArray[return_num] = cur_pos+1 ;  
			return_num ++ ;  
		}  
	}  
  
	if(result)  
		*result = (int *)pEpgDbCtrl->playInfo.returnArray ;  
  
done:  
	return return_num ;  
}  
  
/*  
 *过滤EPG信息:  
 *	starttime: 起始时间,0忽略;  
 *	endtime:   终止时间0忽略;  
 *	tvid:      电视台ID,0为未定义;  
 *	mainkind:   大类,0忽略;  
 *	subkind:   小类,0忽略;  
 *	Timer:     1定时、-1未定时,0忽略;  
 *	title:		对节目名进行查找,NULL或""将被忽略  
 *	desc:		对节目描述进行查找,NULL或""将被忽略  
 *	Result:     返回结果对应节目播放信息表中的数组下标(playid);  
 *	Return:     Result中的结果数  
 */  
int FilterEPGDB(time_t starttime,time_t endtime,int tvid,int mainkind,int subkind,int Timer,  
				char *title, char *desc,  
				int **result)  
{  
	if (tvid > 0)  
		return TvIdFilterEPGDB(starttime, endtime, tvid, mainkind, subkind, Timer,  
						title, desc, 0x0000,  
						result  
						) ;  
	else  
		return TimeFilterEPGDB(starttime, endtime, tvid, mainkind, subkind, Timer,  
						title, desc, 0x0000,  
						result  
						) ;  
}  
  
int FilterEPGDBEx(time_t starttime,time_t endtime,int tvid,int mainkind,int subkind,int Timer,  
				char *title, char *desc, int flags,  
				int **result)  
{  
	if (tvid > 0)  
		return TvIdFilterEPGDB(starttime, endtime, tvid, mainkind, subkind, Timer,  
						title, desc, flags,  
						result  
						) ;  
	else  
		return TimeFilterEPGDB(starttime, endtime, tvid, mainkind, subkind, Timer,  
						title, desc, flags,  
						result  
						) ;  
}  
  
//==================================================================//  
//新增网络功能  
  
int IsEPGDBRefreshNecessarily()  
{  
	int result = -1 ;  
	  
	if (pEpgDbCtrl)  
	{  
		result = 0 ;  
		  
		if (pEpgDbCtrl->playInfo.itemCount > 0)  
		{  
			time_t now = time(NULL) ;  
			time_t endtime = pEpgDbCtrl->playInfo.records[pEpgDbCtrl->playInfo.timeIndex[pEpgDbCtrl->playInfo.itemCount-1]].playtime ;  
			struct tm tm0, tm1 ;  
			  
			tm0 = *(localtime(&now)) ;  
			tm1 = *(localtime(&endtime)) ;  
			  
			if (tm0.tm_year > tm1.tm_year  
				|| (tm0.tm_year == tm1.tm_year && tm0.tm_yday > tm1.tm_yday)  
				)  
				result = 1 ;  
		}  
		else  
		{  
			result = 1 ;	  
		}  
	}  
	  
	return (result) ;  
}  
  
//刷新从远程数据库服务器  
int NetRefreshEPGDB(int tvtype, int sync)  
{  
	int result = -1 ;  
	int r ;  
	  
	if (pEpgDbCtrl)  
	{  
		EPGRECORD *pEPGRecord = NULL ;  
		int EPGRecordNums = 0 ;  
		  
		PROGRAMRECORD *pProgRecord = NULL ;  
		int ProgRecordNums = 0 ;  
		char *pProgName = NULL ;  
		int ProgNameNums = 0 ;	/* 返回的是数据的总字节数 */  
		  
		char *pProgDesc = NULL ;  
		int ProgDescNums = 0 ;	/* 返回的是数据的总字节数 */  
		int ProgId = 0 ; /* 所有节目 */  
		  
		time_t t0 = 0 ;						/* 1970 */  
		time_t t1 = t0 + 3600*24*365*50 ;	/* 向后50年 */  
		  
		int tvid = 0 ; /* 所有电视信息 */  
		  
		int progid_reindexed = 0 ;				/* 重排了索引 */  
		  
		r = GetPlayTblData(&pEPGRecord, &EPGRecordNums, &pProgDesc, &ProgDescNums, t0, t1, tvid) ;  
		if (r == 0  
			&& pEPGRecord  
			&& EPGRecordNums > 0  
			)  
		{  
			int size0 = (int)sizeof(EPGRECORD)*EPGRecordNums ;  
			int size1 = (int)sizeof(char)*ProgDescNums ;  
			EPGRECORD *p = (EPGRECORD *)malloc(size0) ;  
			char *t = NULL ;  
			  
			if (size1 > 0)  
				t = (char *)malloc(size1) ;  
				  
			if ((ProgDescNums <= 0 && p)  
				|| (ProgDescNums > 0 && p && t)  
				)  
			{  
				memcpy(p, pEPGRecord, size0) ;  
				pEPGRecord = p ;  
				memcpy(t, pProgDesc, size1) ;  
				pProgDesc = t ;  
			}  
			else  
			{  
				if (p) free(p) ;  
				if (t) free(t) ;  
				pEPGRecord = NULL ;  
				pProgDesc = NULL ;  
			}  
		}  
		else  
		{  
			pEPGRecord = NULL ;  
			pProgDesc = NULL ;  
		}  
		FreePlayTblData() ;  
		  
		if (pEPGRecord)  
		{  
			r = GetProgTblData(&pProgRecord, &ProgRecordNums, &pProgName, &ProgNameNums) ;  
			if (r == 0  
				&& pProgRecord  
				&& ProgRecordNums > 0  
				&& pProgName  
				&& ProgNameNums > 0  
				)  
			{  
				int size0 = (int)sizeof(PROGRAMRECORD)*ProgRecordNums ;  
				int size1 = ProgNameNums ;  
				PROGRAMRECORD *p0 = (PROGRAMRECORD *)malloc(size0) ;  
				char *p1 = (char *)malloc(size1) ;  
				  
				if (p0  
					&& p1  
					)  
				{  
					memcpy(p0, pProgRecord, size0) ;  
					pProgRecord = p0 ;  
					memcpy(p1, pProgName, size1) ;  
					pProgName = p1 ;  
					result = 0 ;  
				}  
				else  
				{  
					if (p0) free(p0) ;  
					if (p1) free(p1) ;  
					pProgRecord = NULL ;  
					pProgName = NULL ;  
				}  
			}  
			else  
			{  
				pProgRecord = NULL ;  
			}  
			FreeProgTblData() ;  
		}  
/*  
	从PlayTbl中取得节目描述信息,此处停止使用  
*/  
/*		  
		if (pEPGRecord  
			&& pProgRecord  
			&& pProgName  
			)  
		{  
			r = GetProgDescTblData(&pProgDesc, &ProgDescNums, &ProgId) ;  
			if (r == 0  
				&& pProgDesc  
				&& ProgDescNums > 0  
				)  
			{  
				int size0 = (int)sizeof(char)*ProgDescNums ;  
				char *p = (char *)malloc(size0) ;  
				  
				if (p)  
				{  
					memcpy(p, pProgDesc, size0) ;  
					pProgDesc = p ;  
				}  
				else  
				{  
					pProgDesc = NULL ;  
				}  
			}  
			else  
			{  
				pProgDesc = NULL ;  
			}  
			FreeProgDescTblData() ;  
		}  
*/  
		/* 重排索引 */  
		if (pEPGRecord  
			&& pProgRecord  
			&& pProgName  
			)  
		{  
			int i, max ;  
			  
			for (i=0,max=-1; i max)  
					max = pProgRecord[i].programid ;  
			}  
			if (max > 0)  
			{  
				int *pi = (int *) malloc(sizeof(int)*(max+1)) ;  
				  
				if (pi)  
				{  
					bzero(pi, sizeof(int)*max) ;  
					for (i=0; iplayInfo.records)  
					free(pEpgDbCtrl->playInfo.records) ;  
				if (pEpgDbCtrl->playInfo.flagArray)  
					free(pEpgDbCtrl->playInfo.flagArray) ;  
				if (pEpgDbCtrl->playInfo.returnArray)  
					free(pEpgDbCtrl->playInfo.returnArray) ;  
				if (pEpgDbCtrl->playInfo.timeIndex)  
					free(pEpgDbCtrl->playInfo.timeIndex) ;  
				if (pEpgDbCtrl->playInfo.tvIndex)  
					free(pEpgDbCtrl->playInfo.tvIndex) ;  
					  
				pEpgDbCtrl->playInfo.allocCount = EPGRecordNums ;  
				pEpgDbCtrl->playInfo.itemCount = EPGRecordNums ;  
				pEpgDbCtrl->playInfo.records = pEPGRecord ;  
				pEpgDbCtrl->playInfo.flagArray = flagArray0 ;  
				pEpgDbCtrl->playInfo.timeIndex = NULL ;  
				pEpgDbCtrl->playInfo.tvIndex = NULL ;  
				  
				/* 更新节目表 */  
				if (pEpgDbCtrl->programInfo.records)  
					free(pEpgDbCtrl->programInfo.records) ;  
				if (pEpgDbCtrl->programInfo.flagArray)  
					free(pEpgDbCtrl->programInfo.flagArray) ;  
					  
				pEpgDbCtrl->programInfo.allocCount = ProgRecordNums ;  
				pEpgDbCtrl->programInfo.itemCount = ProgRecordNums ;  
				pEpgDbCtrl->programInfo.records = pProgRecord ;  
				pEpgDbCtrl->programInfo.flagArray = flagArray1 ;  
					  
				/* 更新节目表名 */  
				if (pEpgDbCtrl->nameField.head)  
					free(pEpgDbCtrl->nameField.head) ;  
					  
				pEpgDbCtrl->nameField.allocCount = ProgNameNums ;  
				pEpgDbCtrl->nameField.usedCount = ProgNameNums ;  
				pEpgDbCtrl->nameField.head = (UINT8 *)pProgName ;  
				  
				/* 清除节目描述数据 */  
				if (pEpgDbCtrl->textField.head)  
					free(pEpgDbCtrl->textField.head) ;  
				pEpgDbCtrl->textField.head = NULL ;  
				pEpgDbCtrl->textField.allocCount = 0 ;  
				pEpgDbCtrl->textField.usedCount = 0 ;  
				  
				/* 若获取节目描述成功,更新它 */  
				if (pProgDesc  
					&& ProgDescNums > 0  
					)  
				{  
					pEpgDbCtrl->textField.head = pProgDesc ;  
					pEpgDbCtrl->textField.allocCount = ProgDescNums ;  
					pEpgDbCtrl->textField.usedCount = ProgDescNums ;  
				}  
				  
				/* 准备更新索引表 */  
				pEpgDbCtrl->playInfo.returnArray = returnArray ;  
				pEpgDbCtrl->playInfo.timeIndex = timeIndex ;  
				pEpgDbCtrl->playInfo.tvIndex = tvIndex ;  
				reindexall() ;  
								  
				/* 更新数据到文件(数据库)中去 */  
				  
				/* 无需进行重新整理 */  
				write_to_disk(1) ;  
				  
				/* 试图从网络更新节目类型数据表 */  
				r = NetRefreshEPGTypeRecordDB(tvtype, sync) ;  
#ifdef __DEBUG__  
				printf("NetRefreshEPGTypeRecordDB()=%d \n", r) ;  
#endif  
				  
				result = 0 ;  
			}  
			else  
			{  
				if (flagArray0)	free(flagArray0) ;  
				if (flagArray1)	free(flagArray1) ;  
			}  
		}  
		  
		/* 更新不完全成功 */  
		if (result != 0)  
		{  
			if (pEPGRecord)		free(pEPGRecord) ;  
			if (pProgRecord)	free(pProgRecord) ;  
			if (pProgName)		free(pProgName) ;  
			if (pProgDesc)		free(pProgDesc) ;  
		}  
	}  
	  
	return (result) ;  
}  
  
//刷新从远程数据库服务器  
int NetUpdateEPGDB(int tvtype, int sync)  
{  
	int result = -1 ;  
	  
	if (pEpgDbCtrl)  
	{  
		  
		  
	}  
	  
	return (result) ;  
}  
  
//==================================================================//  
//EEP节目类型管理  
  
typedef struct tagEPGTypeCtrl  
{  
	TYPERECORD	*pList ;  
	int		bInitialized ;  
	int		itemCount ;  
	int		mallocCount ;  
} EPGTypeCtrl_t, *pEPGTypeCtrl_t ;  
  
#define EPG_TYPE_CTRL_ALLOC_NUMS	10	//每次分配的项数  
#define EPG_TYPE_DB_FILE 	"/extra/database/progtype.db"  
  
static EPGTypeCtrl_t *pEPGTypeCtrl = NULL ;  
  
  
/* 初始化节目类型称数据库 */  
int InitEPGTypeRecordDB()  
{  
	int result = -1 ;  
	FILE *fr ;  
	  
	if (pEPGTypeCtrl)  
	{  
		if (pEPGTypeCtrl->pList)	free(pEPGTypeCtrl->pList);  
		free(pEPGTypeCtrl) ;  
		pEPGTypeCtrl = NULL ;  
	}  
	  
	pEPGTypeCtrl = (EPGTypeCtrl_t *)malloc(sizeof(EPGTypeCtrl_t)) ;  
	if (pEPGTypeCtrl == NULL)  
		goto done ;  
	  
	/* 从存储器装载,并初化pEPGTypeCtrl指向的结构 */  
	fr = fopen(EPG_TYPE_DB_FILE, "rb") ;  
	if (fr)  
	{  
		int n = 0 ;  
		  
		if (fseek(fr, 0, SEEK_END) == 0)  
			n = (int)ftell(fr) ;  
		fseek(fr, 0, SEEK_SET) ;  
		  
		if (n > (int)sizeof(EPGTypeCtrl_t)  
			&& fread(pEPGTypeCtrl, (size_t)sizeof(EPGTypeCtrl_t), 1, fr) == 1  
			&& pEPGTypeCtrl->itemCount > 0  
			)  
		{  
			size_t size0 = (size_t)(sizeof(TYPERECORD)*pEPGTypeCtrl->itemCount) ;  
			  
			TYPERECORD *pList = (TYPERECORD *)malloc(size0) ;  
			if (pList  
				&& n >= (sizeof(EPGTypeCtrl_t) + size0)  
				&& (fread(pList, (size_t)sizeof(TYPERECORD), pEPGTypeCtrl->itemCount, fr) == pEPGTypeCtrl->itemCount)  
				)  
			{  
				pEPGTypeCtrl->pList = pList ;  
				pEPGTypeCtrl->mallocCount = pEPGTypeCtrl->itemCount ;  
				result = 0 ;  
			}  
			else  
			{  
#ifdef __DEBUG__  
				printf("open database %s error \n", EPG_TYPE_DB_FILE) ;  
#endif  
				if (pList) free(pList) ;  
				memset(pEPGTypeCtrl, 0x00, sizeof(EPGTypeCtrl_t)) ;  
			}  
		}  
		fclose(fr) ;  
	}  
	else  
	{  
		memset(pEPGTypeCtrl, 0x00, sizeof(EPGTypeCtrl_t)) ;  
	}  
		  
done:  
	return (result) ;  
}  
  
/* 关闭节目类型称数据库 */  
int CloseEPGTypeRecordDB()  
{  
	int result = -1 ;  
	FILE *fw ;  
	  
	if (pEPGTypeCtrl)  
	{		  
		/* 释放资源 */  
		if (pEPGTypeCtrl->pList) free(pEPGTypeCtrl->pList) ;  
		free(pEPGTypeCtrl) ;  
		pEPGTypeCtrl = NULL ;  
	}  
	result = 0 ;  
		  
	return (result) ;  
}  
  
/* 更新节目类型称数据库 */  
int UpdateEPGTypeRecordDB()  
{  
	int result = -1 ;  
	FILE *fw ;  
	  
	if (pEPGTypeCtrl)  
	{  
		/* 写入数据到存储器中 */  
		if (pEPGTypeCtrl->itemCount >= 0)  
		{  
			fw = fopen(EPG_TYPE_DB_FILE, "wb") ;  
			if (fw)  
			{  
				fwrite(pEPGTypeCtrl, sizeof(EPGTypeCtrl_t), 1, fw) ;  
				fwrite(pEPGTypeCtrl->pList, sizeof(TYPERECORD)*pEPGTypeCtrl->itemCount, 1, fw) ;  
				fclose(fw) ;  
				result = 0 ;  
			}  
		}	  
	}  
		  
	return (result) ;  
}  
  
/* 清空节目类型称数据库 */  
int EmptyEPGTypeRecordDB(void)  
{  
	int result = -1 ;  
	  
	if (pEPGTypeCtrl)  
	{  
		if (pEPGTypeCtrl->pList) free(pEPGTypeCtrl->pList) ;  
		pEPGTypeCtrl->itemCount = 0 ;  
		pEPGTypeCtrl->mallocCount = 0 ;  
		result = 0 ;  
	}  
	  
	return (result) ;  
}  
  
/* 从过程服务器刷新数据库 */  
int NetRefreshEPGTypeRecordDB(int tvtype, int sync)  
{  
	int result = -1 ;  
	int r ;  
	TYPERECORD *progtype = NULL ;  
	int nums = 0 ;  
	  
	if (pEPGTypeCtrl)  
	{  
		r = GetProgTypeTblData(&progtype, &nums) ;  
		if (r == 0  
			&& progtype  
			&& nums > 0  
			)  
		{  
			EmptyEPGTypeRecordDB() ;  
			pEPGTypeCtrl->pList = (TYPERECORD *)malloc(sizeof(TYPERECORD)*nums) ;  
			if (pEPGTypeCtrl->pList)  
			{  
				memcpy(pEPGTypeCtrl->pList, progtype, sizeof(TYPERECORD)*nums) ;  
				pEPGTypeCtrl->itemCount = nums ;  
				pEPGTypeCtrl->mallocCount = nums ;  
				  
				UpdateEPGTypeRecordDB() ;  
				result = 0 ;  
			}  
		}  
		else  
		{  
#ifdef __DEBUG__  
			printf("NetRefreshEPGTypeRecordDB() Error! \n") ;  
#endif  
		}  
		FreeProgTypeTblData() ;  
	}  
	  
	return (result) ;  
}  
  
/* 使用本地数据更新过程服务器 */  
int NetUpdateEPGTypeRecordDB(int tvtype, int sync)  
{  
	int result = -1 ;  
	  
	return (result) ;  
}  
  
/* 增加节目类型记录,返回分配给其的台名ID(>0) */  
int AddEPGTypeRecord(char * type_name)  
{  
	int result = -1 ;  
	  
	if (pEPGTypeCtrl  
		&& type_name  
		)  
	{  
		if (pEPGTypeCtrl->mallocCount <= pEPGTypeCtrl->itemCount)  
		{  
			TYPERECORD *p ;  
			int count = (((pEPGTypeCtrl->itemCount + 1)/EPG_TYPE_CTRL_ALLOC_NUMS) + 1) * EPG_TYPE_CTRL_ALLOC_NUMS ;  
			  
			p = (TYPERECORD *)malloc(count * sizeof(TYPERECORD)) ;  
			if (p)  
			{  
				memcpy(p, pEPGTypeCtrl->pList, pEPGTypeCtrl->itemCount*sizeof(TYPERECORD)) ;  
				free(pEPGTypeCtrl->pList) ;  
				pEPGTypeCtrl->pList = p ;  
				pEPGTypeCtrl->mallocCount = count ;  
			}  
			else  
			{  
				goto done ;  
			}  
		}  
		  
		if (pEPGTypeCtrl->mallocCount > pEPGTypeCtrl->itemCount)  
		{  
			TYPERECORD *p = &(pEPGTypeCtrl->pList[pEPGTypeCtrl->itemCount]) ;  
			int i, id ;  
			  
			// 分配一个id  
			for (i=0, id=-1; iitemCount; i++)  
			{  
				if (pEPGTypeCtrl->pList[i].type_id > id)  
					id = pEPGTypeCtrl->pList[i].type_id ;  
			}  
			id++ ;  
			if (id <=0)  
				id = 1 ;  
				  
			memset(p->type_name, sizeof(p->type_name), 0x00) ;  
			strncpy(p->type_name, type_name, sizeof(p->type_name)-1) ;  
			  
			pEPGTypeCtrl->itemCount++ ;  
			result = 0 ;  
		}  
	}  
  
done:  
	return (result) ;	  
}  
  
  
/* 删除节目类型记录,成功返回0 */  
void DelEPGTypeRecord(int type_id)  
{  
	int result = -1 ;  
	  
	if (pEPGTypeCtrl)  
	{  
		int i, j ;  
		  
		for (i=0; iitemCount; i++)  
		{  
			if (pEPGTypeCtrl->pList  
				&& pEPGTypeCtrl->pList[i].type_id == type_id)  
			{  
				if ((pEPGTypeCtrl->itemCount-i-1) > 0)  
					memcpy(&(pEPGTypeCtrl->pList[i]), &(pEPGTypeCtrl->pList[i+1]), (pEPGTypeCtrl->itemCount-i-1)*sizeof(TYPERECORD)) ;  
				pEPGTypeCtrl->itemCount-- ;  
				result = 0 ;  
				break ;  
			}  
		}  
	}  
	  
//	return (result) ;	  
}  
  
  
/* 修改节目类型记录,成功返回0 */  
int ModifyEPGTypeRecord(TYPERECORD *progtype)  
{  
	int result = -1 ;  
  
	if (pEPGTypeCtrl  
		&& progtype  
		)  
	{  
		int i ;  
		  
		for (i=0; iitemCount; i++)  
		{  
			if (pEPGTypeCtrl->pList[i].type_id == progtype->type_id)  
			{  
				TYPERECORD *p = &(pEPGTypeCtrl->pList[i]) ;  
				  
				memcpy(p, progtype, sizeof(TYPERECORD)) ;  
				  
				result = 0 ;  
				break ;  
			}  
		}  
	}  
	  
	return (result) ;	  
}  
  
  
/* 取得节目类型的总数 */  
int GetEPGTypeRecordNums()  
{  
	int result = 0 ;  
	  
	if (pEPGTypeCtrl)  
	{  
		result = pEPGTypeCtrl->itemCount ;  
	}  
	  
	return (result) ;	  
}  
  
  
/* 取得节目类型表中的第“n”条记录,索引从0开始 */  
int GetEPGTypeRecordRec(int index, TYPERECORD *progtype)  
{  
	int result = -1 ;  
  
	if (pEPGTypeCtrl  
		&& progtype  
		&& index >= 0  
		&& index < pEPGTypeCtrl->itemCount  
		)  
	{  
		memcpy(progtype, &(pEPGTypeCtrl->pList[index]), sizeof(TYPERECORD)) ;  
		result = 0 ;  
	}  
	  
	return (result) ;  
}  
  
/* 按节目类型id取得完整的节目类型记录 */  
int GetEPGTypeRecord(int type_id, TYPERECORD *epgtype)  
{  
	int result = -1 ;  
	  
	if (pEPGTypeCtrl  
		&& type_id > 0  
		&& epgtype  
		&& pEPGTypeCtrl->itemCount > 0  
		&& pEPGTypeCtrl->pList  
		)  
	{  
		int i ;  
		  
		for (i=0; iitemCount; i++)  
		{  
			if (type_id == pEPGTypeCtrl->pList[i].type_id)  
			{  
				memcpy(epgtype, &(pEPGTypeCtrl->pList[i]), sizeof(TYPERECORD)) ;  
				result = 0 ;  
				break ;	  
			}  
		}  
	}  
	  
	return (result) ;  
}