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

📄 databuffer.cpp

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 CPP
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// DataBuffer.cpp: implementation of the DataBuffer class.
// 
// DataBuffer is a simple circular dynamical databuffer that wraps around and
// may dynamically expand its size
//
//////////////////////////////////////////////////////////////////////
#include <windows.h>
#include "DataBuffer.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

//We initialize the size to two bytes more than asked for to 
//allow the readposition to never reach the writeposition
DataBuffer::DataBuffer(DWORD initialsize)
{
	mBuffer = new BYTE[initialsize+2];
	mTotalSize=initialsize +2;
	Flush();
}

DataBuffer::~DataBuffer()
{
	delete[] mBuffer;
}


//Assignment operator
DataBuffer	&
DataBuffer::operator=(DataBuffer &rhs)
{
	BOOL fRet = TRUE;
	
	if(&rhs==this) return *this;

	DWORD size = rhs.DataAvailable();
	if(mTotalSize < size) {
		fRet = IncreaseBuffer(size - mTotalSize);
	}

	if (! fRet) {
		DEBUGMSG(1, (L"WCESTREAMBT - Can't write data due to OOM.\n"));
		return *this;
	}

	BYTE *buf = new BYTE[size];
	rhs.ReadData(buf,size);
	WriteData(buf,size);

	delete[] buf;
	return *this;

}


//DataAvailable: return the amount of data currently stored
DWORD
DataBuffer::DataAvailable()
{
	return GetContentSize();
}


//WriteData: Store the requested data in our buffer. Increase buffer if needed.
// Wrap around if needed.
void
DataBuffer::WriteData(BYTE *buf, DWORD size)
{
	BOOL fRet = TRUE;

	if(size > GetEmptySpace()) {
		fRet = IncreaseBuffer(size);
	}

	if (! fRet) {
		DEBUGMSG(1, (L"WCESTREAMBT - Can't write data due to OOM.\n"));
		return;
	}

	//Now we know there is space
	if(mWritePos + size > mTotalSize)//we will wrap around
	{
		DWORD firstpart = mTotalSize - mWritePos;
		DWORD secondpart = size - firstpart;
		memcpy(mBuffer + mWritePos,buf,firstpart);
		memcpy(mBuffer,buf + firstpart,secondpart);
		mWritePos = secondpart;
	}
	else//we won't wrap around
	{
		memcpy(mBuffer + mWritePos,buf,size);
		mWritePos = mWritePos + size;
	}
}


//ReadData: Read the requested amount of data from our buffer. Correct the read-position
//afterwards
DWORD
DataBuffer::ReadData(BYTE *buf, DWORD size)
{
	DWORD thisread=0;
	if(GetContentSize() >= size) thisread = size;
	else thisread = GetContentSize();

	if(thisread + mReadPos > mTotalSize)// we will wrap around
	{
		DWORD firstpart = mTotalSize - mReadPos;
		DWORD secondpart = thisread - firstpart;
		memcpy(buf,mBuffer + mReadPos,firstpart);
		memcpy(buf + firstpart,mBuffer,secondpart);
		mReadPos = secondpart;
	}
	else//we won't wrap around
	{
		memcpy(buf,mBuffer + mReadPos,thisread);
		mReadPos = mReadPos + thisread;
	}

	return thisread;
}



//Read in data into the passed in DataBuffer.
DWORD
DataBuffer::ReadData(DataBuffer *db,DWORD size)
{
	DWORD thisread=0;
	if(GetContentSize() >= size) thisread = size;
	else thisread = GetContentSize();

	BYTE *temp = new BYTE[thisread];
	ReadData(temp,thisread);
	db->WriteData(temp,thisread);
	delete[] temp;
	return thisread;
}


//Drop this amount of data
void
DataBuffer::DropData(DWORD size)
{
	DWORD thisread=0;
	if(GetContentSize() >= size) thisread = size;
	else thisread = GetContentSize();

	if(thisread + mReadPos > mTotalSize)// we will wrap around
	{
		DWORD firstpart = mTotalSize - mReadPos;
		DWORD secondpart = thisread - firstpart;
		mReadPos = secondpart;
	}
	else//we won't wrap around
	{
		mReadPos = mReadPos + thisread;
	}
}


//Reset the write- and read-positions to zero.
void
DataBuffer::Flush()
{
	mWritePos=0;
	mReadPos=0;
}

//////////////////////////////////////////////////////
// Internal helper methods
///////////////////////////////////////////////////////

//IncreaseBuffer: Increase the buffersize with the requested amount
//and copy existing data into the new buffer
BOOL
DataBuffer::IncreaseBuffer(DWORD size)
{
	BYTE *temp = mBuffer;
	DWORD currentcontent = GetContentSize();
	mBuffer = new BYTE[mTotalSize + size];

	if (! mBuffer)
	{
		mBuffer = temp; // assign back to old value
		DEBUGMSG(1, (L"WCESTREAMBT - OOM!\n"));
		return FALSE;
	}	
	
	//Copy the content to the new buffer
	if(mWritePos >= mReadPos)//No wrap around
	{
		memcpy(mBuffer,temp + mReadPos,currentcontent);
	}
	else//wrap around
	{
		DWORD firstpart = mTotalSize - mReadPos;
		DWORD secondpart = mWritePos;
		memcpy(mBuffer,temp + mReadPos,firstpart);
		memcpy(mBuffer + firstpart,temp,secondpart);
	}
	
	//Update sizes and pointers
	mTotalSize = mTotalSize + size;
	mReadPos = 0;
	mWritePos = currentcontent;

	delete[] temp;
	return TRUE;
}



//GetContentSize: return the amount of data available
DWORD
DataBuffer::GetContentSize()
{
	if(mWritePos>=mReadPos)//No wrap around
	{
		return mWritePos - mReadPos;
	}
	else
	{
		return mTotalSize + mWritePos - mReadPos;
	}
}


//GetEmptySpace: Return the amount of free space in the buffer
DWORD
DataBuffer::GetEmptySpace()
{
	return mTotalSize - GetContentSize() -2;//We always leave two empty bytes
}


//Peek into position pos in the data
BYTE
DataBuffer::Peek(DWORD pos)
{
	if(mReadPos + pos < mTotalSize) return mBuffer[mReadPos + pos];
	else return mBuffer[mReadPos + pos - mTotalSize];
}


//Return a pointer to the data at position pos. N.B: NOT THREAD SAFE!
//validbytes indicates how many bytes the caller wishes to look at. If our 
//buffer wraps around before we need to reshuffle data
BYTE *
DataBuffer::c_ptr(DWORD pos, DWORD validbytes)
{
	if(validbytes + mReadPos + pos > mTotalSize) ResetBuffer();

	return mBuffer + mReadPos + pos;
}


//Move all data to start of buffer (no wrap)
void 
DataBuffer::ResetBuffer()
{
	DWORD size = DataAvailable();
	BYTE *temp = new BYTE[size];
	if (temp)
	{
		ReadData(temp,size);
		memcpy(mBuffer,temp,size);
		mReadPos = 0;
		mWritePos = size;
		delete[] temp;
	}
}

⌨️ 快捷键说明

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