📄 callinfo.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 + -