⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 callinfo.cpp

📁 多媒体电话记录程序
💻 CPP
字号:
/////////////////////////////////////////////////////////////////////////////
//  Name: callinfo.cpp
//  Copyright: wellgain
//  Author: bet
//  Date: 2003-10-8
//  Description:  the implement for class CCallinfo and others which are used by it
/////////////////////////////////////////////////////////////////////////////
#include <assert.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include "callinfo.h"
#include "config.h"


/////////////////////////////////////////////////////////////////////////////
//------------------------------ class CCallTimes ---------------------------
CCallTimes::CCallTimes(const char* szfilename) 
{
	assert(szfilename && szfilename[0]);
	m_last = m_callin = m_callout = CTime(0, 0, 0);	
	m_szFileName = g_strdup(szfilename);

	LoadFromFile();	
}

CCallTimes::CCallTimes(const CCallTimes& ct)
{
	m_last    = ct.m_last;
	m_callin  = ct.m_callin;
	m_callout = ct.m_callout;
	m_szFileName = g_strdup(ct.m_szFileName);
}
	
CCallTimes& CCallTimes::operator=(const CCallTimes& ct)
{
	if(this == &ct)
		return *this;
	m_last    = ct.m_last;
	m_callin  = ct.m_callin;
	m_callout = ct.m_callout;
	m_szFileName = g_strdup(ct.m_szFileName);
	return *this;
}

CCallTimes::~CCallTimes()
{
	if(m_szFileName)
		g_free(m_szFileName);
	m_szFileName = NULL;
}

void CCallTimes::NewCall(CTime& t, bool iscallin)
{
	if(iscallin)
		m_callin += t;
	else
		m_callout += t;

	m_last = t;
	SaveToFile();
}

void CCallTimes::Clear()
{ 
	m_callin  = 0L;
	m_callout = 0L;

	SaveToFile();
}

void CCallTimes::SaveToFile()
{
	assert(m_szFileName && m_szFileName[0]);
	FILE* fp;
	fp = fopen(m_szFileName, "wb");
	if(fp != NULL){
		CArchive storeAr(fp, CArchive::store);
		m_last.Serialize(storeAr);
		m_callin.Serialize(storeAr);
		m_callout.Serialize(storeAr);
		storeAr.Close();
		fclose(fp);
	}
}

void CCallTimes::LoadFromFile()
{
	assert(m_szFileName && m_szFileName[0]);
	FILE* fp;
	struct stat buf;
	/* 如果文件不存在,则创建 */
	if((stat(m_szFileName, &buf) == -1) && (errno == ENOENT)) 
		SaveToFile();
	else{
		fp = fopen(m_szFileName, "rb");
		if(fp == NULL)
			return;
		CArchive loadAr(fp, CArchive::load);
		m_last.Serialize(loadAr);
		m_callin.Serialize(loadAr);
		m_callout.Serialize(loadAr);
		loadAr.Close();
		fclose(fp);
	}		
}

/////////////////////////////////////////////////////////////////////////////
//------------------------------ class CCallRecord ---------------------------

CCallRecord::CCallRecord(const char* szName, const char* szTel, 
						 CDateTime dt, CTime dur, int freq)
{
	SetName(szName);
	SetTel(szTel);
	
	SetTime(dt);
	SetDuration(dur);
	m_nIndex = -1;
	SetFreq(freq);
} 

CCallRecord::CCallRecord(const CCallRecord& cr)
{
	SetName(cr.m_szName);
	SetTel(cr.m_szTel);
	SetTime(cr.m_Time);
	SetDuration(cr.m_Duration);
	m_nIndex = cr.m_nIndex;
	SetFreq(cr.m_nFreq);
}
	
CCallRecord& CCallRecord::operator=(const CCallRecord& cr)
{
	if(this == &cr)
		return *this;
	SetName(cr.m_szName);
	SetTel(cr.m_szTel);
	SetTime(cr.m_Time);
	SetDuration(cr.m_Duration);
	m_nIndex = cr.m_nIndex;
	SetFreq(cr.m_nFreq);
	return *this;
}

CCallRecord::~CCallRecord()
{

}

/*
void CCallRecord::SetTel(const char* szTel)
{	
	int i = 0;
	while(*szTel){
		if(isdigit(*szTel))
			m_szTel[i++] = *szTel;
		szTel++;
	}
	m_szTel[i] = '\0';
}
*/

void CCallRecord::Serialize(CArchive& ar)
{
	if(ar.IsStoring()){
		ar.Write(m_szName, sizeof(m_szName));
		ar.Write(m_szTel, sizeof(m_szTel));
		m_Time.Serialize(ar);
		m_Duration.Serialize(ar);
		ar<<m_nFreq;
	}
	else{
		ar.Read(m_szName, sizeof(m_szName));
		ar.Read(m_szTel, sizeof(m_szTel));
		m_Time.Serialize(ar);
		m_Duration.Serialize(ar);
		ar>>m_nFreq;
	}
}

/////////////////////////////////////////////////////////////////////////////
//------------------------------ class CCallsInfo ---------------------------
static gint SortFreqFirst(gconstpointer a, gconstpointer b)
{ 
	CCallRecord* aa = (CCallRecord*)a;
	CCallRecord* bb = (CCallRecord*)b;
	if(bb->isDeleted())
		return -1;
	if(aa->isDeleted() || (bb->GetFreq() > aa->GetFreq()) || 
		((bb->GetFreq() == aa->GetFreq()) && (bb->GetTime() > aa->GetTime())))
		return 1;
	return -1;
}

static gint SortTimeFirst(gconstpointer a, gconstpointer b)
{ 
	CCallRecord* aa = (CCallRecord*)a;
	CCallRecord* bb = (CCallRecord*)b;
	if(bb->isDeleted())
		return -1;
	if(aa->isDeleted() || (bb->GetTime() > aa->GetTime()) || 
		((bb->GetTime() == aa->GetTime()) && (bb->GetFreq() > aa->GetFreq())))
		return 1;
	return -1;
}

int CCallsInfo::telcmp(const char* tel1, const char* tel2)
{
	int len = 0;
	while(*tel1 || *tel2){
		if(*tel1 && !isdigit(*tel1)){
			tel1++;
			continue;
		}
		if(*tel2 && !isdigit(*tel2)){
			tel2++;
			continue;
		}
		if(*tel1 != *tel2)
			return *tel1 - *tel2;
		tel1++;
		tel2++;		
		len++;
	}
	if(len)
		return 0;
	return 1;
}

gint FindCompareFunc(gconstpointer a, gconstpointer b)
{ 
	CCallRecord* aa = (CCallRecord*)a;
	CCallRecord* bb = (CCallRecord*)b;
	return (aa->isDeleted() || bb->isDeleted() || 
			CCallsInfo::telcmp(aa->GetTel(), bb->GetTel())); 
}

CCallsInfo::CCallsInfo(CallType type, const char* szfilename)
{
	assert(szfilename && szfilename[0]);
	m_szFileName = g_strdup(szfilename);
	m_eType = type;
	m_nCount = 0;
	m_lRecordLength = 0L;
	m_Records = NULL;

	LoadFromFile();	
}

CCallsInfo::~CCallsInfo()
{
	if(m_szFileName)
		g_free(m_szFileName);
	if(m_Records){
		GSList* list = m_Records;
		while(list){
			delete (CCallRecord*)(list->data);
			list = list->next;
		}
		g_slist_free(m_Records);
	}
	m_Records = NULL;
}

void CCallsInfo::Delete(int nth)
{	
	GSList* list = g_slist_nth(m_Records, nth);
	if(list){
		CCallRecord* pcr = (CCallRecord*)(list->data);
		if(!(pcr->isDeleted()))
			m_nCount--;
		pcr->Delete();		
		UpdateRecord(pcr);		
		m_Records = g_slist_remove_link(m_Records, list);
		m_Records = g_slist_concat(m_Records, list);				
	}
}

void CCallsInfo::UpdateDuration(CTime dur)
{
	if((m_eType==received) || (m_eType==dialed)){
		CCallRecord* pcr = (CCallRecord*)g_slist_nth_data(m_Records, 0);
		if(pcr){
			pcr->SetDuration(dur);
			UpdateRecord(pcr);
		}
	}
}

void CCallsInfo::ForEach(CallsInfoForEach f, gpointer user_data)
{
	GSList* list = m_Records;
	CCallRecord* pcr;
	int i = 0;
	while(list && (i++ < MaxRecordCount)){
		pcr = (CCallRecord*)(list->data);
		list = list->next;
		if(pcr->isDeleted() || !f(*pcr, user_data))
			break;
	}
}
	
void CCallsInfo::UpdateRecord(CCallRecord* rec)
{
	assert(m_szFileName && m_szFileName[0]);
	FILE* fp;
	struct stat buf;
	/* 如果文件不存在,则创建 */
	if((stat(m_szFileName, &buf) == -1) && (errno == ENOENT)){
		SaveToFile();
		return;
	}

	fp = fopen(m_szFileName, "rb+");
	if(fp == NULL)
		return;
	CArchive storeAr(fp, CArchive::store);
	assert(storeAr);
	storeAr.Seek(rec->m_nIndex*m_lRecordLength,CArchive::beg);
	
	if(m_lRecordLength == 0L){
		int pos = storeAr.Tell();
		rec->Serialize(storeAr);
		m_lRecordLength = storeAr.Tell() - pos;
	}
	else
		rec->Serialize(storeAr);

	storeAr.Close();
	fclose(fp);
}

void CCallsInfo::SaveToFile()
{
	assert(m_szFileName && m_szFileName[0]);
	FILE* fp;
	fp = fopen(m_szFileName, "wb");
	if(fp == NULL)
		return;
	CArchive storeAr(fp, CArchive::store);
		
	GSList* list = m_Records;	
	while(list){		
		if(m_lRecordLength==0L){
			long pos = storeAr.Tell();
			((CCallRecord*)(list->data))->Serialize(storeAr);
			m_lRecordLength = storeAr.Tell() - pos;
		}
		else{
			((CCallRecord*)(list->data))->Serialize(storeAr);
		}
		list = list->next;
	}
	storeAr.Close();
	fclose(fp);			
}

void CCallsInfo::LoadFromFile()
{
	assert(m_szFileName && m_szFileName[0]);
	FILE* fp;
	struct stat buf;
	/* 如果文件不存在,则创建 */
	if((stat(m_szFileName, &buf) == -1) && (errno == ENOENT)){ 
		SaveToFile();
		return;
	}
	
	fp = fopen(m_szFileName, "rb");
	if(fp == NULL)
		return;
	CArchive loadAr(fp, CArchive::load);
	
	CCallRecord* pcr;
	int i = 0;
	while(loadAr){
		pcr = new CCallRecord();
		if(m_lRecordLength==0L){
			long pos = loadAr.Tell();
			pcr->Serialize(loadAr);
			m_lRecordLength = loadAr.Tell() - pos;
		}			
		else{
			pcr->Serialize(loadAr);
		}				
		
		if(!loadAr){
			delete pcr;
			pcr = NULL;
			break;
		}
		
		pcr->m_nIndex  = i++;
		if(!pcr->isDeleted())
			m_nCount++;
		
		m_Records = g_slist_prepend(m_Records, pcr);
	}
	
	loadAr.Close();
	fclose(fp);	
	
	if(m_eType==offen)
		m_Records = g_slist_sort(m_Records, SortFreqFirst);
	else
		m_Records = g_slist_sort(m_Records, SortTimeFirst);		
}

int CCallsInfo::NewCall(CCallRecord& newrec)
{
	if(newrec.isDeleted())
		return -1;
	CCallRecord* pcr = NULL;	
	CCallRecord* p = NULL;
	int index = -1, freq = 0;
	switch(m_eType){
	case received:
	case dialed:		
		break;
	case missed:
		p = (CCallRecord*)g_slist_nth_data(m_Records, 0);
		if(p && !strcmp(p->GetTel(), newrec.GetTel())){
			m_Records = g_slist_remove(m_Records, p);
			m_nCount--;
			p->inCrease();
			index = p->m_nIndex;
			freq = p->GetFreq();
			delete p;
		}		
		break;
	case blacklist:
	case offen:
		GSList* temp = g_slist_find_custom(m_Records, &newrec, FindCompareFunc);
		if(temp){	
			p = (CCallRecord*)(temp->data);			
			m_Records = g_slist_remove(m_Records, p);
			m_nCount--;			
			p->inCrease();
			index = p->m_nIndex;
			freq = p->GetFreq();
			delete p;						
		}
		else if(m_eType == blacklist)
			return -1;
		break;
	}	//switch

	if(index<0){		
		int nth = 0;		
		freq = 1;
		GSList* list = m_Records;
		while(list){
			p = (CCallRecord*)(list->data);
			if(p->isDeleted()){				
				break;
			}
			list = list->next;
			nth++;
		}				
		if(p && p->isDeleted()){
			index = p->m_nIndex;
			m_Records = g_slist_remove(m_Records, p);
			delete p;
		}
		else if(nth < MaxRecordCount){
			index = nth;
		}
		else{
			if(m_eType!=offen){
				GSList* list = g_slist_last(m_Records);
				if(list){
					p = (CCallRecord*)(list->data);
					if(p){
						index = p->m_nIndex;
						//p->Delete();						
						m_Records = g_slist_remove(m_Records, p);
						m_nCount--;	
						delete p;
					}
				}
			}
			// 常用号码类
			else{
				if(nth < (MaxRecordCount*3)){
					index = nth;
				}
				else{			
					GSList* list = g_slist_nth(m_Records, MaxRecordCount*2); 
					while(list){						
						p = (CCallRecord*)(list->data);						
						p->Delete();
						UpdateRecord(p);
						//if(p->isDeleted())
							m_nCount--;										
						list = list->next;
					}				
					p = (CCallRecord*)g_slist_nth_data(m_Records, MaxRecordCount*2);
					if(p){
						index = p->m_nIndex;
						m_Records = g_slist_remove(m_Records, p);
						delete p;
					}
				}				
			}								
		}	
	}
	pcr = new CCallRecord(newrec);
	pcr->SetFreq(freq);
	pcr->m_nIndex = index;
			
	UpdateRecord(pcr);
	if(m_eType==offen)
		m_Records = g_slist_insert_sorted(m_Records, pcr, SortFreqFirst);
	else
		m_Records = g_slist_insert_sorted(m_Records, pcr, SortTimeFirst);
	m_nCount++;	
	//return g_slist_index(m_Records,pcr);
	return 0;
}

int CCallsInfo::NewBlackName(CCallRecord& newrec)
{
	if(m_eType != blacklist)
		return -1;

	CCallRecord* pcr = FindRecord(newrec);
	if(pcr){
		pcr->SetName(newrec.GetName());
		pcr->SetTel(newrec.GetTel());
		UpdateRecord(pcr);
		return -2;
	}

	pcr = NULL;	
	CCallRecord* p = NULL;
	int index = 0, nth = 0;		
	GSList* list = m_Records;
	while(list){
		p = (CCallRecord*)(list->data);
		if(p->isDeleted()){				
			break;
		}
		list = list->next;
		nth++;
	}				
	if(p && p->isDeleted()){
		index = p->m_nIndex;
		m_Records = g_slist_remove(m_Records, p);
		delete p;
	}
	else if(nth < MaxRecordCount){
		index = nth;
	}
	else{
		GSList* list = g_slist_last(m_Records);
		if(list){
			p = (CCallRecord*)(list->data);
			index = p->m_nIndex;
			//p->Delete();						
			m_Records = g_slist_remove(m_Records, p);
			m_nCount--;	
			delete p;			
		}
	}
	pcr = new CCallRecord(newrec);
	pcr->m_nIndex = index;
	pcr->SetFreq(0);
	UpdateRecord(pcr);
	m_Records = g_slist_insert_sorted(m_Records, pcr, SortTimeFirst);
	m_nCount++;	
	//return g_slist_index(m_Records,pcr);
	return 0;
}


void CCallsInfo::SyncDataFile()
{
/*	struct stat buf1, buf2;
	char *cmd, *memfile, *flashfile;
	static char* filename[6] = {OffenFileName, MissedFileName, 
								DialedFileName, ReceivedFileName,
								BlacklistFileName, CallTimesFileName 
								};
	for(int i=0; i<6; i++){	
		memfile = g_strdup_printf("%s%s", MEMDATAFILEPATH, filename[i]);
		flashfile = g_strdup_printf("%s%s", FLASHDATAFILEPATH, filename[i]);
		if(	(stat(memfile, &buf1) == 0) &&
			((stat(flashfile, &buf2)!=0) || (buf1.st_mtime > buf2.st_mtime)) )
		{
			cmd = g_strdup_printf("cp -f %s %s", memfile, flashfile);
			//g_print("---- cmd = %s --- \n", cmd);
			system(cmd);
			g_free(cmd);
		}
		g_free(memfile);
		g_free(flashfile);
	}
*/
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -