1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2018 KONDO Takatoshi
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef MSGPACK_V1_TYPE_CPP11_TIMESPEC_HPP
#define MSGPACK_V1_TYPE_CPP11_TIMESPEC_HPP
#include "msgpack/versioning.hpp"
#include "msgpack/adaptor/adaptor_base.hpp"
#include "msgpack/object.hpp"
#include "msgpack/object.hpp"
#include <ctime>
namespace msgpack {
/// @cond
MSGPACK_API_VERSION_NAMESPACE(v1) {
/// @endcond
namespace adaptor {
template <>
struct convert<timespec> {
msgpack::object const& operator()(msgpack::object const& o, timespec& v) const {
if(o.type != msgpack::type::EXT) { throw msgpack::type_error(); }
if(o.via.ext.type() != -1) { throw msgpack::type_error(); }
switch(o.via.ext.size) {
case 4: {
uint32_t sec;
_msgpack_load32(uint32_t, o.via.ext.data(), &sec);
v.tv_sec = static_cast<decltype(v.tv_sec)>(sec);
v.tv_nsec = 0;
} break;
case 8: {
uint64_t value;
_msgpack_load64(uint64_t, o.via.ext.data(), &value);
v.tv_sec = static_cast<decltype(v.tv_sec)>(value & 0x00000003ffffffffLL);
v.tv_nsec= static_cast<decltype(v.tv_nsec)>(value >> 34);
} break;
case 12: {
uint32_t nanosec;
_msgpack_load32(uint32_t, o.via.ext.data(), &nanosec);
int64_t sec;
_msgpack_load64(int64_t, o.via.ext.data() + 4, &sec);
v.tv_sec = static_cast<decltype(v.tv_sec)>(sec);
v.tv_nsec = static_cast<decltype(v.tv_nsec)>(nanosec);
} break;
default:
throw msgpack::type_error();
}
return o;
}
};
template <>
struct pack<timespec> {
template <typename Stream>
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const timespec& v) const {
if ((static_cast<uint64_t>(v.tv_sec) >> 34) == 0) {
uint64_t data64 = (static_cast<uint64_t>(v.tv_nsec) << 34) | static_cast<uint64_t>(v.tv_sec);
if ((data64 & 0xffffffff00000000L) == 0) {
// timestamp 32
o.pack_ext(4, -1);
uint32_t data32 = static_cast<uint32_t>(data64);
char buf[4];
_msgpack_store32(buf, data32);
o.pack_ext_body(buf, 4);
}
else {
// timestamp 64
o.pack_ext(8, -1);
char buf[8];
_msgpack_store64(buf, data64);
o.pack_ext_body(buf, 8);
}
}
else {
// timestamp 96
o.pack_ext(12, -1);
char buf[12];
_msgpack_store32(&buf[0], static_cast<uint32_t>(v.tv_nsec));
_msgpack_store64(&buf[4], v.tv_sec);
o.pack_ext_body(buf, 12);
}
return o;
}
};
template <>
struct object_with_zone<timespec> {
void operator()(msgpack::object::with_zone& o, const timespec& v) const {
if ((static_cast<uint64_t>(v.tv_sec) >> 34) == 0) {
uint64_t data64 = (static_cast<uint64_t>(v.tv_nsec) << 34) | static_cast<uint64_t>(v.tv_sec);
if ((data64 & 0xffffffff00000000L) == 0) {
// timestamp 32
o.type = msgpack::type::EXT;
o.via.ext.size = 4;
char* p = static_cast<char*>(o.zone.allocate_no_align(o.via.ext.size + 1));
p[0] = static_cast<char>(-1);
uint32_t data32 = static_cast<uint32_t>(data64);
_msgpack_store32(&p[1], data32);
o.via.ext.ptr = p;
}
else {
// timestamp 64
o.type = msgpack::type::EXT;
o.via.ext.size = 8;
char* p = static_cast<char*>(o.zone.allocate_no_align(o.via.ext.size + 1));
p[0] = static_cast<char>(-1);
_msgpack_store64(&p[1], data64);
o.via.ext.ptr = p;
}
}
else {
// timestamp 96
o.type = msgpack::type::EXT;
o.via.ext.size = 12;
char* p = static_cast<char*>(o.zone.allocate_no_align(o.via.ext.size + 1));
p[0] = static_cast<char>(-1);
_msgpack_store32(&p[1], static_cast<uint32_t>(v.tv_nsec));
_msgpack_store64(&p[1 + 4], v.tv_sec);
o.via.ext.ptr = p;
}
}
};
} // namespace adaptor
/// @cond
} // MSGPACK_API_VERSION_NAMESPACE(v1)
/// @endcond
} // namespace msgpack
#endif // MSGPACK_V1_TYPE_CPP11_TIMESPEC_HPP
|