记录一下封装的ByteBuffer

MyByteBuffer.h

#include "cocos2d.h"
#include <string>
//////////////////////////////////////////////////////////////////////////
///  bytebuffer 
//////////////////////////////////////////////////////////////////////////
class MyByteBuffer
{
public:
    MyByteBuffer();
    ~MyByteBuffer();
    MyByteBuffer(const unsigned char* data, int dataLen);
public:
    // 获得缓冲区数据长度
    int getBufferDataLength();
    // 获得游标位置
    int getCursorPosition();
    void PushByte(char by);
    void PushByteArray(const unsigned char* data, int dataLen);
    void PushInt(int num);
    void PushLong(long Num);
    void PushString(const std::string& str);
    void PushPoint(cocos2d::Vec2& point);
    void PushFloat(float value);
    char PopByte();
    int PopInt();
    long PopLong();
    float PopFloat();
    const unsigned char* PopByteArray(int Length);
    std::string PopString();
    cocos2d::Vec2 PopPoint();
    unsigned char* ToByteArray();
private:
    /// 获取新的缓冲区
    unsigned char* initNewBuffer(int buffLen);
    /// 检测缓冲区是否足够
    void checkBuffSize(int addDataLen);
private:
    //固定长度的中间数组
    unsigned char* temp_byte_array;
    //当前数据长度
    int current_data_length;
    //当前游标位置
    int cursor_position;
    // 缓冲区大小
    int bufferSize;
};

MyByteBuffer.cpp

#include "MyByteBuffer.h"
#include <memory>

const int BUFFER_BLOCK = 1024; // 缓冲块

MyByteBuffer::MyByteBuffer()
{
    this->temp_byte_array = initNewBuffer(BUFFER_BLOCK);
    this->current_data_length = 0;
    this->cursor_position = 0;
    this->bufferSize = BUFFER_BLOCK;
}

MyByteBuffer::MyByteBuffer(const unsigned char* data, int dataLen)
{
    this->temp_byte_array = initNewBuffer(BUFFER_BLOCK);
    this->current_data_length = 0;
    this->cursor_position = 0;
    this->bufferSize = BUFFER_BLOCK;

    PushByteArray(data, dataLen);
}

MyByteBuffer::~MyByteBuffer()
{
    delete[] this->temp_byte_array;
}

unsigned char* MyByteBuffer::initNewBuffer(int buffLen)
{
    unsigned char* buff = new unsigned char[buffLen];
    memset(buff, 0x00, buffLen);
    return buff;
}

void MyByteBuffer::checkBuffSize(int addDataLen)
{
    int needLen = current_data_length + addDataLen;
    int newBuffSize = this->bufferSize;
    if (needLen < newBuffSize)
    {
        // 数据存储区域足够
        return;
    }
    // 存储区不足,重新分配
    while (newBuffSize <= needLen)
    {
        newBuffSize += BUFFER_BLOCK;
    }
    unsigned char* tmparr = initNewBuffer(newBuffSize);
    this->bufferSize = newBuffSize;
    // 拷贝资源
    memcpy(tmparr, this->temp_byte_array, current_data_length);
    // 释放旧内存
    delete[] this->temp_byte_array;
    this->temp_byte_array = tmparr;
}

int MyByteBuffer::getBufferDataLength()
{
    return current_data_length;
}

int MyByteBuffer::getCursorPosition()
{
    return cursor_position;
}

void MyByteBuffer::PushByte(char by)
{
    checkBuffSize(1);
    temp_byte_array[current_data_length++] = by;
}

void MyByteBuffer::PushByteArray(const unsigned char* data, int dataLen)
{
    checkBuffSize(dataLen);
    //把自己CopyTo目标数组
    memcpy(temp_byte_array + current_data_length, data, dataLen);
    //调整长度
    current_data_length += dataLen;
}

void MyByteBuffer::PushInt(int Num)
{
    checkBuffSize(4);
    temp_byte_array[current_data_length++] = (char)(((Num & 0xff000000) >> 24) & 0xff);
    temp_byte_array[current_data_length++] = (char)(((Num & 0x00ff0000) >> 16) & 0xff);
    temp_byte_array[current_data_length++] = (char)(((Num & 0x0000ff00) >> 8) & 0xff);
    temp_byte_array[current_data_length++] = (char)((Num & 0x000000ff) & 0xff);
}

void MyByteBuffer::PushLong(long Num)
{
    checkBuffSize(4);
    temp_byte_array[current_data_length++] = (char)(((Num & 0xff000000) >> 24) & 0xff);
    temp_byte_array[current_data_length++] = (char)(((Num & 0x00ff0000) >> 16) & 0xff);
    temp_byte_array[current_data_length++] = (char)(((Num & 0x0000ff00) >> 8) & 0xff);
    temp_byte_array[current_data_length++] = (char)((Num & 0x000000ff) & 0xff);
}

/// <summary>
/// 从ByteBuffer的当前位置弹出一个Byte,并提升一位
/// </summary>
/// <returns>1字节Byte</returns>
char MyByteBuffer::PopByte()
{
    char ret = temp_byte_array[cursor_position++];
    return ret;
}

/// <summary>
/// 从ByteBuffer的当前位置弹出一个uint,并提升4位
/// </summary>
/// <returns>4字节UInt</returns>
int MyByteBuffer::PopInt()
{
    if (cursor_position + 3 >= current_data_length)
        return 0;
    int ret = (int)(temp_byte_array[cursor_position] << 24 | temp_byte_array[cursor_position + 1] << 16 | temp_byte_array[cursor_position + 2] << 8 | temp_byte_array[cursor_position + 3]);
    cursor_position += 4;
    return ret;
}

/// <summary>
/// 从ByteBuffer的当前位置弹出一个long,并提升4位
/// </summary>
/// <returns>4字节Long</returns>
long MyByteBuffer::PopLong()
{
    if (cursor_position + 3 >= current_data_length)
        return 0;
    long ret = (long)(temp_byte_array[cursor_position] << 24 | temp_byte_array[cursor_position + 1] << 16 | temp_byte_array[cursor_position + 2] << 8 | temp_byte_array[cursor_position + 3]);
    cursor_position += 4;
    return ret;
}

/// <summary>
/// 从ByteBuffer的当前位置弹出长度为Length的Byte数组,提升Length位
/// </summary>
/// <param name="Length">数组长度</param>
/// <returns>Length长度的byte数组</returns>
const unsigned char* MyByteBuffer::PopByteArray(int Length)
{
    //溢出
    if (cursor_position + Length > current_data_length)
    {
        return nullptr;
    }
    unsigned char* ret = temp_byte_array + cursor_position;
    cursor_position += Length;
    return ret;
}


/// <summary>
/// 放入字符串
/// </summary>
/// <param name="str"></param>
void MyByteBuffer::PushString(const std::string& str)
{
    PushInt(str.length());
    PushByteArray((const unsigned char*)str.c_str(), str.length());
}

/// <summary>
/// 取出字符串
/// </summary>
/// <returns></returns>
std::string MyByteBuffer::PopString()
{
    int strlen = PopInt();
    if (strlen <= 0)
    {
        return "";
    }
    const char* bytes = (const char*)PopByteArray(strlen);
    std::string ret = std::string(bytes, 0, strlen);
    return ret;
}

void MyByteBuffer::PushPoint(cocos2d::Vec2& point)
{
    PushInt(point.x);
    PushInt(point.y);
}

cocos2d::Vec2 MyByteBuffer::PopPoint()
{
    int x = PopInt();
    int y = PopInt();
    return cocos2d::Vec2(x, y);
}

union FloatBinUnion
{
    float floatvalue;
    unsigned char bitvalue[4];
    int intvalue;
};


void MyByteBuffer::PushFloat(float value)
{
    FloatBinUnion bin;
    bin.floatvalue = value;
    PushInt(bin.intvalue);
}

float MyByteBuffer::PopFloat()
{
    FloatBinUnion bin;
    bin.intvalue = PopInt();
    return bin.floatvalue;
}

unsigned char* MyByteBuffer::ToByteArray()
{
    //分配大小
    unsigned char* RETURN_ARRAY = new unsigned char[current_data_length];
    //调整指针
    memcpy(RETURN_ARRAY, temp_byte_array, current_data_length);
    return RETURN_ARRAY;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容