From: Eric S. Raymond Date: Sun, 28 Sep 2014 00:32:18 +0000 (-0400) Subject: Being reintegrating t_time. X-Git-Tag: 1.3~7 X-Git-Url: http://thyrsus.com/gitweb/?a=commitdiff_plain;h=b7a11603bd7dd6b8e5a8649c55107dae2cca0d61;p=microjson.git Being reintegrating t_time. --- diff --git a/Makefile b/Makefile index be1e8a1..718635e 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,8 @@ CFLAGS = -O # Add DEBUG_ENABLE for the tracing code CFLAGS += -DDEBUG_ENABLE -g +# Add TIME_ENABLE to support RFC3339 time literals +CFLAGS += -DTIME_ENABLE all: mjson.o test_microjson example1 example2 example3 @test_microjson diff --git a/mjson.c b/mjson.c index e735d8b..b5e2fd9 100644 --- a/mjson.c +++ b/mjson.c @@ -57,6 +57,12 @@ PERMISSIONS BSD terms apply: see the file COPYING in the distribution root for details. ***************************************************************************/ +/* The strptime prototype is not provided unless explicitly requested. + * We also need to set the value high enough to signal inclusion of + * newer features (like clock_gettime). See the POSIX spec for more info: + * http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_02_01_02 */ +#define _XOPEN_SOURCE 600 + #include #include #include @@ -64,6 +70,7 @@ PERMISSIONS #include #include #include +#include #include "mjson.h" @@ -120,6 +127,7 @@ static /*@null@*/ char *json_target_address(const struct json_attr_t *cursor, case t_uinteger: targetaddr = (char *)&cursor->addr.uinteger[offset]; break; + case t_time: case t_real: targetaddr = (char *)&cursor->addr.real[offset]; break; @@ -146,6 +154,23 @@ static /*@null@*/ char *json_target_address(const struct json_attr_t *cursor, return targetaddr; } +#ifdef TIME_ENABLE +static double iso8601_to_unix( /*@in@*/ char *isotime) +/* ISO8601 UTC to Unix UTC */ +{ + char *dp = NULL; + double usec; + struct tm tm; + + /*@i1@*/ dp = strptime(isotime, "%Y-%m-%dT%H:%M:%S", &tm); + if (dp != NULL && *dp == '.') + usec = strtod(dp, NULL); + else + usec = 0; + return (double)timegm(&tm) + usec; +} +#endif /* TIME_ENABLE */ + /*@-immediatetrans -dependenttrans +usereleased +compdef@*/ static int json_internal_read_object(const char *cp, @@ -197,6 +222,7 @@ static int json_internal_read_object(const char *cp, case t_uinteger: memcpy(lptr, &cursor->dflt.uinteger, sizeof(unsigned int)); break; + case t_time: case t_real: memcpy(lptr, &cursor->dflt.real, sizeof(double)); break; @@ -286,7 +312,7 @@ static int json_internal_read_object(const char *cp, maxlen = (int)cursor->len - 1; else if (cursor->type == t_check) maxlen = (int)strlen(cursor->dflt.check); - else if (cursor->type == t_ignore) + else if (cursor->type == t_time || cursor->type == t_ignore) maxlen = JSON_VAL_MAX; else if (cursor->map != NULL) maxlen = (int)sizeof(valbuf) - 1; @@ -413,7 +439,7 @@ static int json_internal_read_object(const char *cp, */ for (;;) { int seeking = cursor->type; - if (value_quoted && cursor->type == t_string) + if (value_quoted && (cursor->type == t_string || cursor->type == t_time)) break; if ((strcmp(valbuf, "true")==0 || strcmp(valbuf, "false")==0) && seeking == t_boolean) @@ -433,7 +459,7 @@ static int json_internal_read_object(const char *cp, } if (value_quoted && (cursor->type != t_string && cursor->type != t_character - && cursor->type != t_check + && cursor->type != t_check && cursor->type != t_time && cursor->type != t_ignore && cursor->map == 0)) { json_debug_trace((1, "Saw quoted value when expecting non-string.\n")); @@ -441,7 +467,7 @@ static int json_internal_read_object(const char *cp, } if (!value_quoted && (cursor->type == t_string || cursor->type == t_check - || cursor->map != 0)) { + || cursor->type == t_time || cursor->map != 0)) { json_debug_trace((1, "Didn't see quoted value when expecting string.\n")); return JSON_ERR_NONQSTRING; @@ -472,6 +498,14 @@ static int json_internal_read_object(const char *cp, memcpy(lptr, &tmp, sizeof(unsigned int)); } break; + case t_time: +#ifdef TIME_ENABLE + { + double tmp = iso8601_to_unix(valbuf); + memcpy(lptr, &tmp, sizeof(double)); + } +#endif /* TIME_ENABLE */ + break; case t_real: { double tmp = atof(valbuf); diff --git a/mjson.h b/mjson.h index 948092a..c4b5697 100644 --- a/mjson.h +++ b/mjson.h @@ -6,11 +6,14 @@ #include #include +#include +#include #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0])) typedef enum {t_integer, t_uinteger, t_real, t_string, t_boolean, t_character, + t_time, t_object, t_structobject, t_array, t_check, t_ignore} json_type;