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

📄 netbuff.cpp

📁 自己动手写操作系统源代码,不可多得的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//

static __NET_BUFFER* NetBufferGet(__NET_BUFFER* lpNetBuffer)
{
	if(NULL == lpNetBuffer)    //Parameter check.
		return NULL;
	AtomicInc(&lpNetBuffer->Users);    //Increment the reference counter.
	return lpNetBuffer;
}

//
//The implementation of NetBufferPull.
//

static UCHAR* NetBufferPull(__NET_BUFFER* lpNetBuffer,INT nOffset)
{
	DWORD                   dwFlags                   = 0L;

	if(NULL == lpNetBuffer)    //Parameter check.
		return NULL;
	if(NET_BUFFER_SHARED(lpNetBuffer)) //The net buffer is shared by other entities.
		return NULL;
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	lpNetBuffer->lpDataHdr += nOffset;
	if(lpNetBuffer->lpDataHdr < lpNetBuffer->lpBufferHdr)  //The nOffset is negative,and
		                                                   //it exceed the headroom.
	{
		lpNetBuffer->lpDataHdr -= nOffset;
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return NULL;
	}
	if(lpNetBuffer->lpDataHdr >= lpNetBuffer->lpDataEnd)  //Exceed valid range.
	{
		lpNetBuffer->lpDataHdr -= nOffset;
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return NULL;
	}
	lpNetBuffer->dwDataLen  += nOffset;    //Update the data length.
	lpNetBuffer->dwTotalLen += nOffset;    //Update the tatol length.
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	return lpNetBuffer->lpDataHdr;             //Returns the start address of data area.
}

//
//The implementation of NetBufferPush.
//

static UCHAR* NetBufferPush(__NET_BUFFER* lpNetBuffer,INT nOffset)
{
	DWORD                   dwFlags                   = 0L;

	if(NULL == lpNetBuffer)    //Parameter check.
		return NULL;
	if(NET_BUFFER_SHARED(lpNetBuffer)) //The net buffer is shared by other entities.
		return NULL;
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	lpNetBuffer->lpDataHdr -= nOffset;
	if(lpNetBuffer->lpDataHdr < lpNetBuffer->lpBufferHdr)  //The nOffset is larger than
		                                                   //data buffer's headroom.
	{
		lpNetBuffer->lpDataHdr += nOffset;
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return NULL;
	}
	if(lpNetBuffer->lpDataHdr >= lpNetBuffer->lpDataEnd)  //The nOffset is negative,and
		                                                  //it's absolute value is larger than
														  //data area.
	{
		lpNetBuffer->lpDataHdr += nOffset;
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return NULL;
	}
	lpNetBuffer->dwDataLen  -= nOffset;
	lpNetBuffer->dwTotalLen -= nOffset;
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	return lpNetBuffer->lpDataHdr;             //Returns the start address of data area.
}

//
//The implementation of NetBufferPut.
//

static UCHAR* NetBufferPut(__NET_BUFFER* lpNetBuffer,INT nOffset)
{
	DWORD                  dwFlags                   = 0L;
	UCHAR*                 lpTmp                     = NULL;

	if(NULL == lpNetBuffer)    //Parameter check.
		return NULL;
	if(NET_BUFFER_SHARED(lpNetBuffer)) //The net buffer object is shared by other entity.
		return NULL;

	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	lpTmp = lpNetBuffer->lpDataEnd;
	lpNetBuffer->lpDataEnd += nOffset;    //Add the offset.
	if(lpNetBuffer->lpDataEnd <= lpNetBuffer->lpDataHdr)  //Exceed the data area.
	{
		lpNetBuffer->lpDataEnd -= nOffset; //Restore the initial value.
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return NULL;
	}
	if(lpNetBuffer->lpDataEnd > lpNetBuffer->lpBufferEnd) //The nOffset larger than tailroom.
	{
		lpNetBuffer->lpDataEnd -= nOffset;
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return NULL;
	}
	lpNetBuffer->dwDataLen  += nOffset;
	lpNetBuffer->dwTotalLen += nOffset;
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	return lpTmp;
}

//
//The implementation of NetBufferReserve.
//

static BOOL NetBufferReserve(__NET_BUFFER* lpNetBuffer,INT nLen)
{
	DWORD                    dwFlags                   = 0L;

	if(NULL == lpNetBuffer)  //Parameter check.
		return FALSE;
	if(NET_BUFFER_SHARED(lpNetBuffer))  //The net buffer object is shared by other entity.
		return FALSE;
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	lpNetBuffer->lpDataHdr  += nLen;
	lpNetBuffer->lpDataEnd  += nLen;
	if((lpNetBuffer->lpDataHdr <  lpNetBuffer->lpBufferHdr) ||
	   (lpNetBuffer->lpDataEnd >= lpNetBuffer->lpBufferEnd))    //Exceed valid range.
	{
		lpNetBuffer->lpDataEnd -= nLen;
		lpNetBuffer->lpDataHdr -= nLen;
		//__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return NULL;
	}
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	return TRUE;
}

//
//The implementation of NetBufferStore.
//In current implementation,this routine can be replaced by NetBufferPut routine,because
//the NetBufferStore routine does not process the fragment data.
//

static BOOL NetBufferStore(__NET_BUFFER* lpNetBuffer,INT nOffset,UCHAR* lpSrc,DWORD dwLen)
{
	return FALSE;
}

//
//The implementation of NetBufferSave.
//

static BOOL NetBufferSave(__NET_BUFFER* lpNetBuffer,INT nOffset,UCHAR* lpDes,DWORD dwLen)
{
	return FALSE;
}

//
//The implementation of NetBufferExpand.
//This routine create a new data buffer,copy the old data buffer's data into the new one,
//and append all fragment data of old data buffer to new one,then release the old data
//buffer.
//If the net buffer or data buffer is shared,then only returns FALSE.
//

static BOOL NetBufferExpand(__NET_BUFFER* lpNetBuffer,DWORD dwHeadroom,DWORD dwTailroom)
{
	__FRAG_DATA*           lpFragData                 = NULL;
	__NET_BUFFER*          lpNetBuff                  = NULL;
	DWORD                  dwFlags                    = 0L;
	DWORD                  dwBuffSize                 = 0L;
	UCHAR*                 lpTmpBuff                  = NULL;
	UCHAR*                 lpDataStart                = NULL;

	if(NULL == lpNetBuffer) //Parameter check.
		return FALSE;
	if(NET_BUFFER_SHARED(lpNetBuffer)) //The net buffer is shared.
		return FALSE;
	lpFragData = NET_BUFFER_FRAG_DATA(lpNetBuffer);  //Get fragment data.
	if(AtomicGet(&lpFragData->SharedCounter) != 1)   //The data buffer is shared also.
		return FALSE;
	dwBuffSize = NET_BUFFER_DATA_LEN(lpNetBuffer) + dwHeadroom + dwTailroom;
	lpTmpBuff  = ALLOC_DATA_MEMORY(dwBuffSize);
	if(NULL == lpTmpBuff)    //Can not allocate data memory.
		return FALSE;
	lpDataStart = lpTmpBuff + dwHeadroom;
	MemCpy(lpDataStart,lpNetBuffer->lpDataHdr,NET_BUFFER_DATA_LEN(lpNetBuffer));  //Copy data.
	lpDataStart += NET_BUFFER_DATA_LEN(lpNetBuffer);
	lpDataStart += dwTailroom;
	MemCpy(lpDataStart,lpNetBuffer->lpBufferEnd,FRAG_DATA_SIZE);  //Copy fragment data.
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	FREE_DATA_MEMORY(lpNetBuffer->lpBufferHdr);    //Release the old data buffer.
	lpNetBuffer->lpBufferHdr  = lpTmpBuff;
	lpNetBuffer->lpBufferEnd  = lpDataStart;
	lpNetBuffer->lpDataHdr    = lpTmpBuff + dwHeadroom;
	lpNetBuffer->lpDataEnd    = lpDataStart - dwTailroom;
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	return TRUE;
}

//
//The implementation of NetBufferAppendFrag.
//This routine add a fragment data to the net buffer's frag data list.
//If the current data buffer or the net buffer object is shared,this 
//routine will do nothing,only returns FALSE.
//Parameters:
// @lpNetBuffer : The net buffer object which fragment data will be appended to.
// @lpAppended  : The net buffer object which will be appended.
//That is,this routine will put lpAppended to lpNetBuffer's fragment data.
//

static BOOL NetBufferAppendFrag(__NET_BUFFER* lpNetBuffer,__NET_BUFFER* lpAppended)
{
	__FRAG_DATA*                lpFragData                = NULL;
	DWORD                       dwFlags                   = 0L;

	if((NULL == lpNetBuffer) || (NULL == lpAppended)) //Parameter check.
		return FALSE;
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	if(NET_BUFFER_SHARED(lpNetBuffer))    //The target net buffer is shared.
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return FALSE;
	}
	lpFragData = NET_BUFFER_FRAG_DATA(lpNetBuffer);   //Get the fragment control block.
	if(AtomicGet(&lpFragData->SharedCounter) != 1)    //The data buffer is shared.
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return FALSE;
	}
	//
	//The following code append the lpAppended to the fragment list.
	//
	NetBufferGet(lpAppended);    //Increment the reference counter.
	lpFragData->FragQueue.InsertIntoQueue(&lpFragData->FragQueue,lpAppended);  //Insert into queue.
	lpNetBuffer->dwTotalLen += NET_BUFFER_DATA_LEN(lpAppended);  //Update total length.
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	return TRUE;
}

//
//The implementation of NetBufferGetFrag.
//This routine gets the first fragment data from fragment list.
//If the net buffer object is shared,or the data buffer is shared,
//this routine will do nothing,only returns a NULL.
//

static __NET_BUFFER* NetBufferGetFrag(__NET_BUFFER* lpNetBuffer)
{
	return NULL;
}

//
//The implementation of NetBufferCopy.
//

static __NET_BUFFER* NetBufferCopy(__NET_BUFFER* lpNetBuffer)
{
	return NULL;
}

//
//The implementation of NetBufferSharedCopy.
//

static __NET_BUFFER* NetBufferSharedCopy(__NET_BUFFER* lpNetBuffer)
{
	return NULL;
}

//
//The implementation of NetBufferPackCopy.
//This routine allocates a new net buffer object and a new data buffer,
//then copies the data buffer,including fragment data,into the new data buffer,
//and returns the new created net buffer object.
//

static __NET_BUFFER* NetBufferPackCopy(__NET_BUFFER_MANAGER* lpManager,__NET_BUFFER* lpNetBuffer)
{
	__NET_BUFFER*                     lpNetBuff      = NULL;
	__NET_BUFFER*                     lpFragBuff     = NULL;
	__FRAG_DATA*                      lpFragData     = NULL;
	DWORD                             dwFlags        = 0L;
	DWORD                             dwBuffSize     = 0L;
	UCHAR*                            lpDataBuff     = NULL;

	if(NULL == lpNetBuffer)    //Parameter check.
		return NULL;
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	dwBuffSize  = NET_BUFFER_TOTAL_LEN(lpNetBuffer);  //Get the total length.
	dwBuffSize += NET_BUFFER_HEADROOM(lpNetBuffer);
	dwBuffSize += NET_BUFFER_TAILROOM(lpNetBuffer);
	lpNetBuff  = NetBufferAlloc(lpManager,dwBuffSize);  //Allocate a new net buffer object.
	if(NULL == lpNetBuff)     //Can not allocate net buffer object,may caused by less memory.
	{
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return NULL;
	}
	NetBufferReserve(lpNetBuff,NET_BUFFER_HEADROOM(lpNetBuffer));  //Reserve head room.
	MemCpy((LPVOID)NetBufferPut(lpNetBuff,NET_BUFFER_DATA_LEN(lpNetBuffer)),
		lpNetBuffer->lpDataHdr,NET_BUFFER_DATA_LEN(lpNetBuffer));  //Copy data.
	lpFragData = NET_BUFFER_FRAG_DATA(lpNetBuffer);
	DWORD dwQueueLen = lpFragData->FragQueue.GetQueueLen(&lpFragData->FragQueue);
	for(DWORD dwLoop = 0;dwLoop < dwQueueLen;dwLoop ++)  //Copy fragment data.
	{
		lpFragBuff = lpFragData->FragQueue.GetFromQueue(&lpFragData->FragQueue);
		MemCpy((LPVOID)NetBufferPut(lpNetBuff,NET_BUFFER_DATA_LEN(lpFragBuff)),
			lpFragBuff->lpDataHdr,NET_BUFFER_DATA_LEN(lpFragBuff));
		lpFragData->FragQueue.InsertIntoQueue(&lpFragData->FragQueue,
			lpFragBuff);    //Re-insert into the frag queue again.
	}
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
	return lpNetBuff;
}

//
//The implementation of NetBufferClone.
//

static __NET_BUFFER* NetBufferClone(__NET_BUFFER* lpNetBuffer)
{
	return NULL;
}

//
//The implementation of Initialize.
//

static BOOL ManagerInitialize(__NET_BUFFER_MANAGER* lpManager)
{
	if(NULL == lpManager)    //Parameter check.
		return FALSE;

	lpManager->FreeBufferLink.lpNext       = NULL;
	lpManager->FreeBufferLink.dwLinkLen    = 0L;
	lpManager->Initialize                  = ManagerInitialize;
	lpManager->NetBufferAlloc              = NetBufferAlloc;
	lpManager->NetBufferFreeData           = NetBufferFreeData;
	lpManager->NetBufferFree               = NetBufferFree;
	lpManager->NetBufferGet                = NetBufferGet;
	lpManager->NetBufferPull               = NetBufferPull;
	lpManager->NetBufferPush               = NetBufferPush;
	lpManager->NetBufferPut                = NetBufferPut;
	lpManager->NetBufferReserve            = NetBufferReserve;
	lpManager->NetBufferStore              = NetBufferStore;
	lpManager->NetBufferSave               = NetBufferSave;
	lpManager->NetBufferExpand             = NetBufferExpand;
	lpManager->NetBufferAppendFrag         = NetBufferAppendFrag;
	lpManager->NetBufferGetFrag            = NetBufferGetFrag;
	lpManager->NetBufferCopy               = NetBufferCopy;
	lpManager->NetBufferSharedCopy         = NetBufferSharedCopy;
	lpManager->NetBufferPackCopy           = NetBufferPackCopy;
	lpManager->NetBufferClone              = NetBufferClone;

	return TRUE;
}

/*************************************************************************************
**************************************************************************************
**************************************************************************************
**************************************************************************************
*************************************************************************************/

//
//Global object : NetBufferManager.
//This object is used by all network entitis to operate net buffers.
//

__NET_BUFFER_MANAGER NetBufferManager;

⌨️ 快捷键说明

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