Merge pull request #707 from redboltz/ts_c

Added timestamp minimal support for C.
This commit is contained in:
Takatoshi Kondo 2018-07-22 22:06:58 +09:00 committed by GitHub
commit 5bd75905cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 185 additions and 0 deletions

View File

@ -142,6 +142,7 @@ LIST (APPEND msgpackc_HEADERS
include/msgpack/predef/version_number.h include/msgpack/predef/version_number.h
include/msgpack/sbuffer.h include/msgpack/sbuffer.h
include/msgpack/sysdep.h include/msgpack/sysdep.h
include/msgpack/timestamp.h
include/msgpack/unpack.h include/msgpack/unpack.h
include/msgpack/unpack_define.h include/msgpack/unpack_define.h
include/msgpack/unpack_template.h include/msgpack/unpack_template.h

View File

@ -12,6 +12,7 @@
#include "pack_define.h" #include "pack_define.h"
#include "object.h" #include "object.h"
#include "timestamp.h"
#include <stdlib.h> #include <stdlib.h>
#ifdef __cplusplus #ifdef __cplusplus
@ -98,6 +99,8 @@ static int msgpack_pack_bin_body(msgpack_packer* pk, const void* b, size_t l);
static int msgpack_pack_ext(msgpack_packer* pk, size_t l, int8_t type); static int msgpack_pack_ext(msgpack_packer* pk, size_t l, int8_t type);
static int msgpack_pack_ext_body(msgpack_packer* pk, const void* b, size_t l); static int msgpack_pack_ext_body(msgpack_packer* pk, const void* b, size_t l);
static int msgpack_pack_timestamp(msgpack_packer* pk, const msgpack_timestamp* d);
MSGPACK_DLLEXPORT MSGPACK_DLLEXPORT
int msgpack_pack_object(msgpack_packer* pk, msgpack_object d); int msgpack_pack_object(msgpack_packer* pk, msgpack_object d);

View File

@ -890,6 +890,34 @@ msgpack_pack_inline_func(_ext_body)(msgpack_pack_user x, const void* b, size_t l
msgpack_pack_append_buffer(x, (const unsigned char*)b, l); msgpack_pack_append_buffer(x, (const unsigned char*)b, l);
} }
msgpack_pack_inline_func(_timestamp)(msgpack_pack_user x, const msgpack_timestamp* d)
{
if ((((int64_t)d->tv_sec) >> 34) == 0) {
uint64_t data64 = ((uint64_t) d->tv_nsec << 34) | d->tv_sec;
if ((data64 & 0xffffffff00000000L) == 0) {
// timestamp 32
char buf[4];
uint32_t data32 = (uint32_t)data64;
msgpack_pack_ext(x, 4, -1);
_msgpack_store32(buf, data32);
msgpack_pack_append_buffer(x, buf, 4);
} else {
// timestamp 64
char buf[8];
msgpack_pack_ext(x, 8, -1);
_msgpack_store64(buf, data64);
msgpack_pack_append_buffer(x, buf, 8);
}
} else {
// timestamp 96
char buf[12];
_msgpack_store32(&buf[0], d->tv_nsec);
_msgpack_store64(&buf[4], d->tv_sec);
msgpack_pack_ext(x, 12, -1);
msgpack_pack_append_buffer(x, buf, 12);
}
}
#undef msgpack_pack_inline_func #undef msgpack_pack_inline_func
#undef msgpack_pack_user #undef msgpack_pack_user
#undef msgpack_pack_append_buffer #undef msgpack_pack_append_buffer

View File

@ -0,0 +1,54 @@
/*
* MessagePack for C TimeStamp
*
* 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_TIMESTAMP_H
#define MSGPACK_TIMESTAMP_H
#include <msgpack/object.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct msgpack_timestamp {
int64_t tv_sec;
uint32_t tv_nsec;
} msgpack_timestamp;
static inline bool msgpack_object_to_timestamp(const msgpack_object* obj, msgpack_timestamp* ts) {
if (obj->type != MSGPACK_OBJECT_EXT) return false;
if (obj->via.ext.type != -1) return false;
switch (obj->via.ext.size) {
case 4:
ts->tv_nsec = 0;
_msgpack_load32(uint32_t, obj->via.ext.ptr, &ts->tv_sec);
return true;
case 8: {
uint64_t value;
_msgpack_load64(uint64_t, obj->via.ext.ptr, &value);
ts->tv_nsec = (uint32_t)(value >> 34);
ts->tv_sec = value & 0x00000003ffffffffL;
return true;
}
case 12:
_msgpack_load32(uint32_t, obj->via.ext.ptr, &ts->tv_nsec);
_msgpack_load64(int64_t, obj->via.ext.ptr + 4, &ts->tv_sec);
return true;
default:
return false;
}
}
#ifdef __cplusplus
}
#endif
#endif /* msgpack/timestamp.h */

View File

@ -627,6 +627,105 @@ TEST(MSGPACKC, simple_buffer_fixext_4byte_65536)
msgpack_sbuffer_destroy(&sbuf); msgpack_sbuffer_destroy(&sbuf);
} }
TEST(MSGPACKC, simple_buffer_timestamp_32)
{
msgpack_timestamp ts = {
0xffffffff,
0
};
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_timestamp(&pk, &ts);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_EXT, obj.type);
EXPECT_EQ(4u, obj.via.ext.size);
EXPECT_EQ(-1, obj.via.ext.type);
msgpack_timestamp ts2;
bool r = msgpack_object_to_timestamp(&obj, &ts2);
EXPECT_TRUE(r);
EXPECT_EQ(ts.tv_sec, ts2.tv_sec);
EXPECT_EQ(ts.tv_nsec, ts2.tv_nsec);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_timestamp_64)
{
msgpack_timestamp ts = {
0x3ffffffffL,
999999999
};
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_timestamp(&pk, &ts);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_EXT, obj.type);
EXPECT_EQ(8u, obj.via.ext.size);
EXPECT_EQ(-1, obj.via.ext.type);
msgpack_timestamp ts2;
bool r = msgpack_object_to_timestamp(&obj, &ts2);
EXPECT_TRUE(r);
EXPECT_EQ(ts.tv_sec, ts2.tv_sec);
EXPECT_EQ(ts.tv_nsec, ts2.tv_nsec);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_timestamp_96)
{
msgpack_timestamp ts = {
0x7fffffffffffffffLL,
999999999
};
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_timestamp(&pk, &ts);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_EXT, obj.type);
EXPECT_EQ(12u, obj.via.ext.size);
EXPECT_EQ(-1, obj.via.ext.type);
msgpack_timestamp ts2;
bool r = msgpack_object_to_timestamp(&obj, &ts2);
EXPECT_TRUE(r);
EXPECT_EQ(ts.tv_sec, ts2.tv_sec);
EXPECT_EQ(ts.tv_nsec, ts2.tv_nsec);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_array) TEST(MSGPACKC, simple_buffer_array)
{ {
unsigned int array_size = 5; unsigned int array_size = 5;