diff --git a/goodies/objC/cwpack_objc.m b/goodies/objC/cwpack_objc.m index 782ced9..11773eb 100755 --- a/goodies/objC/cwpack_objc.m +++ b/goodies/objC/cwpack_objc.m @@ -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); @@ -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 diff --git a/goodies/utils/cwpack_utils.c b/goodies/utils/cwpack_utils.c index bfdaaa9..7d082b5 100755 --- a/goodies/utils/cwpack_utils.c +++ b/goodies/utils/cwpack_utils.c @@ -21,6 +21,7 @@ */ +#include #include "cwpack_utils.h" @@ -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 ******************************/ @@ -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; } diff --git a/goodies/utils/cwpack_utils.h b/goodies/utils/cwpack_utils.h index abb6fc4..09450c2 100644 --- a/goodies/utils/cwpack_utils.h +++ b/goodies/utils/cwpack_utils.h @@ -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 ********************************/ diff --git a/src/cwpack.c b/src/cwpack.c index 20dd064..6fb2710 100644 --- a/src/cwpack.c +++ b/src/cwpack.c @@ -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) @@ -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); } } @@ -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) @@ -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 */ diff --git a/src/cwpack.h b/src/cwpack.h index 3e06ff6..c347ab9 100644 --- a/src/cwpack.h +++ b/src/cwpack.h @@ -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); @@ -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 @@ -145,7 +151,7 @@ typedef struct { cwpack_blob str; cwpack_blob bin; cwpack_blob ext; - struct timespec time; + cwpack_timespec time; } as; } cwpack_item; diff --git a/src/cwpack_internals.h b/src/cwpack_internals.h index 92c39ce..b03b3f1 100644 --- a/src/cwpack_internals.h +++ b/src/cwpack_internals.h @@ -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 */ diff --git a/test/cwpack_module_test.c b/test/cwpack_module_test.c index 9d260f0..d2889ec 100644 --- a/test/cwpack_module_test.c +++ b/test/cwpack_module_test.c @@ -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"); @@ -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 ********************** @@ -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) \