hessian2/basic_codec/date_codec.cc (122 lines of code) (raw):

#include "hessian2/basic_codec/date_codec.hpp" namespace Hessian2 { namespace { template <typename T> std::unique_ptr<T> readDate(ReaderPtr &reader) { auto out = std::make_unique<T>(); uint8_t code = reader->read<uint8_t>().second; switch (code) { case 0x4b: if (reader->byteAvailable() < 4) { return nullptr; } return std::make_unique<T>(std::chrono::duration_cast<T>( std::chrono::minutes(reader->readBE<int32_t>().second))); case 0x4a: if (reader->byteAvailable() < 8) { return nullptr; } return std::make_unique<T>(std::chrono::duration_cast<T>( std::chrono::milliseconds(reader->readBE<int64_t>().second))); } return nullptr; } template <typename T> void writeDate(WriterPtr &writer, const T &value) { int64_t value_in_min = std::chrono::duration_cast<std::chrono::minutes>(value).count(); int64_t value_in_ms = std::chrono::duration_cast<std::chrono::milliseconds>(value).count(); if (value_in_min * 60000 == value_in_ms) { writer->writeByte(0x4b); writer->writeBE<int32_t>(value_in_min); } else { writer->writeByte(0x4a); writer->writeBE<int64_t>(value_in_ms); } } } // namespace // # time in UTC encoded as 64-bit long milliseconds since epoch // ::= x4a b7 b6 b5 b4 b3 b2 b1 b0 // ::= x4b b3 b2 b1 b0 # minutes since epoch template <> std::unique_ptr<std::chrono::milliseconds> Decoder::decode() { return readDate<std::chrono::milliseconds>(reader_); } template <> std::unique_ptr<std::chrono::minutes> Decoder::decode() { return readDate<std::chrono::minutes>(reader_); } template <> std::unique_ptr<std::chrono::seconds> Decoder::decode() { return readDate<std::chrono::seconds>(reader_); } template <> std::unique_ptr<std::chrono::hours> Decoder::decode() { return readDate<std::chrono::hours>(reader_); } #if defined(_LIBCPP_STD_VER) && _LIBCPP_STD_VER > 17 template <> std::unique_ptr<std::chrono::days> Decoder::decode() { return readDate<std::chrono::days>(reader_); } template <> std::unique_ptr<std::chrono::weeks> Decoder::decode() { return readDate<std::chrono::weeks>(reader_); } template <> std::unique_ptr<std::chrono::years> Decoder::decode() { return readDate<std::chrono::years>(reader_); } template <> std::unique_ptr<std::chrono::months> Decoder::decode() { return readDate<std::chrono::months>(reader_); } #endif // # time in UTC encoded as 64-bit long milliseconds since epoch // ::= x4a b7 b6 b5 b4 b3 b2 b1 b0 // ::= x4b b3 b2 b1 b0 # minutes since epoch template <> bool Encoder::encode(const std::chrono::minutes &value) { writer_->writeByte(0x4b); writer_->writeBE<int32_t>(value.count()); return true; } template <> bool Encoder::encode(const std::chrono::milliseconds &value) { std::chrono::minutes value_min = std::chrono::duration_cast<std::chrono::minutes>(value); if (value_min.count() * 60000 == value.count()) { return encode<std::chrono::minutes>(value_min); } writer_->writeByte(0x4a); writer_->writeBE<int64_t>(value.count()); return true; } template <> bool Encoder::encode(const std::chrono::seconds &value) { writeDate<std::chrono::seconds>(writer_, value); return true; } template <> bool Encoder::encode(const std::chrono::hours &value) { writeDate<std::chrono::hours>(writer_, value); return true; } #if defined(_LIBCPP_STD_VER) && _LIBCPP_STD_VER > 17 template <> bool Encoder::encode(const std::chrono::days &value) { writeDate<std::chrono::days>(writer_, value); return true; } template <> bool Encoder::encode(const std::chrono::weeks &value) { writeDate<std::chrono::weeks>(writer_, value); return true; } template <> bool Encoder::encode(const std::chrono::years &value) { writeDate<std::chrono::years>(writer_, value); return true; } template <> bool Encoder::encode(const std::chrono::months &value) { writeDate<std::chrono::months>(writer_, value); return true; } #endif } // namespace Hessian2