Packet.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //
  2. // "$Id$"
  3. //
  4. // Copyright (c)1992-2011, ZheJiang Dahua Technology Stock CO.LTD.
  5. // All Rights Reserved.
  6. //
  7. // Description:
  8. // Revisions: Year-Month-Day SVN-Author Modification
  9. //
  10. #ifndef __DAHUA_MEMORY_PACKET_H__
  11. #define __DAHUA_MEMORY_PACKET_H__
  12. #include <stddef.h> // for size_t
  13. #include "Infra/Defs.h"
  14. #include "Infra/Function.h"
  15. #include "Defs.h"
  16. namespace Dahua {
  17. namespace Memory {
  18. ////////////////////////////////////////////////////////////////////////////////
  19. struct PacketInternal;
  20. /// \释放自定义内存的函数指针
  21. typedef Infra::TFunction2<void, void*, size_t> FreeMemFunc;
  22. /// \class CPacket
  23. /// \brief 数据包缓存管理
  24. class MEMORY_API CPacket
  25. {
  26. public:
  27. /// 构造函数,生成一个无效的包,需要赋值才能使用。可以用于给有效包赋值,
  28. /// 使原包的包数据引用计数递减。
  29. CPacket();
  30. /// 构造函数
  31. /// \param data 数据指针
  32. /// \param len 数据长度
  33. /// \param func 释放函数(空表示不释放)
  34. CPacket(void* data, size_t len, FreeMemFunc func = FreeMemFunc());
  35. /// 构造函数,生成一个可以使用的包
  36. /// \param dataSize 申请的包包含的有效数据缓冲的字节数。
  37. /// \param extraSize 扩展数据缓冲字节数
  38. explicit CPacket(size_t dataSize, size_t extraSize = 0);
  39. /// 拷贝构造函数,完成包数据引用计数递增
  40. CPacket(const CPacket& other);
  41. /// 从大包中构造小包,小包引用大包中的局部内存,如果参数不正确,构造一个无效包
  42. /// \param hugePacket 被引用的大包
  43. /// \param offset 被引用的内存在大包中的起始字节数
  44. /// \param size 被引用的内存字节数
  45. CPacket(const CPacket& hugePacket, size_t offset, size_t size, size_t extraSize);
  46. /// 赋值运算符重载,完成包数据引用计数递增
  47. CPacket& operator=(const CPacket& other);
  48. /// 析构函数,完成对包数据引用计数递减
  49. virtual ~CPacket();
  50. /// 重置包,恢复为无效包
  51. void reset();
  52. /// 判断是否为有效包
  53. bool valid() const;
  54. /// 从当前包缓冲的指针偏移处追加数据,同时自动更新有效数据长度。如果用此函数来
  55. /// 填充数据,第一次填充前应该将有效数据长度设置为0。
  56. /// \param buffer 追加的数据指针
  57. /// \param length 追加的数据长度
  58. /// \return 实际写入的数据,如果小于length,表示缓冲已满,剩余的数据需要调用者自行处理
  59. size_t putBuffer(void* buffer, size_t length);
  60. /// 得到包缓冲的起始位置的指针
  61. uint8_t* getBuffer() const;
  62. /// 得到包的有效数据长度, 不包含扩展数据大小
  63. size_t size() const;
  64. /// 设置包的有效数据长度,刚申请来的包的有效长度是包申请时的大小。
  65. /// \param size 新的长度,不会超过包的容量。
  66. /// \return 返回操作是否成功
  67. bool resize(size_t size);
  68. /// 得到包占用空间的大小,按内部页面对齐,可能比申请的稍大。
  69. size_t capacity() const;
  70. /// 得到扩展数据缓冲地址
  71. void* getExtraData() const;
  72. /// 得到扩展数据长度
  73. size_t getExtraSize() const;
  74. ///\ brief 构造数据包
  75. explicit CPacket(uint32_t size, FreeMemFunc fun, void *arg, size_t extraSize = 0);
  76. private:
  77. PacketInternal* m_internal;
  78. };
  79. ////////////////////////////////////////////////////////////////////////////////
  80. struct PacketManagerInternal;
  81. /// \class CPacketManager
  82. /// \brief 包管理类
  83. /// \see CPacket
  84. class MEMORY_API CPacketManager
  85. {
  86. CPacketManager();
  87. CPacketManager(CPacketManager const&);
  88. CPacketManager& operator=(CPacketManager const&);
  89. public:
  90. /// 内存分配函数类型;参数为要分配的内存大小,返回为分配的内存地址
  91. typedef Infra::TFunction1<void*, size_t> AllocProc;
  92. /// 内存释放函数类型;参数是 malloc 获得的指针
  93. typedef Infra::TFunction1<void, void*> FreeProc;
  94. /// 内存复制函数类型;第一个参数为目的地址,第二个参数为源地址,第三个参数为字节数
  95. typedef Infra::TFunction3<void*, void*, const void*, size_t> CopyProc;
  96. /// 内存管理策略
  97. enum Policy
  98. {
  99. policyDefault = 0, ///< 根据平台设定为系统缺省值, x86 平台为 policySystem,其他平台为 policyPool
  100. policySystem, ///< 每次申请空间都调用MemoryOperator.malloc,释放调用MemoryOperator.free
  101. policyPool, ///< 内存池模式,一次性分配好大段空间后,每次申请时分配连续内存块
  102. policyPoolSystem, ///< 包数据内存使用内存池,扩展数据、PacketInternal 使用系统内存;主要用于兼容组件化包管理器
  103. policySharePool, ///< 多进程共享内存池模式
  104. policyCount
  105. };
  106. /// 内存池模式的参数
  107. struct PoolParameter
  108. {
  109. size_t totalSize; ///< 内存池总字节数,由于对齐的原因,实际申请的量会更大一点。缺省值为8M Bytes
  110. size_t chunkSize; ///< 内存池区块字节数,必须是2^nK 字节,也是能够申请到的内存块的最小单位。缺省值为1K Bytes
  111. size_t alignSize; ///< CPacket数据区可用容量对齐字节数,必须为2^n 字节。缺省值为 4 Bytes
  112. };
  113. /// 自定义内存操作函数
  114. struct MemoryOperator
  115. {
  116. AllocProc malloc; ///< 内存池所管理的内存的申请函数。缺省为 ::malloc
  117. FreeProc free; ///< 内存池所管理的内存的释放函数。缺省为 ::free
  118. CopyProc memcpy; ///< 内存池所管理的内存之间的复制函数。缺省 ::memcpy
  119. };
  120. /// 配置包缓冲管理策略,需要在单件构造之前调用,否则使用缺省的配置。
  121. /// \param policy [in] 内存管理策略
  122. /// \param memop [in] 自定义内存操作函数,为NULL时使用缺少函数
  123. /// \param param [in] 内存池策略的配置参数,为NULL时使用缺省配置
  124. static void config(Policy policy = policyDefault, MemoryOperator* memop = NULL, PoolParameter* param = NULL);
  125. /// 获取内存池分配的总的内存空间的起始地址
  126. uint8_t* getPoolBuffer();
  127. /// 创建包管理对象
  128. static CPacketManager* instance();
  129. /// 虚析构函数
  130. ~CPacketManager();
  131. /// 从管理的内存中申请内存块
  132. void* malloc(size_t size);
  133. /// 释放内存块
  134. void free(void*);
  135. /// 内存复制,如果源和目标都在管理的内存范围内,使用配置时指定的内存复制函数
  136. void* memcpy(void* dest, const void* src, size_t size);
  137. /// 得到管理的内存总字节数,这个值就是缺省值或者config配置后的值。
  138. size_t getBufferSize();
  139. /// 得到管理的内存剩余字节数,是按2^n页面来进行统计的,可能会比用户调用GetPacket
  140. /// 时传入的bytes值累加的结果要大。
  141. size_t getFreeSize();
  142. /// 打印内存节点的状态,仅用于调试
  143. void dumpNodes();
  144. private:
  145. PacketManagerInternal* m_internal;
  146. };
  147. } // namespace Memory
  148. } // namespace Dahua
  149. #endif // __DAHUA_MEMORY_PACKET_H__