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

📄 dbsfile.cpp

📁 C51访问西门子MC55做的透传模块, 支持远程注册和配置, 仅支持TCP协议, 其他请参考MC55说明书.
💻 CPP
字号:
#include "DbsFile.h"
#include <dos.h>
#include <dir.h>
//该数据库保存记录的批次数为245批抄表读数,3批结算日数据。
//每167K的内存最多可以保存64块表,也即数据库大小必须为167K的倍数
int CDbsFile::CreateNewDbs()
{
	//计算数据库文件大小
	struct dfree free;
	unsigned long FreeSpaceKB;
	unsigned long NewFileSize;
	getdfree(getdisk()+1, &free);//获得当前磁盘的基本信息。
	if(free.df_sclus == 0xFFFF) return 1;//产生失败

	FreeSpaceKB=(unsigned long) free.df_avail*(unsigned long) free.df_bsec* (unsigned long) free.df_sclus/1024L;
	FreeSpaceKB-=384;//剩余空间少384K
	if(FreeSpaceKB>0x4000L) FreeSpaceKB=0x4000L;//最大文件空间为16M=0x4000K
	if(1)  FreeSpaceKB=1024;

	//数据库文件大小
	NewFileSize=FreeSpaceKB/167*167;//文件大小,单位多少K

	memset(m_HubMsgData,0,192);

	//库标志	8	+0	缺省为Device
	memcpy(m_HubMsgData,"Device",6);

	//库文件长度	4	+8	(单位字节)
	ULongInt(m_HubMsgData+8)=NewFileSize*1024L;


	//系统区大小	4	+12
	ULongInt(m_HubMsgData+12)=(NewFileSize/167*64*192);

	//最大存储表数	2	+16
	UShortInt(m_HubMsgData+16)=(unsigned short int)(NewFileSize/167*64)-1;

	//集中器编号	4	+24	缺省:1234567890
	ULongInt(m_HubMsgData+24)=1234567890L;

	//一般用户密码	4	+28	缺省:1234
	ULongInt(m_HubMsgData+28)=GetPWDLongIntValue("1234",4);
	//超级用户密码	4	+32	缺省:12345678
	ULongInt(m_HubMsgData+32)=GetPWDLongIntValue("12345678",8);

	//CRC校验码	4	+188	前188字节
	ULongInt(m_HubMsgData+188)=GetFileDataCrc(m_HubMsgData,188);

	//创建文件,文件大小为:NewFileSize
	FILE *fp=fopen(DbsFileName,"wb");
	char buf[1024]={0};
	cprintf("\r\nCreateNewDbs(%ldK)...",NewFileSize);

	for(;NewFileSize>0;NewFileSize--)
	{
		fwrite(buf,1024,1,fp);
		if(NewFileSize%2048==0) cprintf(" %2lu",NewFileSize/2048);
	}
	fseek(fp,0,SEEK_SET);
	fwrite(m_HubMsgData,192,1,fp);
	fclose(fp);
	cprintf("...OK");
	return 0;
}

//1=错误 0=OK
int CDbsFile::CheckDBSFileHead(FILE *fp)
{
	long FileLen;
	char buf[192]={1};
	fseek(fp,0,SEEK_SET);
	if(fread(buf,192,1,fp)!=1) return 0;
	if(ULongInt(buf+188)!=GetFileDataCrc(buf,188)) return 1;
	fseek(fp,0,SEEK_END);
	FileLen=ftell(fp);
	if(memcmp(buf,"Device",6)
	||(LongInt(buf+8)!=FileLen)
	||(LongInt(buf+12)!=FileLen*12/167)
	||(UShortInt(buf+16)!=FileLen/2672-1)) return 1;
	return 0;
}

void CDbsFile::ReadDBS()
{
	m_DBSFile=fopen(DbsFileName,"rb+");
	if((!m_DBSFile)||CheckDBSFileHead(m_DBSFile))
	{
		if(m_DBSFile) fclose(m_DBSFile);
		CreateNewDbs();	
		m_DBSFile=fopen(DbsFileName,"rb+");
		if(!m_DBSFile) return ;
	}
	fseek(m_DBSFile,0,SEEK_SET);
	fread(m_HubMsgData,192,1,m_DBSFile);
	m_DataOffset=ULongInt(m_HubMsgData+12);
	m_CurMeterCount=0;
	m_MaxMeterCount=UShortInt(m_HubMsgData+16);
	if(!m_Dbs.SetSize(m_MaxMeterCount+1))
	{
		m_ErrorCode=1;
		return;
	}
	
	struct CMemMeter NewMemMeter={0},TempMeter;
	long k,i;
	char buf[192];
	m_Dbs[0]=NewMemMeter;

	for(k=1;k<=m_MaxMeterCount;k++)
	{
		fread(buf,192,1,m_DBSFile);

		memset(&NewMemMeter,0,sizeof(struct CMemMeter));
		if(ULongInt(buf+188)==GetFileDataCrc(buf,188) && UShortInt(buf)!=0)
		{
			m_CurMeterCount++;
			NewMemMeter.MeterNo=UShortInt(buf);
			//NewMemMeter.TransformerId;		//区号:台变标识
			//NewMemMeter.uArea;				//片号:片区号,该表所在片区号
			//NewMemMeter.SpecialMeter
			//NewMemMeter.uRelay[5];				//中继信息:最高位=0无效,1=有效,低四位为中继水平。
		}
		else NewMemMeter.MeterNo=0xFFFF;

		NewMemMeter.uFileIndex=(unsigned short)k;//0为中继中继表号 ???k-1"???

		//按表号从小到大排序,插入排序到数据库中
		i=k-1;
		TempMeter=m_Dbs[i];
		while(TempMeter.MeterNo>NewMemMeter.MeterNo)
		{
			m_Dbs[i+1]=TempMeter;
			i--;
			TempMeter=m_Dbs[i];
		}
		m_Dbs[i+1]=NewMemMeter;
	}
}
unsigned short int CDbsFile::FindMeterMemoryIndex(unsigned short MeterNo)
{
	if((MeterNo==0)||(MeterNo==0xFFFF)) return 0;
	unsigned short int low=1,high=m_CurMeterCount,mid;
	unsigned long int MidMeterNo;
	while(low<=high)
	{
		mid=(low+high)/2;
		MidMeterNo=m_Dbs[mid].MeterNo;
		if(MeterNo>MidMeterNo) low=mid+1;
		else if(MeterNo<MidMeterNo) high=mid-1;
		else return mid;
	}
	return 0;
}
////////////////////////////////////////////////////////////////////////////
// 数据库操作
////////////////////////////////////////////////////////////////////////////
//清除所有的表。
void CDbsFile::EmptyAllMeter()
{
	struct CMemMeter *ptrMemMeter;
	long k;
	char buf[1024]={0};

	PreEmptyAllMeter(ULongInt(m_HubMsgData+8));
	
	//清楚数据库数据
	fseek(m_DBSFile,192,SEEK_SET);
	fwrite(buf,1024-192,1,m_DBSFile);
	for(k=ULongInt(m_HubMsgData+8)/1024-1;k>0;k--) fwrite(buf,1024,1,m_DBSFile);
	flush(m_DBSFile);

	//清楚内存数据	
	for(k=1;k<=m_MaxMeterCount;k++)
	{
		ptrMemMeter=m_Dbs.GetAddr(k);
		ptrMemMeter->MeterNo=0xFFFF;
		ptrMemMeter->uFileIndex=(unsigned short)k;
	}
	m_CurMeterCount=0;

	//清除swp文件的数据
	ClearSwpFile();
}
//写系统区的第Position个192字节
void CDbsFile::WriteBasicMeterDataToFile(unsigned char data[], int Position)
{
	if(!m_DBSFile)
	{
		cprintf("\r\nSYSTEM ERROR:m_DBSFile is NULL");
		return;
	}
	ULongInt(data+188)=GetFileDataCrc(data,188);
	if(Position==0) memcpy(m_HubMsgData,data,192);

	//先写swp文件
	PreWriteDataToSwpFile(data,Position);

	//再写到数据库中
	fseek(m_DBSFile,Position*192L,SEEK_SET);
	fwrite(data,192,1,m_DBSFile);
	flush(m_DBSFile);

	//清除swp文件的数据
	ClearSwpFile();
}
void CDbsFile::AppendORModifyMeter(const char *Data)
{
	unsigned short int NewMeterNO=UShortInt(Data);
	struct CMemMeter *ptrMeterMem=FindMeterMemoryAddr(NewMeterNO);
	if(ptrMeterMem)
	{
		//修改表资料
		cprintf(" %u(*)",NewMeterNO);
	}
	else
	{
		//增加新表
		cprintf(" %u(+)",NewMeterNO);

	}
}
void CDbsFile::DeleteMeter(const unsigned short delMeterNo)
{
	unsigned short DelIndex=FindMeterMemoryIndex(delMeterNo);
	cprintf(" %u(-)",delMeterNo);
	if(DelIndex)
	{
		long k;
		unsigned char buf[192]={0};
		unsigned short DelMeterFileIndex;

		struct CMemMeter TempMeter;
		DelMeterFileIndex=m_Dbs[DelIndex].uFileIndex;

		//先写swp文件
		PreWriteDataToSwpFile(buf,DelMeterFileIndex);

		//清除文件内容
		fseek(m_DBSFile,DelMeterFileIndex*192L,SEEK_SET);
		fwrite(buf,192,1,m_DBSFile);
		flush(m_DBSFile);

		//清除swp文件的数据
		ClearSwpFile();

		//删除内存表号。移动到最后
		for(k=DelIndex;k<m_CurMeterCount;k++)
		{
			TempMeter=m_Dbs[k+1];
			m_Dbs[k]=TempMeter;
		}

		memset(&TempMeter,0,sizeof(struct CMemMeter));
		TempMeter.MeterNo=0xFFFF;
		TempMeter.uFileIndex=DelMeterFileIndex;
		m_Dbs[m_CurMeterCount]=TempMeter;
		m_CurMeterCount--;

	}
}

⌨️ 快捷键说明

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