热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

二进制编码与解码容器

0背景在rpc或分布式节点间的通讯框架里面,我们经常会有“编码或解码业务数据成网络二进制流”的场景要求,在jdk的nio框架里面有既有的ByteBuffer类满足此需求,那么在c+

0 背景

   在rpc或分布式节点间的通讯框架里面,我们经常会有“编码或解码业务数据成网络二进制流”的场景要求,在jdk的nio框架里面有既有的ByteBuffer类满足此需求,那么在c++里面,同样我们简单看看具有类似功能的类DataBuffer。  

1 实现基本逻辑

   指针偏移指向同一块内存,分别表示内存的起始与结束偏移位置,分别表示读与写的偏移位置。如下图:  

技术分享

2 操作步骤

   1.1 读取数据时,仅需偏移_pdata即可

       源码如下:

技术分享技术分享
    bool readBytes(void *dst, int len) {

        if (_pdata + len > _pfree) {

            return false;

        }

        memcpy(dst, _pdata, len);

        _pdata += len;

        assert(_pfree>=_pdata);

        return true;

    }
View Code

   1.2 写数据时,仅需偏移_pfree指针即可

       源码如下:                  

技术分享技术分享
  void writeString(const char *str) {

        int len = (str ? static_cast(strlen(str)) : 0);

        if (len>0) len ++;

        expand(static_cast(len+sizeof(uint32_t)));

        writeInt32(len);

        if (len>0) {

            memcpy(_pfree, str, len);

            _pfree += (len);

        }

    }
View Code

    1.3 当所需内存不足时(_ppend - _pfree

        a 申请新的当前于内存空间2倍的内存(<<= 1)

        b 把已有数据拷贝至新的内存块上

       源码如下:

技术分享技术分享
inline void expand(int need) {

        if (_pstart == NULL) {

            int len = 256;

            while (len 1;

            _pfree = _pdata = _pstart = (unsigned char*)malloc(len);

            _pend = _pstart + len;

        } else if (_pend - _pfree // 空间不够

            int flen = static_cast((_pend - _pfree) + (_pdata - _pstart));

            int dlen = static_cast(_pfree - _pdata);

 

            if (flen 4 < dlen) {

                int bufsize = static_cast((_pend - _pstart) * 2);

                while (bufsize - dlen < need)

                    bufsize <<= 1;

 

                unsigned char *newbuf = (unsigned char *)malloc(bufsize);

                if (newbuf == NULL)

                {

                  TBSYS_LOG(ERROR, "expand data buffer failed, length: %d", bufsize);

                }

                assert(newbuf != NULL);

                if (dlen > 0) {

                    memcpy(newbuf, _pdata, dlen);

                }

                free(_pstart);

 

                _pdata = _pstart = newbuf;

                _pfree = _pstart + dlen;

                _pend = _pstart + bufsize;

            } else {

                memmove(_pstart, _pdata, dlen);

                _pfree = _pstart + dlen;

                _pdata = _pstart;

            }

        }

    }
View Code

3 实例

3.1 输入

技术分享

3.2 输出

out1: 11 out2: 1100 out3: hello world

    源码请见 http://files.cnblogs.com/files/gisorange/databuffer.zip

二进制编码与解码容器


推荐阅读
author-avatar
mobiledu2502908023
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有