]> thyrsus.com Git - microjson.git/commitdiff
Being reintegrating t_time.
authorEric S. Raymond <esr@thyrsus.com>
Sun, 28 Sep 2014 00:32:18 +0000 (20:32 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Sun, 28 Sep 2014 00:32:18 +0000 (20:32 -0400)
Makefile
mjson.c
mjson.h

index be1e8a117729504c44477c3f4caa87eb3c96aede..718635ef19f4ccd8d5f0e93294e34b9117eae671 100644 (file)
--- 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 e735d8b657204c8d4a714b22d4a10443bbd87b87..b5e2fd9c7e1d9312038d20f269933ae2e0a8efde 100644 (file)
--- 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 <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -64,6 +70,7 @@ PERMISSIONS
 #include <stdarg.h>
 #include <ctype.h>
 #include <errno.h>
+#include <time.h>
 
 #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 948092ab8bd700e17ceb03d18c2eea328c291c87..c4b5697b4ed50390cefb2779f7469edc45f9a328 100644 (file)
--- a/mjson.h
+++ b/mjson.h
@@ -6,11 +6,14 @@
 
 #include <stdbool.h>
 #include <ctype.h>
+#include <stdio.h>
+#include <sys/types.h>
 
 #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;