Thrift消息序列化是如何进行的详细分析?
- 内容介绍
- 文章标签
- 相关推荐
本文共计583个文字,预计阅读时间需要3分钟。
序列化浮点型数据流程包括使用 bitwise_cast 和 __int64 将 double 类型的数据转换为无符号整数。以下为简化后的步骤:
1. 使用 bitwise_cast 将 double 类型的数据转换为 unsigned int64。
2.使用 double(from) 函数将转换后的无符号整数转换回 double 类型。
3.Apache Thrift 使用 TBinaryProtocol 进行序列化,具体行号 74。
4.在 Apache Thrift 中,使用 TTransport 类的 writeDouble 方法序列化 double 类型数据,具体行号 171。
序列化浮点型数据流程
bitwise_cast<unsigned __int64,double>(double from) 行 74 C++
apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::TTransport>::writeDouble(const double dub) 行 171 C++
apache::thrift::protocol::TVirtualProtocol<apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::TTransport>,apache::thrift::protocol::TProtocolDefaults>::writeDouble_virt(const double dub) 行 414 C++
apache::thrift::protocol::TProtocol::writeDouble(const double dub) 行 458 C++
ucrtbased.dll!60dfa298() 未知
[下面的框架可能不正确和/或缺失,没有为 ucrtbased.dll 加载符号] 未知
ucrtbased.dll!60df9fd9() 未知
kernel32.dll!74a86359() 未知
ntdll.dll!76ee8944() 未知
ntdll.dll!76ee8914() 未知
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeDouble(const double dub) {
BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
uint64_t bits = bitwise_cast<uint64_t>(dub);
bits = htonll(bits);
this->trans_->write((uint8_t*)&bits, 8);
return 8;
}
xfer += oprot->writeFieldBegin("fFhorizontalValue", ::apache::thrift::protocol::T_DOUBLE, 12);
xfer += oprot->writeDouble(this->fFhorizontalValue);
xfer += oprot->writeFieldEnd();
uint32_t writeDouble(const double dub) {
T_VIRTUAL_CALL();
return writeDouble_virt(dub);
}
virtual uint32_t writeDouble_virt(const double dub) {
return static_cast<Protocol_*>(this)->writeDouble(dub);
}
double类型保存成整型
通过联合体将double类型转换成整型
// Use this to get around strict aliasing rules.
// For example, uint64_t i = bitwise_cast<uint64_t>(returns_double());
// The most obvious implementation is to just cast a pointer,
// but that doesn't work.
// For a pretty in-depth explanation of the problem, see
// www.cellperformance.com/mike_acton/2006/06/ (...)
// understanding_strict_aliasing.html
template <typename To, typename From>
static inline To bitwise_cast(From from) {
BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To));
// BAD!!! These are all broken with -O2.
//return *reinterpret_cast<To*>(&from); // BAD!!!
//return *static_cast<To*>(static_cast<void*>(&from)); // BAD!!!
//return *(To*)(void*)&from; // BAD!!!
// Super clean and paritally blessed by section 3.9 of the standard.
//unsigned char c[sizeof(from)];
//memcpy(c, &from, sizeof(from));
//To to;
//memcpy(&to, c, sizeof(c));
//return to;
// Slightly more questionable.
// Same code emitted by GCC.
//To to;
//memcpy(&to, &from, sizeof(from));
//return to;
// Technically undefined, but almost universally supported,
// and the most efficient implementation.
union {
From f;
To t;
} u;
u.f = from;
return u.t;
}
本文共计583个文字,预计阅读时间需要3分钟。
序列化浮点型数据流程包括使用 bitwise_cast 和 __int64 将 double 类型的数据转换为无符号整数。以下为简化后的步骤:
1. 使用 bitwise_cast 将 double 类型的数据转换为 unsigned int64。
2.使用 double(from) 函数将转换后的无符号整数转换回 double 类型。
3.Apache Thrift 使用 TBinaryProtocol 进行序列化,具体行号 74。
4.在 Apache Thrift 中,使用 TTransport 类的 writeDouble 方法序列化 double 类型数据,具体行号 171。
序列化浮点型数据流程
bitwise_cast<unsigned __int64,double>(double from) 行 74 C++
apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::TTransport>::writeDouble(const double dub) 行 171 C++
apache::thrift::protocol::TVirtualProtocol<apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::TTransport>,apache::thrift::protocol::TProtocolDefaults>::writeDouble_virt(const double dub) 行 414 C++
apache::thrift::protocol::TProtocol::writeDouble(const double dub) 行 458 C++
ucrtbased.dll!60dfa298() 未知
[下面的框架可能不正确和/或缺失,没有为 ucrtbased.dll 加载符号] 未知
ucrtbased.dll!60df9fd9() 未知
kernel32.dll!74a86359() 未知
ntdll.dll!76ee8944() 未知
ntdll.dll!76ee8914() 未知
template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeDouble(const double dub) {
BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
uint64_t bits = bitwise_cast<uint64_t>(dub);
bits = htonll(bits);
this->trans_->write((uint8_t*)&bits, 8);
return 8;
}
xfer += oprot->writeFieldBegin("fFhorizontalValue", ::apache::thrift::protocol::T_DOUBLE, 12);
xfer += oprot->writeDouble(this->fFhorizontalValue);
xfer += oprot->writeFieldEnd();
uint32_t writeDouble(const double dub) {
T_VIRTUAL_CALL();
return writeDouble_virt(dub);
}
virtual uint32_t writeDouble_virt(const double dub) {
return static_cast<Protocol_*>(this)->writeDouble(dub);
}
double类型保存成整型
通过联合体将double类型转换成整型
// Use this to get around strict aliasing rules.
// For example, uint64_t i = bitwise_cast<uint64_t>(returns_double());
// The most obvious implementation is to just cast a pointer,
// but that doesn't work.
// For a pretty in-depth explanation of the problem, see
// www.cellperformance.com/mike_acton/2006/06/ (...)
// understanding_strict_aliasing.html
template <typename To, typename From>
static inline To bitwise_cast(From from) {
BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To));
// BAD!!! These are all broken with -O2.
//return *reinterpret_cast<To*>(&from); // BAD!!!
//return *static_cast<To*>(static_cast<void*>(&from)); // BAD!!!
//return *(To*)(void*)&from; // BAD!!!
// Super clean and paritally blessed by section 3.9 of the standard.
//unsigned char c[sizeof(from)];
//memcpy(c, &from, sizeof(from));
//To to;
//memcpy(&to, c, sizeof(c));
//return to;
// Slightly more questionable.
// Same code emitted by GCC.
//To to;
//memcpy(&to, &from, sizeof(from));
//return to;
// Technically undefined, but almost universally supported,
// and the most efficient implementation.
union {
From f;
To t;
} u;
u.f = from;
return u.t;
}

