Skip to content

Commit

Permalink
Fix bugs in TIMESTAMP
Browse files Browse the repository at this point in the history
  • Loading branch information
clwi committed Aug 17, 2020
1 parent abef70e commit d60634b
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 43 deletions.
9 changes: 4 additions & 5 deletions goodies/objC/cwpack_objc.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ - (void) packIn:(cw_pack_context*) buff
}


+ (instancetype) setWithArray:(NSArray*)array {return nil;}


+ (instancetype) unpackFrom:(cw_unpack_context*) buff
{
id result = cwObjectFromBuffer(buff);
Expand Down Expand Up @@ -186,12 +189,8 @@ @implementation NSDate (cwPack)

- (void) packIn:(cw_pack_context*) buff
{
struct timespec t;

NSTimeInterval ti = self.timeIntervalSince1970;
t.tv_sec = floor(ti);
t.tv_nsec = floor((ti - t.tv_sec)*1000000000);
cw_pack_time(buff, &t);
cw_pack_time_interval (buff, ti);
}
@end

Expand Down
10 changes: 5 additions & 5 deletions goodies/utils/cwpack_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/


#include <math.h>
#include "cwpack_utils.h"


Expand Down Expand Up @@ -56,10 +57,9 @@ void cw_pack_float_opt (cw_pack_context* pack_context, float f)

void cw_pack_time_interval (cw_pack_context* pack_context, double ti)
{
struct timespec ts;
ts.tv_sec = (long)ti;
ts.tv_nsec = (long)((ti - (double)ts.tv_sec) * 1000000000.0);
cw_pack_time(pack_context, &ts);
int64_t sec = (int64_t)floor(ti);
uint32_t nsec = (uint32_t)((ti - (double)sec) * 1000000000.0);
cw_pack_time(pack_context, sec, nsec);
}

/******************************* U N P A C K ******************************/
Expand Down Expand Up @@ -337,7 +337,7 @@ unsigned int cw_unpack_next_str_lengh (cw_unpack_context* unpack_context)
return unpack_context->item.as.str.length;

unpack_context->return_code = CWP_RC_TYPE_ERROR;
return NaN;
return 0;
}


Expand Down
4 changes: 3 additions & 1 deletion goodies/utils/cwpack_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ void cw_pack_float_opt (cw_pack_context* pack_context, float f); /* Pack as s
void cw_pack_double_opt (cw_pack_context* pack_context, double d); /* Pack as signed or float if precision isn't destroyed */
#define cw_pack_real cw_pack_double_opt /* Backward compatibility */

void cw_pack_time_interval (cw_pack_context* pack_context, double ti);
#define cw_pack_timespec (pack_contextptr, timespecptr) cw_pack_time ((pack_contextptr), (int64_t)((timespecptr)->tv_sec), (uint32_t)((timespecptr)->tv_nsec))

void cw_pack_time_interval (cw_pack_context* pack_context, double ti); /* ti is seconds relative epoch */

/***************************** U N P A C K ********************************/

Expand Down
57 changes: 30 additions & 27 deletions src/cwpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,19 +380,40 @@ void cw_pack_ext (cw_pack_context* pack_context, int8_t type, const void* v, uin
}


void cw_pack_time (cw_pack_context* pack_context, struct timespec* t)
void cw_pack_time (cw_pack_context* pack_context, int64_t sec, uint32_t nsec)
{
if (pack_context->return_code)
return;

if (pack_context->be_compatible)
PACK_ERROR(CWP_RC_ILLEGAL_CALL);

if (nsec >= 1000000000)
PACK_ERROR(CWP_RC_VALUE_ERROR);

uint8_t *p;

if ((t->tv_sec >> 34) == 0) {
uint64_t data64 = (uint64_t)((t->tv_nsec << 34) | t->tv_sec);
if ((data64 & 0xffffffff00000000L) == 0) {

if ((uint64_t)sec & 0xfffffffc00000000L) {
// timestamp 96
//serialize(0xc7, 12, -1, nsec, sec)
cw_pack_reserve_space(15);
*p++ = (uint8_t)0xc7;
*p++ = (uint8_t)12;
*p++ = (uint8_t)0xff;
cw_store32(nsec); p += 4;
cw_store64(sec);
}
else {
uint64_t data64 = (((uint64_t)nsec << 34) | (uint64_t)sec);
if (data64 & 0xffffffff00000000L) {
// timestamp 64
//serialize(0xd7, -1, data64)
cw_pack_reserve_space(10);
*p++ = (uint8_t)0xd7;
*p++ = (uint8_t)0xff;
cw_store64(data64);
}
else {
// timestamp 32
uint32_t data32 = (uint32_t)data64;
//serialize(0xd6, -1, data32)
Expand All @@ -401,24 +422,6 @@ void cw_pack_time (cw_pack_context* pack_context, struct timespec* t)
*p++ = (uint8_t)0xff;
cw_store32(data32);
}
else {
// timestamp 64
//serialize(0xd7, -1, data64)
cw_pack_reserve_space(10);
*p++ = (uint8_t)0xd7;
*p++ = (uint8_t)0xff;
cw_store64(data64);
}
}
else {
// timestamp 96
//serialize(0xc7, 12, -1, t->tv_nsec, t->tv_sec)
cw_pack_reserve_space(3+12);
*p++ = (uint8_t)0xc7;
*p++ = (uint8_t)12;
*p++ = (uint8_t)0xff;
cw_store32(t->tv_nsec);
cw_store64(t->tv_sec);
}
}

Expand Down Expand Up @@ -523,9 +526,10 @@ void cw_unpack_next (cw_unpack_context* unpack_context)
{
cw_unpack_assert_space(4);
cw_load32(p);
unpack_context->item.as.time.tv_nsec = (long)tmpu32;
unpack_context->item.as.time.tv_nsec = tmpu32;
cw_unpack_assert_space(8);
cw_load64(p,unpack_context->item.as.time.tv_sec);
cw_load64(p,tmpu64);
unpack_context->item.as.time.tv_sec = (int64_t)tmpu64;
return;
}
UNPACK_ERROR(CWP_RC_WRONG_TIMESTAMP_LENGTH)
Expand Down Expand Up @@ -731,7 +735,6 @@ void cw_skip_items (cw_unpack_context* unpack_context, long item_count)
UNPACK_ERROR(CWP_RC_MALFORMED_INPUT)
}
}
return;
}

/* end cwpack.c */
10 changes: 8 additions & 2 deletions src/cwpack.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void cw_pack_map_size (cw_pack_context* pack_context, uint32_t n);
void cw_pack_str (cw_pack_context* pack_context, const char* v, uint32_t l);
void cw_pack_bin (cw_pack_context* pack_context, const void* v, uint32_t l);
void cw_pack_ext (cw_pack_context* pack_context, int8_t type, const void* v, uint32_t l);
void cw_pack_time (cw_pack_context* pack_context, struct timespec* t);
void cw_pack_time (cw_pack_context* pack_context, int64_t sec, uint32_t nsec);

void cw_pack_insert (cw_pack_context* pack_context, const void* v, uint32_t l);

Expand Down Expand Up @@ -131,6 +131,12 @@ typedef struct {
} cwpack_container;


typedef struct {
int64_t tv_sec;
uint32_t tv_nsec;
} cwpack_timespec;


typedef struct {
cwpack_item_types type;
union
Expand All @@ -145,7 +151,7 @@ typedef struct {
cwpack_blob str;
cwpack_blob bin;
cwpack_blob ext;
struct timespec time;
cwpack_timespec time;
} as;
} cwpack_item;

Expand Down
2 changes: 1 addition & 1 deletion src/cwpack_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@
#ifndef FORCE_ALIGNMENT_64BIT
#define cw_load64(ptr,dest) dest = *(uint64_t*)ptr;
#else
#define cw_store64(x) memcpy(p,&x,8);
#define cw_load64(ptr,dest) memcpy(&dest,ptr,8);
#endif

#else /* Byte order little endian or undetermined */
Expand Down
22 changes: 20 additions & 2 deletions test/cwpack_module_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ int main(int argc, const char * argv[])
TESTP(unsigned,256,"cd0100");
TESTP(unsigned,65535,"cdffff");
TESTP(unsigned,65536,"ce00010000");
TESTP(unsigned,500000000,"ce1dcd6500");
TESTP(unsigned,0xffffffffUL,"ceffffffff");
TESTP(unsigned,0x100000000ULL,"cf0000000100000000");
TESTP(unsigned,0xffffffffffffffffULL,"cfffffffffffffffff");
Expand Down Expand Up @@ -314,7 +315,17 @@ int main(int argc, const char * argv[])
TESTP_EXT(ext,21,65535,"c8ffff15");
TESTP_EXT(ext,21,65536,"c90001000015");


pack_ctx.current = outbuffer;
cw_pack_time(&pack_ctx, 1, 0);
check_pack_result("d6ff00000001", 0);
pack_ctx.current = outbuffer;
cw_pack_time(&pack_ctx, 1, 2);
check_pack_result("d7ff0000000800000001", 0);
pack_ctx.current = outbuffer;
cw_pack_time(&pack_ctx, -1, 500000000);
check_pack_result("c70cff1dcd6500ffffffffffffffff", 0);

TESTP(time_interval,-0.5,"c70cff1dcd6500ffffffffffffffff");

//******************* TEST cwpack unpack **********************

Expand Down Expand Up @@ -390,7 +401,14 @@ int main(int argc, const char * argv[])
TESTUP_VAL("deffff",MAP,map.size,65535)
TESTUP_VAL("df00010000",MAP,map.size,65536)


// TESTUP timeStamp
TESTUP_VAL("d6ff00000001",TIMESTAMP,time.tv_sec,1);
TESTUP_VAL("d6ff00000001",TIMESTAMP,time.tv_nsec,0);
TESTUP_VAL("d7ff0000000800000001",TIMESTAMP,time.tv_sec,1);
TESTUP_VAL("d7ff0000000800000001",TIMESTAMP,time.tv_nsec,2);
TESTUP_VAL("c70cff1dcd6500ffffffffffffffff",TIMESTAMP,time.tv_sec,-1);
TESTUP_VAL("c70cff1dcd6500ffffffffffffffff",TIMESTAMP,time.tv_nsec,500000000);

#define TESTUP_AREA(buffer,etype,blob,len) \
blob_length = len; \
TESTUP_VAL(buffer,etype,blob.length,len) \
Expand Down

0 comments on commit d60634b

Please sign in to comment.