google的protocol buffer 分析
来源:互联网 发布:系统性能监控软件 编辑:程序博客网 时间:2024/05/21 21:47
protocol buffer被引进项目组,今天强制自己抽时间,分析了。pb是:[typeID+type]+data的结构方式
[typeID+type]识别
具体的组合如下:
#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \
static_cast<uint32>( \((FIELD_NUMBER) << ::google::protobuf::internal::WireFormatLite::kTagTypeBits) \
| (TYPE))
其中type占居低3位,其余的由typeID占居,type类型如下:
enum WireType {
WIRETYPE_VARINT = 0,
WIRETYPE_FIXED64 = 1,
WIRETYPE_LENGTH_DELIMITED = 2,
WIRETYPE_START_GROUP = 3,
WIRETYPE_END_GROUP = 4,
WIRETYPE_FIXED32 = 5,
};
data识别
有了标识,但是如此简单的标识,而数据又被压缩过,怎么识别有效数据长度呢?(string是有自己长度的,简单;int等却没有长度,4个字节可能只被保存1个字节)
关键在于如下函数,它用了每个字节的最高位用来作为标识。细节各位看官慢慢品尝
压缩打包函数:
inline uint8* CodedOutputStream::WriteVarint32ToArray(uint32 value,
uint8* target) {
if (value < 0x80) {
*target = value;
return target + 1;
} else {
return WriteVarint32FallbackToArray(value, target);
}
}
inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline(
uint32 value, uint8* target) {
target[0] = static_cast<uint8>(value | 0x80);
if (value >= (1 << 7)) {
target[1] = static_cast<uint8>((value >> 7) | 0x80);
if (value >= (1 << 14)) {
target[2] = static_cast<uint8>((value >> 14) | 0x80);
if (value >= (1 << 21)) {
target[3] = static_cast<uint8>((value >> 21) | 0x80);
if (value >= (1 << 28)) {
target[4] = static_cast<uint8>(value >> 28);
return target + 5;
} else {
target[3] &= 0x7F;
return target + 4;
}
} else {
target[2] &= 0x7F;
return target + 3;
}
} else {
target[1] &= 0x7F;
return target + 2;
}
} else {
target[0] &= 0x7F;
return target + 1;
}
}
解析读取函数:
inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) {
// Fast path: We have enough bytes left in the buffer to guarantee that
// this read won't cross the end, so we can skip the checks.
const uint8* ptr = buffer;
uint32 b;
uint32 result;
b = *(ptr++); result = (b & 0x7F) ; if (!(b & 0x80)) goto done;
b = *(ptr++); result |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
b = *(ptr++); result |= b << 28; if (!(b & 0x80)) goto done;
// If the input is larger than 32 bits, we still need to read it all
// and discard the high-order bits.
for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) {
b = *(ptr++); if (!(b & 0x80)) goto done;
}
// We have overrun the maximum size of a varint (10 bytes). Assume
// the data is corrupt.
return NULL;
done:
*value = result;
return ptr;
}
- google的protocol buffer 分析
- google protocol buffer的使用
- google的protocol buffer学习
- Google Protocol Buffer持久化框架分析
- Google的protocol buffer的实例
- FreeWheel的架构 -- Protocol Buffer by Google
- Google Protocol Buffer 的使用和原理
- Google Protocol Buffer 的使用和原理
- Google Protocol Buffer 的使用和原理
- Google Protocol Buffer 的使用和原理
- Google Protocol Buffer 的使用和原理
- Google Protocol Buffer 的使用和原理
- Google Protocol Buffer 的使用和原理
- Google Protocol Buffer 的使用和原理
- Google Protocol Buffer 的使用和原理
- Google Protocol Buffer 的使用和原理
- Google Protocol Buffer 的使用和原理
- Google Protocol Buffer 的使用和原理
- Android 开机画面更改
- AIX常用命令与参数调整
- wordpress下怎样为Windows和Linux空间设置301重定向?
- 一些学习资源网址
- linux学习入门18——LINUX命令行文本处理工具(linuxcast.net)(grep,sed,diff,tr,cut,wc,sort)
- google的protocol buffer 分析
- Spring bean 通过实现 InitializingBean ,DisposableBean 接口实现初始化方法和销毁前操作
- GPU加速MG整车设计平台汽车碰撞测试高性能计算
- LogFactory.getLog之commons_logging.jar源码分析
- 一道题_20130316
- 也谈谈GalaxyS4:缺乏创新
- Linux下怎样安装卸载各种不同形式的软件
- Linux makefile 入门实例
- 人生不过如此