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

📄 session_data.cpp

📁 朋友的作品
💻 CPP
字号:

#include "session_data.h"
#include <assert.h>
#include <stdio.h>

session_buf_full::session_buf_full(const string & s):runtime_error(s){}

CSessionData::CSessionData()
{
	_data_head = NULL;
	_list_arr = NULL;
	_data_ptr = NULL;
}

CSessionData::~CSessionData()
{
	_data_head = NULL;
	_list_arr = NULL;
	_data_ptr = NULL;
}

void CSessionData::Create(char * pBuf, unsigned buflen, size_t datanum, size_t datasize)
throw (runtime_error)
{
	assert(pBuf);
	assert(datanum>1);
	assert(datasize>0);
	unsigned len = CalBufLen(datanum, datasize);
	if(buflen<len) {
		char sTmp[128];
		sprintf(sTmp,"CSessionData::Create: buflen(%u)<len(%u)",buflen,len);
		throw runtime_error(sTmp);
	}
	_data_head = (Data_Head *)pBuf;
	_data_head->buf_len = len;
	_data_head->data_num = datanum;
	_data_head->data_size = datasize;
	_data_head->used_num = 0;
	_data_head->unused_head = 0; //0

	_list_arr = (DList *)(pBuf+Head_Length);
	_list_arr[0].previous = datanum-1;
	_list_arr[0].next = 1;
	_list_arr[0].stat = 0;
	for(unsigned i=1;i<datanum;i++) {
		_list_arr[i].previous = i-1;
		_list_arr[i].next = i+1;
		_list_arr[i].stat = 0;
	}
	_list_arr[datanum-1].next = 0;

	_data_ptr = pBuf+Head_Length+sizeof(DList)*datanum;
}

void CSessionData::Attach(char * pBuf, unsigned buflen, size_t datanum,size_t datasize)
throw (runtime_error)
{
	assert(pBuf);
	assert(buflen>Head_Length);

	_data_head = (Data_Head *)pBuf;
	if(buflen!=_data_head->buf_len) {
		char sTmp[128];
		sprintf(sTmp,"CSessionData::Attach: buflen(%u)!=len(%u)",buflen,_data_head->buf_len);
		throw runtime_error(sTmp);
	}
	if(datanum!=_data_head->data_num) {
		char sTmp[128];
		sprintf(sTmp,"CSessionData::Attach: datanum(%u)!=data_num(%u)",datanum,_data_head->data_num);
		throw runtime_error(sTmp);
	}
	if(datasize!=_data_head->data_size) {
		char sTmp[128];
		sprintf(sTmp,"CSessionData::Attach: datasize(%u)!=datasize(%u)",datasize,_data_head->data_size);
		throw runtime_error(sTmp);
	}
	unsigned len = CalBufLen(_data_head->data_num, _data_head->data_size);
	if(len!=buflen) {
		char sTmp[128];
		sprintf(sTmp,"CSessionData::Attach: buflen(%u)!=callen(%u)",buflen,len);
		throw runtime_error(sTmp);
	}

	if(_data_head->unused_head>=(int)_data_head->data_num) {
		char sTmp[128];
		sprintf(sTmp,"CSessionData::Attach: unused_head(%u)>=data_num(%u)"
			,_data_head->unused_head,_data_head->data_num);
		throw runtime_error(sTmp);
	}
	if(_data_head->unused_head==-1) {
		if(_data_head->used_num!=_data_head->data_num) {
			char sTmp[128];
			sprintf(sTmp,"CSessionData::Attach: unused_head=-1,but used_num!=data_num(%u)"
				,_data_head->data_num);
			throw runtime_error(sTmp);
		}
	}

	unsigned used_num=0;
	_list_arr = (DList *)(pBuf+Head_Length);
	for(unsigned i=0;i<_data_head->data_num;i++) {
		if(_list_arr[i].stat == 1) used_num++;
	}
	if(_data_head->used_num!=used_num) {
		char sTmp[128];
		sprintf(sTmp,"CSessionData::Attach: used_num(%u)!=real_used_num(%u)"
			,_data_head->data_num,used_num);
		throw runtime_error(sTmp);
	}

	// 还要检查链表的正确性

	_data_ptr = pBuf+Head_Length+sizeof(DList)*_data_head->data_num;
}

char * CSessionData::GetData(unsigned index)
{
	assert(index<_data_head->data_num);
	if(_list_arr[index].stat == 0) return NULL;
	return _data_ptr+(_data_head->data_size * index);
}

unsigned CSessionData::AllocData() throw(session_buf_full)
{
	if(_data_head->unused_head == -1) {
		throw session_buf_full("sesion buf full");
	}
	unsigned index = _data_head->unused_head;
	DList * pHead = _list_arr+index;
	assert(pHead->stat == 0);

	if(pHead->previous == -1) { // 1->0
		assert(pHead->next == -1);
		_data_head->unused_head = -1;
	}
	else {
		assert(pHead->next >= 0);
		DList * pre = _list_arr+pHead->previous;
		DList * post = _list_arr+pHead->next;
		if(pre == post) { // 2->1
			post->previous = -1;
			post->next = -1;
		}
		else {
			pre->next = post-_list_arr;
			post->previous = pre-_list_arr;
		}
		_data_head->unused_head = post-_list_arr;		
		pHead->previous = -1;
		pHead->next = -1;
	}
	pHead->stat = 1;
	_data_head->used_num++;
	return index;
}

void CSessionData::FreeData(unsigned index)
{
	assert(index<_data_head->data_num);
	DList * pDest = _list_arr+index;
	if(pDest->stat == 0) return;

	if(_data_head->unused_head == -1) { // 0->1
		assert(_data_head->used_num == _data_head->data_num);
		_data_head->unused_head = index;
		pDest->previous = -1;
		pDest->next = -1;
	}
	else { 
		DList * pHead = _list_arr+_data_head->unused_head;
		if(pHead->previous == -1) { // 1->2
			assert(pHead->next == -1);
			pHead->previous = index;
			pHead->next = index;
			pDest->previous = _data_head->unused_head;
			pDest->next = _data_head->unused_head;
		}
		else { // 2->x
			assert(pHead->next >= 0);
			DList * pTail = _list_arr+pHead->previous;
			pHead->previous = index;
			pTail->next = index;
			pDest->previous = pTail - _list_arr;
			pDest->next = _data_head->unused_head;
		}
	}

	pDest->stat = 0;
	assert(_data_head->used_num>0);
	_data_head->used_num--;
}

void CSessionData::DumpBuf(const char * pBuf,size_t iBufLen)
{
	if(iBufLen < sizeof(Data_Head)) {
		cout << "CSessionData::DumpBuf: iBufLen is too small " << iBufLen << endl;
		return;
	}

	Data_Head * pHead = (Data_Head *)pBuf;
	cout << "CSessionData::DumpBuf" << endl;
	cout << "---------Head---------" << endl;	
	cout << "buf_len:" << pHead->buf_len  << "\n"
		<< "data_num:" << pHead->data_num << "\n"
		<< "data_size:" << pHead->data_size << "\n"
		<< "used_num:" << pHead->used_num << "\n"
		<< "unused_head:" << pHead->unused_head 
		<< endl;

	if(iBufLen < pHead->buf_len) {
		cout << "CSessionData::DumpBuf: iBufLen " << iBufLen << "<" << pHead->buf_len << endl;
		return;
	}

	cout << "---------List---------" << endl;	
	cout << "len = " << sizeof(DList)*pHead->data_num << endl;
	cout << "---------Data---------" << endl;	
	cout << "len = " << pHead->buf_len - Head_Length - sizeof(DList)*pHead->data_num << endl;

}

⌨️ 快捷键说明

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