Skip to content

Commit 5bd7590

Browse files
authored
Merge pull request #707 from redboltz/ts_c
Added timestamp minimal support for C.
2 parents 3aae588 + eebdc00 commit 5bd7590

File tree

5 files changed

+185
-0
lines changed

5 files changed

+185
-0
lines changed

Files.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ LIST (APPEND msgpackc_HEADERS
142142
include/msgpack/predef/version_number.h
143143
include/msgpack/sbuffer.h
144144
include/msgpack/sysdep.h
145+
include/msgpack/timestamp.h
145146
include/msgpack/unpack.h
146147
include/msgpack/unpack_define.h
147148
include/msgpack/unpack_template.h

include/msgpack/pack.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "pack_define.h"
1414
#include "object.h"
15+
#include "timestamp.h"
1516
#include <stdlib.h>
1617

1718
#ifdef __cplusplus
@@ -98,6 +99,8 @@ static int msgpack_pack_bin_body(msgpack_packer* pk, const void* b, size_t l);
9899
static int msgpack_pack_ext(msgpack_packer* pk, size_t l, int8_t type);
99100
static int msgpack_pack_ext_body(msgpack_packer* pk, const void* b, size_t l);
100101

102+
static int msgpack_pack_timestamp(msgpack_packer* pk, const msgpack_timestamp* d);
103+
101104
MSGPACK_DLLEXPORT
102105
int msgpack_pack_object(msgpack_packer* pk, msgpack_object d);
103106

include/msgpack/pack_template.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,34 @@ msgpack_pack_inline_func(_ext_body)(msgpack_pack_user x, const void* b, size_t l
890890
msgpack_pack_append_buffer(x, (const unsigned char*)b, l);
891891
}
892892

893+
msgpack_pack_inline_func(_timestamp)(msgpack_pack_user x, const msgpack_timestamp* d)
894+
{
895+
if ((((int64_t)d->tv_sec) >> 34) == 0) {
896+
uint64_t data64 = ((uint64_t) d->tv_nsec << 34) | d->tv_sec;
897+
if ((data64 & 0xffffffff00000000L) == 0) {
898+
// timestamp 32
899+
char buf[4];
900+
uint32_t data32 = (uint32_t)data64;
901+
msgpack_pack_ext(x, 4, -1);
902+
_msgpack_store32(buf, data32);
903+
msgpack_pack_append_buffer(x, buf, 4);
904+
} else {
905+
// timestamp 64
906+
char buf[8];
907+
msgpack_pack_ext(x, 8, -1);
908+
_msgpack_store64(buf, data64);
909+
msgpack_pack_append_buffer(x, buf, 8);
910+
}
911+
} else {
912+
// timestamp 96
913+
char buf[12];
914+
_msgpack_store32(&buf[0], d->tv_nsec);
915+
_msgpack_store64(&buf[4], d->tv_sec);
916+
msgpack_pack_ext(x, 12, -1);
917+
msgpack_pack_append_buffer(x, buf, 12);
918+
}
919+
}
920+
893921
#undef msgpack_pack_inline_func
894922
#undef msgpack_pack_user
895923
#undef msgpack_pack_append_buffer

include/msgpack/timestamp.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* MessagePack for C TimeStamp
3+
*
4+
* Copyright (C) 2018 KONDO Takatoshi
5+
*
6+
* Distributed under the Boost Software License, Version 1.0.
7+
* (See accompanying file LICENSE_1_0.txt or copy at
8+
* http://www.boost.org/LICENSE_1_0.txt)
9+
*/
10+
#ifndef MSGPACK_TIMESTAMP_H
11+
#define MSGPACK_TIMESTAMP_H
12+
13+
#include <msgpack/object.h>
14+
15+
#ifdef __cplusplus
16+
extern "C" {
17+
#endif
18+
19+
20+
typedef struct msgpack_timestamp {
21+
int64_t tv_sec;
22+
uint32_t tv_nsec;
23+
} msgpack_timestamp;
24+
25+
static inline bool msgpack_object_to_timestamp(const msgpack_object* obj, msgpack_timestamp* ts) {
26+
if (obj->type != MSGPACK_OBJECT_EXT) return false;
27+
if (obj->via.ext.type != -1) return false;
28+
switch (obj->via.ext.size) {
29+
case 4:
30+
ts->tv_nsec = 0;
31+
_msgpack_load32(uint32_t, obj->via.ext.ptr, &ts->tv_sec);
32+
return true;
33+
case 8: {
34+
uint64_t value;
35+
_msgpack_load64(uint64_t, obj->via.ext.ptr, &value);
36+
ts->tv_nsec = (uint32_t)(value >> 34);
37+
ts->tv_sec = value & 0x00000003ffffffffL;
38+
return true;
39+
}
40+
case 12:
41+
_msgpack_load32(uint32_t, obj->via.ext.ptr, &ts->tv_nsec);
42+
_msgpack_load64(int64_t, obj->via.ext.ptr + 4, &ts->tv_sec);
43+
return true;
44+
default:
45+
return false;
46+
}
47+
}
48+
49+
50+
#ifdef __cplusplus
51+
}
52+
#endif
53+
54+
#endif /* msgpack/timestamp.h */

test/msgpack_c.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,105 @@ TEST(MSGPACKC, simple_buffer_fixext_4byte_65536)
627627
msgpack_sbuffer_destroy(&sbuf);
628628
}
629629

630+
TEST(MSGPACKC, simple_buffer_timestamp_32)
631+
{
632+
msgpack_timestamp ts = {
633+
0xffffffff,
634+
0
635+
};
636+
637+
msgpack_sbuffer sbuf;
638+
msgpack_sbuffer_init(&sbuf);
639+
msgpack_packer pk;
640+
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
641+
642+
msgpack_pack_timestamp(&pk, &ts);
643+
msgpack_zone z;
644+
msgpack_zone_init(&z, 2048);
645+
msgpack_object obj;
646+
msgpack_unpack_return ret =
647+
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
648+
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
649+
EXPECT_EQ(MSGPACK_OBJECT_EXT, obj.type);
650+
EXPECT_EQ(4u, obj.via.ext.size);
651+
EXPECT_EQ(-1, obj.via.ext.type);
652+
msgpack_timestamp ts2;
653+
bool r = msgpack_object_to_timestamp(&obj, &ts2);
654+
655+
EXPECT_TRUE(r);
656+
EXPECT_EQ(ts.tv_sec, ts2.tv_sec);
657+
EXPECT_EQ(ts.tv_nsec, ts2.tv_nsec);
658+
659+
msgpack_zone_destroy(&z);
660+
msgpack_sbuffer_destroy(&sbuf);
661+
}
662+
663+
TEST(MSGPACKC, simple_buffer_timestamp_64)
664+
{
665+
msgpack_timestamp ts = {
666+
0x3ffffffffL,
667+
999999999
668+
};
669+
670+
msgpack_sbuffer sbuf;
671+
msgpack_sbuffer_init(&sbuf);
672+
msgpack_packer pk;
673+
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
674+
675+
msgpack_pack_timestamp(&pk, &ts);
676+
msgpack_zone z;
677+
msgpack_zone_init(&z, 2048);
678+
msgpack_object obj;
679+
msgpack_unpack_return ret =
680+
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
681+
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
682+
EXPECT_EQ(MSGPACK_OBJECT_EXT, obj.type);
683+
EXPECT_EQ(8u, obj.via.ext.size);
684+
EXPECT_EQ(-1, obj.via.ext.type);
685+
msgpack_timestamp ts2;
686+
bool r = msgpack_object_to_timestamp(&obj, &ts2);
687+
688+
EXPECT_TRUE(r);
689+
EXPECT_EQ(ts.tv_sec, ts2.tv_sec);
690+
EXPECT_EQ(ts.tv_nsec, ts2.tv_nsec);
691+
692+
msgpack_zone_destroy(&z);
693+
msgpack_sbuffer_destroy(&sbuf);
694+
}
695+
696+
TEST(MSGPACKC, simple_buffer_timestamp_96)
697+
{
698+
msgpack_timestamp ts = {
699+
0x7fffffffffffffffLL,
700+
999999999
701+
};
702+
703+
msgpack_sbuffer sbuf;
704+
msgpack_sbuffer_init(&sbuf);
705+
msgpack_packer pk;
706+
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
707+
708+
msgpack_pack_timestamp(&pk, &ts);
709+
msgpack_zone z;
710+
msgpack_zone_init(&z, 2048);
711+
msgpack_object obj;
712+
msgpack_unpack_return ret =
713+
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
714+
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
715+
EXPECT_EQ(MSGPACK_OBJECT_EXT, obj.type);
716+
EXPECT_EQ(12u, obj.via.ext.size);
717+
EXPECT_EQ(-1, obj.via.ext.type);
718+
msgpack_timestamp ts2;
719+
bool r = msgpack_object_to_timestamp(&obj, &ts2);
720+
721+
EXPECT_TRUE(r);
722+
EXPECT_EQ(ts.tv_sec, ts2.tv_sec);
723+
EXPECT_EQ(ts.tv_nsec, ts2.tv_nsec);
724+
725+
msgpack_zone_destroy(&z);
726+
msgpack_sbuffer_destroy(&sbuf);
727+
}
728+
630729
TEST(MSGPACKC, simple_buffer_array)
631730
{
632731
unsigned int array_size = 5;

0 commit comments

Comments
 (0)