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

📄 smartbuffer.cpp

📁 用UDP写的可靠传输程序源代码,非常有借鉴意义,适合互连网通讯
💻 CPP
字号:
// SmartBuffer - Buffer for handy network packets arrangement
// Implementation file
//
// (c) Lev Naumov, CAMEL Laboratory
// E-mail: camellab@mail.ru
// For more information see http://camel.ifmo.ru or
// http://www.codeproject.com/internet/ctp.asp
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "SmartBuffer.h"

SmartBuffer::SmartBuffer(unsigned int datasize, bool autodel, unsigned int headsize, unsigned int maxdatasize)
{
    // Store key values
    m_uDataSize=datasize;
    m_bAutoDel=autodel;
    m_uHeadSize=headsize;
    m_uMaxDataSize=maxdatasize;
    // Allocate buffer
    m_pBuffer=new char[m_uBufferSize=GetNeededBufferSize(m_uDataSize,m_uHeadSize,m_uMaxDataSize)];
    // Set current pointer to the begining
    m_pCurPtr=m_pBuffer+m_uHeadSize;
}

SmartBuffer::SmartBuffer(LPCTSTR fname, unsigned int datasize, bool autodel, unsigned int headsize, unsigned int maxdatasize)
{
    CStdioFile file(fname,CFile::modeRead|CFile::typeBinary);
    // Store key values
    unsigned int fsize=file.GetLength();
    m_uDataSize=fsize+datasize;
    m_bAutoDel=autodel;
    m_uHeadSize=headsize;
    m_uMaxDataSize=maxdatasize;
    // Allocate buffer
    m_pBuffer=new char[m_uBufferSize=GetNeededBufferSize(m_uDataSize,m_uHeadSize,m_uMaxDataSize)];
    // Set current pointer and temporary pointer to the begining
    m_pCurPtr=m_pBuffer+m_uHeadSize;
    char* ptr=m_pBuffer;
    // Skip space for prefile data
    while (datasize>m_uMaxDataSize) {
        datasize-=m_uMaxDataSize;
        ptr+=m_uHeadSize+m_uMaxDataSize;
    }
    // Copy file's content
    ptr+=m_uHeadSize+datasize;
    unsigned int read=0;
    do {
        read=file.Read(ptr,min(m_uMaxDataSize-datasize,fsize));
        ptr+=m_uHeadSize+read;
        fsize-=read;
        if (datasize) datasize=0;
    } while (fsize>0);
    file.Close();
}

void SmartBuffer::SetDataSize(unsigned int datasize)
{
    m_uDataSize=datasize;
    // Arrange new buffer
    unsigned int buffersize;
    char* buffer=new char[buffersize=GetNeededBufferSize(m_uDataSize,m_uHeadSize,m_uMaxDataSize)];
    memcpy(buffer,m_pBuffer,min(m_uBufferSize,buffersize));
    // Move current pointer to equivalent place in new buffer
    m_pCurPtr+=buffer-m_pBuffer;
    if (m_pCurPtr>buffer+buffersize) m_pCurPtr=buffer+buffersize;
    // Delete old buffer
    delete[] m_pBuffer;
    m_pBuffer=buffer;
}

bool SmartBuffer::PutHead(void* src, unsigned int i)
{
    char* ptr=GetHeadPtr(i);
    if (!ptr) return false;
    memcpy(ptr,src,m_uHeadSize);
    return true;
}

void SmartBuffer::DestToPtr(int dest, char*& ptr, unsigned int* prtnsize)
{
    if (dest<0) {
        ptr=m_pCurPtr;
        if ((unsigned int)(ptr-m_pBuffer)%(m_uHeadSize+m_uMaxDataSize)<m_uHeadSize) ptr=(ptr-m_pBuffer)/(m_uHeadSize+m_uMaxDataSize)*(m_uHeadSize+m_uMaxDataSize)+m_uHeadSize+m_pBuffer;
        if (prtnsize) *prtnsize=m_uMaxDataSize+m_uHeadSize-(ptr-m_pBuffer)%(m_uHeadSize+m_uMaxDataSize);
    } else {
        ptr=(dest/m_uMaxDataSize)*(m_uHeadSize+m_uMaxDataSize)+dest%m_uMaxDataSize+m_uHeadSize+m_pBuffer;
        if (prtnsize) *prtnsize=m_uMaxDataSize-dest%m_uMaxDataSize;
    }
}

bool SmartBuffer::PutData(void* src, unsigned int size, bool movecur, int dest)
{
    // Calculating pointer and size of single portion
    char* ptr=NULL;
    unsigned int prtnsize=0;
    DestToPtr(dest,ptr,&prtnsize);

    bool res=true;
    while (size>0) {
        // Is starting point out of buffer
        if (ptr>=m_pBuffer+m_uBufferSize) return false;
        // Is possible portion bigger then the rest of data
        if (size<prtnsize) prtnsize=size;
        // Is rest of buffer smaller then possible portion
        if ((unsigned int)(ptr+prtnsize-m_pBuffer)>m_uBufferSize) {
            prtnsize=m_pBuffer+m_uBufferSize-ptr-1;
            res=false;
        }
        // Copy data
        memcpy(ptr,src,prtnsize);
        size-=prtnsize;
        ptr+=prtnsize;
        prtnsize=m_uMaxDataSize;
        if ((unsigned int)(ptr-m_pBuffer)%(m_uHeadSize+m_uMaxDataSize)==0) ptr+=m_uHeadSize;
        if (!res) break;
    }

    if (movecur) m_pCurPtr=ptr;
    return res;
}

bool SmartBuffer::PutDataByte(unsigned char bt, bool movecur, int dest)
{
    // Calculating pointer
    char* ptr=NULL;
    DestToPtr(dest,ptr,NULL);

    // Put byte
    if (ptr<m_pBuffer+m_uBufferSize) {
        *ptr=bt;
        if (movecur) m_pCurPtr=ptr+1;
        return true;
    } else return false;
}

bool SmartBuffer::PutDataFile(LPCTSTR fname, bool movecur, int dest)
{
    // Calculating pointer and size of single portion
    char* ptr=NULL;
    unsigned int prtnsize=0;
    DestToPtr(dest,ptr,&prtnsize);

    CStdioFile file(fname,CFile::modeRead|CFile::typeBinary);
    unsigned int fsize=file.GetLength();
    // Copy file's content
    unsigned int read=0;
    bool res=true;
    do {
        // Is starting point out of buffer
        if (ptr>=m_pBuffer+m_uBufferSize) return false;
        // Is rest of buffer smaller then possible portion
        if ((unsigned int)(ptr+prtnsize-m_pBuffer)>m_uBufferSize) {
            prtnsize=m_pBuffer+m_uBufferSize-ptr-1;
            res=false;
        }
        // Copy data
        read=file.Read(ptr,min(prtnsize,fsize));
        ptr+=read;
        fsize-=read;
        prtnsize=m_uMaxDataSize;
        if ((unsigned int)(ptr-m_pBuffer)%(m_uHeadSize+m_uMaxDataSize)==0) ptr+=m_uHeadSize;
    } while (fsize>0);
    file.Close();

    if (movecur) m_pCurPtr=ptr;
    return res;
}

void SmartBuffer::Trim()
{
    // If m_pCurPtr is erroreous or points to fine end of buffer
    if ((int)(m_pBuffer+m_uBufferSize-m_pCurPtr)<=0) return;
    // New values of m_uBufferSize and m_uDataSize
    m_uBufferSize=(unsigned int)(m_pCurPtr-m_pBuffer);
    m_uDataSize=m_uBufferSize/(m_uHeadSize+m_uMaxDataSize)*m_uMaxDataSize+((m_uBufferSize%(m_uHeadSize+m_uMaxDataSize)<m_uHeadSize)?0:(m_uBufferSize%(m_uHeadSize+m_uMaxDataSize)-m_uHeadSize));
    // Current pointer will point just after buffer's end
}

⌨️ 快捷键说明

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