246 lines
5.2 KiB
C++
246 lines
5.2 KiB
C++
#include "StdAfx.h"
|
||
#include "Buffer.h"
|
||
|
||
#include <math.h>
|
||
|
||
|
||
#define U_PAGE_ALIGNMENT 3
|
||
#define F_PAGE_ALIGNMENT 3.0
|
||
|
||
CBuffer::CBuffer(void)
|
||
{
|
||
m_ulMaxLength = 0;
|
||
|
||
m_Ptr = m_Base = NULL;
|
||
|
||
InitializeCriticalSection(&m_cs);
|
||
}
|
||
|
||
CBuffer::~CBuffer(void)
|
||
{
|
||
if (m_Base) {
|
||
VirtualFree(m_Base, 0, MEM_RELEASE);
|
||
m_Base = NULL;
|
||
}
|
||
|
||
DeleteCriticalSection(&m_cs);
|
||
|
||
m_Base = m_Ptr = NULL;
|
||
m_ulMaxLength = 0;
|
||
}
|
||
|
||
|
||
ULONG CBuffer::RemoveCompletedBuffer(ULONG ulLength)
|
||
{
|
||
EnterCriticalSection(&m_cs);
|
||
|
||
if (ulLength > m_ulMaxLength) { //如果传进的长度比内存的长度还大
|
||
LeaveCriticalSection(&m_cs);
|
||
return 0;
|
||
}
|
||
if (ulLength > (m_Ptr - m_Base)) { //如果传进的长度 比有效的数据长度还大
|
||
ulLength = m_Ptr - m_Base;
|
||
}
|
||
|
||
if (ulLength) {
|
||
MoveMemory(m_Base,m_Base+ulLength, m_ulMaxLength - ulLength);
|
||
|
||
m_Ptr -= ulLength;
|
||
}
|
||
|
||
DeAllocateBuffer(m_Ptr - m_Base);
|
||
LeaveCriticalSection(&m_cs);
|
||
|
||
return ulLength;
|
||
}
|
||
|
||
ULONG CBuffer::ReadBuffer(PBYTE Buffer, ULONG ulLength)
|
||
{
|
||
EnterCriticalSection(&m_cs);
|
||
|
||
if (ulLength > m_ulMaxLength) {
|
||
LeaveCriticalSection(&m_cs);
|
||
return 0;
|
||
}
|
||
|
||
if (ulLength > (m_Ptr - m_Base)) {
|
||
ulLength = m_Ptr - m_Base;
|
||
}
|
||
|
||
if (ulLength) {
|
||
CopyMemory(Buffer,m_Base,ulLength);
|
||
|
||
MoveMemory(m_Base,m_Base+ulLength, m_ulMaxLength - ulLength);
|
||
m_Ptr -= ulLength;
|
||
}
|
||
|
||
DeAllocateBuffer(m_Ptr - m_Base);
|
||
|
||
LeaveCriticalSection(&m_cs);
|
||
return ulLength;
|
||
}
|
||
|
||
// 私有: 无需加锁
|
||
ULONG CBuffer::DeAllocateBuffer(ULONG ulLength)
|
||
{
|
||
if (ulLength < (m_Ptr - m_Base))
|
||
return 0;
|
||
|
||
ULONG ulNewMaxLength = (ULONG)ceil(ulLength / F_PAGE_ALIGNMENT) * U_PAGE_ALIGNMENT;
|
||
|
||
if (m_ulMaxLength <= ulNewMaxLength) {
|
||
return 0;
|
||
}
|
||
PBYTE NewBase = (PBYTE) VirtualAlloc(NULL,ulNewMaxLength,MEM_COMMIT,PAGE_READWRITE);
|
||
|
||
ULONG ulv1 = m_Ptr - m_Base; //算原先内存的有效长度
|
||
CopyMemory(NewBase,m_Base,ulv1);
|
||
|
||
VirtualFree(m_Base,0,MEM_RELEASE);
|
||
|
||
m_Base = NewBase;
|
||
|
||
m_Ptr = m_Base + ulv1;
|
||
|
||
m_ulMaxLength = ulNewMaxLength;
|
||
|
||
return m_ulMaxLength;
|
||
}
|
||
|
||
|
||
BOOL CBuffer::WriteBuffer(PBYTE Buffer, ULONG ulLength)
|
||
{
|
||
EnterCriticalSection(&m_cs);
|
||
|
||
if (ReAllocateBuffer(ulLength + (m_Ptr - m_Base)) == -1) { //10 +1 1024
|
||
LeaveCriticalSection(&m_cs);
|
||
return false;
|
||
}
|
||
|
||
CopyMemory(m_Ptr,Buffer,ulLength);
|
||
|
||
m_Ptr+=ulLength;
|
||
LeaveCriticalSection(&m_cs);
|
||
return TRUE;
|
||
}
|
||
|
||
// 私有: 无需加锁
|
||
ULONG CBuffer::ReAllocateBuffer(ULONG ulLength)
|
||
{
|
||
if (ulLength < m_ulMaxLength)
|
||
return 0;
|
||
|
||
ULONG ulNewMaxLength = (ULONG)ceil(ulLength / F_PAGE_ALIGNMENT) * U_PAGE_ALIGNMENT;
|
||
PBYTE NewBase = (PBYTE) VirtualAlloc(NULL,ulNewMaxLength,MEM_COMMIT,PAGE_READWRITE);
|
||
if (NewBase == NULL) {
|
||
return -1;
|
||
}
|
||
|
||
|
||
ULONG ulv1 = m_Ptr - m_Base; //原先的有效数据长度
|
||
|
||
CopyMemory(NewBase,m_Base,ulv1);
|
||
|
||
if (m_Base) {
|
||
VirtualFree(m_Base,0,MEM_RELEASE);
|
||
}
|
||
m_Base = NewBase;
|
||
m_Ptr = m_Base + ulv1; //1024
|
||
|
||
m_ulMaxLength = ulNewMaxLength; //2048
|
||
|
||
return m_ulMaxLength;
|
||
}
|
||
|
||
VOID CBuffer::ClearBuffer()
|
||
{
|
||
EnterCriticalSection(&m_cs);
|
||
m_Ptr = m_Base;
|
||
|
||
DeAllocateBuffer(1024);
|
||
LeaveCriticalSection(&m_cs);
|
||
}
|
||
|
||
ULONG CBuffer::GetBufferLength() // 获得有效数据长度
|
||
{
|
||
EnterCriticalSection(&m_cs);
|
||
if (m_Base == NULL) {
|
||
LeaveCriticalSection(&m_cs);
|
||
return 0;
|
||
}
|
||
ULONG len = m_Ptr - m_Base;
|
||
LeaveCriticalSection(&m_cs);
|
||
|
||
return len;
|
||
}
|
||
|
||
std::string CBuffer::Skip(ULONG ulPos)
|
||
{
|
||
if (ulPos == 0)
|
||
return "";
|
||
|
||
EnterCriticalSection(&m_cs);
|
||
std::string ret(m_Base, m_Base + ulPos);
|
||
MoveMemory(m_Base, m_Base + ulPos, m_ulMaxLength - ulPos);
|
||
m_Ptr -= ulPos;
|
||
|
||
LeaveCriticalSection(&m_cs);
|
||
return ret;
|
||
}
|
||
|
||
// 此函数不是多线程安全的. 只在远程桌面使用了.
|
||
LPBYTE CBuffer::GetBuffer(ULONG ulPos)
|
||
{
|
||
EnterCriticalSection(&m_cs);
|
||
if (m_Base==NULL || ulPos >= (m_Ptr - m_Base)) {
|
||
LeaveCriticalSection(&m_cs);
|
||
return NULL;
|
||
}
|
||
LPBYTE result = m_Base + ulPos;
|
||
LeaveCriticalSection(&m_cs);
|
||
|
||
return result;
|
||
}
|
||
|
||
// 此函数是多线程安全的. 获取缓存,得到Buffer对象.
|
||
Buffer CBuffer::GetMyBuffer(ULONG ulPos)
|
||
{
|
||
EnterCriticalSection(&m_cs);
|
||
ULONG len = m_Ptr - m_Base;
|
||
if (m_Base == NULL || ulPos >= len) {
|
||
LeaveCriticalSection(&m_cs);
|
||
return Buffer();
|
||
}
|
||
Buffer result = Buffer(m_Base+ulPos, len - ulPos);
|
||
LeaveCriticalSection(&m_cs);
|
||
|
||
return result;
|
||
}
|
||
|
||
// 此函数是多线程安全的. 获取缓存指定位置处的数值.
|
||
BYTE CBuffer::GetBYTE(ULONG ulPos)
|
||
{
|
||
EnterCriticalSection(&m_cs);
|
||
if (m_Base == NULL || ulPos >= (m_Ptr - m_Base)) {
|
||
LeaveCriticalSection(&m_cs);
|
||
return NULL;
|
||
}
|
||
BYTE p = *(m_Base + ulPos);
|
||
LeaveCriticalSection(&m_cs);
|
||
|
||
return p;
|
||
}
|
||
|
||
// 此函数是多线程安全的. 将缓存拷贝至目标内存中.
|
||
BOOL CBuffer::CopyBuffer(PVOID pDst, ULONG nLen, ULONG ulPos)
|
||
{
|
||
EnterCriticalSection(&m_cs);
|
||
ULONG len = m_Ptr - m_Base;
|
||
if (m_Base == NULL || len - ulPos < nLen) {
|
||
LeaveCriticalSection(&m_cs);
|
||
return FALSE;
|
||
}
|
||
memcpy(pDst, m_Base+ulPos, nLen);
|
||
LeaveCriticalSection(&m_cs);
|
||
return TRUE;
|
||
} |