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