Pickle 是Chrome中进程通信用来承载数据的最基本的数据结构。
因此chrome的开发团队把这个数据结构写到了几乎完美的地步。
Pickle的提供了一组成员函数用来序列化数据(基本数据类型和std::string/std::wstring)
实质上它是一个字节流,也叫做Packet,有Header和Header尾随的数据。
由于进程通信的各种方法中,像Socket、管道等,实际传输的都是字节流。
因此必须把结构化的数据(结构体,类等)序列化为连续的字节流。
// Pickle 中的数据成员
public:
// Payload follows after allocation of Header (header size is customizable).
struct Header {
uint32 payload_size; // Specifies the size of the payload.
};
protected:
static const int kPayloadUnit;
private:
Header* header_;
size_t header_size_; // Supports extra data between header and payload.
// Allocation size of payload (or -1 if allocation is const).
size_t capacity_;
size_t variable_buffer_offset_; // IF non-zero, then offset to a buffer.
所有的成员函数中,只有构造函数、拷贝构造函数和Resize会修改capacity_ 成员。
Pickle() 和 explicit Pickle(int header_size) 会把capcacity_赋为0;
Pickle(const char* data, int data_len); 会把capcacity_设置为-1;
Pickle(const Pickle& other) 会Resize payload buffer,并且拷贝数据。
内存管理策略要点:
1. Pickle 中的capacity 最小为kPayloadUnit,每次realloc的内存都kPayloadUnit的整数倍。kPayloadUnit 被初始化为64,因此必然是4字节对齐的.
2. 向Pickle写入数据时,都是以4字节对齐,即使写入一个bool也会占4个字节,而且会把paddings填充0。
3. 从Pickle中读bool型数据时,先读出4字节,并判断是否等于0或1,然后再转成bool型,且判断的结果会写入日志。
4. 每次向Pickle中写入数据都会判断capacity是否够用,如果不够会自动double,使用的是realloc函数,这个函数会复制原来的数据到新的内存区域。
5. Pickle用一个char*指针作为迭代器,每次读写都会更新迭代器至下一个读写位置。
6. 第一次读写payload 中的数据时,可以把NULL作为iter的值传入,Pickle会自动将其指向payload的起始位置,既Header后的第一个字节处。
浙公网安备 33010602011771号