Author: cutting
Date: Tue Jun 23 20:17:22 2009
New Revision: 787820
URL: http://svn.apache.org/viewvc?rev=787820&view=rev
Log:
AVRO-58: Add a JSON parser for C. Contributed by Matt Massie.
Added:
hadoop/avro/trunk/src/c/json/
hadoop/avro/trunk/src/c/json.c
hadoop/avro/trunk/src/c/json.h
hadoop/avro/trunk/src/c/json/README
hadoop/avro/trunk/src/c/json/fail/
hadoop/avro/trunk/src/c/json/fail/array_not_closed
hadoop/avro/trunk/src/c/json/fail/array_not_opened
hadoop/avro/trunk/src/c/json/fail/array_with_start_coma
hadoop/avro/trunk/src/c/json/fail/object_malformed
hadoop/avro/trunk/src/c/json/fail/object_not_closed
hadoop/avro/trunk/src/c/json/fail/object_not_opened
hadoop/avro/trunk/src/c/json/fail/object_with_start_coma
hadoop/avro/trunk/src/c/json/fail/object_with_string
hadoop/avro/trunk/src/c/json/fail/object_without_one_value
hadoop/avro/trunk/src/c/json/pass/
hadoop/avro/trunk/src/c/json/pass/array_multidimensional
hadoop/avro/trunk/src/c/json/pass/array_with_false
hadoop/avro/trunk/src/c/json/pass/array_with_ints
hadoop/avro/trunk/src/c/json/pass/array_with_null
hadoop/avro/trunk/src/c/json/pass/array_with_objects
hadoop/avro/trunk/src/c/json/pass/array_with_string
hadoop/avro/trunk/src/c/json/pass/array_with_true
hadoop/avro/trunk/src/c/json/pass/empty_array
hadoop/avro/trunk/src/c/json/pass/empty_object
hadoop/avro/trunk/src/c/json/pass/object_with_false
hadoop/avro/trunk/src/c/json/pass/object_with_multiple_members
hadoop/avro/trunk/src/c/json/pass/object_with_null
hadoop/avro/trunk/src/c/json/pass/object_with_object_member
hadoop/avro/trunk/src/c/json/pass/object_with_one_member
hadoop/avro/trunk/src/c/json/pass/object_with_true
hadoop/avro/trunk/src/c/json_schema.y
hadoop/avro/trunk/src/c/json_tokenizer.c
hadoop/avro/trunk/src/c/json_tokenizer.h
hadoop/avro/trunk/src/c/lemon.c
hadoop/avro/trunk/src/c/lempar.c
hadoop/avro/trunk/src/c/test_json_parser.c
Modified:
hadoop/avro/trunk/CHANGES.txt
hadoop/avro/trunk/src/c/ (props changed)
hadoop/avro/trunk/src/c/.gitignore
hadoop/avro/trunk/src/c/Makefile.am
hadoop/avro/trunk/src/c/avro.h
hadoop/avro/trunk/src/c/test_avro_float_double.c
Modified: hadoop/avro/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/CHANGES.txt?rev=787820&r1=787819&r2=787820&view=diff
==============================================================================
--- hadoop/avro/trunk/CHANGES.txt (original)
+++ hadoop/avro/trunk/CHANGES.txt Tue Jun 23 20:17:22 2009
@@ -33,6 +33,8 @@
arrays and maps to be efficiently written as sequences of blocks.
(Thiruvalluvan M. G. via cutting)
+ AVRO-48. Add JSON parser for C. (Matt Massie via cutting)
+
IMPROVEMENTS
AVRO-11. Re-implement specific and reflect datum readers and
Propchange: hadoop/avro/trunk/src/c/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Jun 23 20:17:22 2009
@@ -1,18 +1,28 @@
+*.la
+*.lo
+*.o
+*.swp
.deps
.libs
Makefile
Makefile.in
-*.la
-*.lo
-*.o
-configure
-stamp-h1
aclocal.m4
+autom4te.cache
+avro_schema.c
+avro_schema.h
+avro_schema.out
config
-libtool
-config.status
-config.log
-config.h.in
config.h
-autom4te.cache
+config.h.in
+config.log
+config.status
+configure
+json_schema.c
+json_schema.h
+json_schema.out
+lemon
+libtool
+stamp-h1
test_avro_*[!.][!c]
+test_json_*[!.][!c]
+trace.txt
Modified: hadoop/avro/trunk/src/c/.gitignore
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/.gitignore?rev=787820&r1=787819&r2=787820&view=diff
==============================================================================
--- hadoop/avro/trunk/src/c/.gitignore (original)
+++ hadoop/avro/trunk/src/c/.gitignore Tue Jun 23 20:17:22 2009
@@ -16,4 +16,14 @@
config.h
autom4te.cache
test_avro_*[!.][!c]
+test_json_*[!.][!c]
INSTALL
+lemon
+avro_schema.c
+avro_schema.h
+avro_schema.out
+json_schema.c
+json_schema.h
+json_schema.out
+trace.txt
+*.swp
Modified: hadoop/avro/trunk/src/c/Makefile.am
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/Makefile.am?rev=787820&r1=787819&r2=787820&view=diff
==============================================================================
--- hadoop/avro/trunk/src/c/Makefile.am (original)
+++ hadoop/avro/trunk/src/c/Makefile.am Tue Jun 23 20:17:22 2009
@@ -1,15 +1,24 @@
AM_CFLAGS=$(APR_CFLAGS) $(APR_INCLUDES) $(APU_INCLUDES) -Wall -pedantic
C_DOCS_OUTPUT ?= "docs/dox"
+EXTRA_DIST=json_schema.y
+
include_HEADERS = avro.h
lib_LTLIBRARIES = libavro.la
libavro_la_SOURCES = avro_memory.c avro_socket.c avro_file.c \
dump.c dump.h avro.c avro_string.c avro_zigzag.c error.c error.h avro_raw.c \
-avro_double.c
+avro_double.c json_schema.h json_schema.c json_tokenizer.c json.c json.h
check_PROGRAMS=test_avro_zigzag test_avro_string test_avro_bytes test_avro_raw
\
-test_avro_float_double
+test_avro_float_double test_json_parser
+
+noinst_PROGRAMS=lemon
+lemon_SOURCES=lemon.c
+
+json_schema.h json_schema.c: lemon json_schema.y
+ ./lemon ./json_schema.y
+ touch json_schema.c json_schema.h
test_avro_zigzag_SOURCE=test_avro_zigzag.c
test_avro_zigzag_LDADD=$(APR_LIBS) $(APU_LIBS) $(top_builddir)/libavro.la
@@ -26,10 +35,15 @@
test_avro_float_double_SOURCE=test_avro_float_double.c
test_avro_float_double_LDADD=$(APR_LIBS) $(APU_LIBS) $(top_builddir)/libavro.la
+test_json_parser=test_json_parser.c
+test_json_parser_LDADD=$(APR_LIBS) $(APU_LIBS) $(top_builddir)/libavro.la
+
TESTS=$(check_PROGRAMS)
+# Some files should not be run through indent
+pretty_files := $(shell echo *.[c,h]| sed s/lempar.c// | sed s/avro.h// | sed
s/lemon.c//)
pretty:
- indent *.c
+ @indent $(pretty_files)
docs:
@(cat docs/doxygen.conf; echo "OUTPUT_DIRECTORY=$(C_DOCS_OUTPUT)")|
doxygen -
Modified: hadoop/avro/trunk/src/c/avro.h
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/avro.h?rev=787820&r1=787819&r2=787820&view=diff
==============================================================================
--- hadoop/avro/trunk/src/c/avro.h (original)
+++ hadoop/avro/trunk/src/c/avro.h Tue Jun 23 20:17:22 2009
@@ -74,6 +74,7 @@
const int64_t len);
} *a_ops;
apr_pool_t *pool; /**< Pool used for allocating memory for dynamic data
structures */
+ unsigned char *schema; /**< Current AVRO schema for processing data */
apr_file_t *file; /**< Used by the file-backed handle */
apr_socket_t *socket; /**< Used by the socket-backed handle */
@@ -121,7 +122,7 @@
apr_socket_t * socket, avro_op op);
/** @} */
-typedef avro_status_t (*avroproc_t) (AVRO, void *, ...);
+typedef avro_status_t (*avroproc_t) (AVRO *, void *, ...);
typedef int bool_t;
/**
Added: hadoop/avro/trunk/src/c/json.c
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json.c?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json.c (added)
+++ hadoop/avro/trunk/src/c/json.c Tue Jun 23 20:17:22 2009
@@ -0,0 +1,202 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "json.h"
+#include "json_tokenizer.h"
+
+static void
+ws_depth (FILE * file, int depth)
+{
+ int i;
+ for (i = 0; i < depth; i++)
+ {
+ fprintf (file, " ");
+ }
+}
+
+static void
+JSON_print_private (FILE * file, JSON_value * value, int *depth)
+{
+ int i;
+ switch (value->type)
+ {
+ case JSON_UNKNOWN:
+ fprintf (file, "???");
+ return;
+ case JSON_STRING:
+ fprintf (file, "\"%s\"", value->string_value);
+ return;
+ case JSON_NUMBER:
+ fprintf (file, "%E", value->number_value);
+ return;
+ case JSON_BOOLEAN:
+ fprintf (file, "%s", value->boolean_value ? "true" : "false");
+ return;
+ case JSON_NULL:
+ fprintf (file, "null");
+ return;
+ case JSON_ARRAY:
+ (*depth)++;
+ fprintf (file, "[\n");
+ for (i = 0; i < value->array_value->nelts; i++)
+ {
+ if (i)
+ {
+ fprintf (file, ",\n");
+ }
+ ws_depth (file, *depth);
+ JSON_print_private (file,
+ ((JSON_value **) value->array_value->elts)[i],
+ depth);
+ }
+ fprintf (file, "\n");
+ (*depth)--;
+ ws_depth (file, *depth);
+ fprintf (file, "]");
+ break;
+ case JSON_OBJECT:
+ {
+ apr_hash_index_t *hi;
+ char *key;
+ apr_ssize_t len;
+ JSON_value *member_value;
+
+ (*depth)++;
+ fprintf (file, "{\n");
+ for (i = 0, hi = apr_hash_first (value->pool, value->object_value);
+ hi; hi = apr_hash_next (hi), i++)
+ {
+ if (i)
+ {
+ fprintf (file, ",\n");
+ }
+ apr_hash_this (hi, (void *) &key, &len, (void *) &member_value);
+ ws_depth (file, *depth);
+ fprintf (file, "\"%s\" :", key);
+ JSON_print_private (file, member_value, depth);
+ }
+ fprintf (file, "\n");
+ (*depth)--;
+ ws_depth (file, *depth);
+ fprintf (file, "}");
+ }
+ break;
+ }
+ return;
+}
+
+void
+JSON_print (FILE * file, JSON_value * value)
+{
+ int depth = 0;
+ if (!file || !value)
+ {
+ return;
+ }
+ JSON_print_private (file, value, &depth);
+ fprintf (file, "\n");
+}
+
+JSON_value *
+JSON_value_new (apr_pool_t * pool, int type)
+{
+ JSON_value *value = NULL;
+ if (pool)
+ {
+ value = (JSON_value *) apr_palloc (pool, sizeof (JSON_value));
+ value->pool = pool;
+ value->type = type;
+ /* TODO: mark callbacks based on type */
+ }
+ return value;
+}
+
+static JSON_value *
+JSON_parse_inner (void *jsonp, apr_pool_t * pool, char *text, int text_len)
+{
+ int len;
+ char *cur, *text_end;
+ JSON_value *value = NULL;
+ JSON_ctx ctx;
+
+ /* Setup the context */
+ ctx.pool = pool;
+ ctx.error = 0;
+ ctx.result = NULL;
+
+ /* Loop through the input */
+ for (cur = text, text_end = text + text_len; cur < text_end; cur += len)
+ {
+ int tokenType;
+ double number;
+
+ len = json_get_token (cur, text_end - cur, &tokenType, &number);
+ if (len < 0)
+ {
+ return NULL;
+ }
+
+ value = NULL;
+ switch (tokenType)
+ {
+ /* Manage our terminals here. Non-terminals are managed in the
schema. */
+
+ case TK_SPACE:
+ /* Ignore whitespace */
+ continue;
+
+ case TK_COLON:
+ case TK_COMMA:
+ /* Don't create JSON_values for these terminals */
+ break;
+
+ case TK_STRING:
+ value = JSON_value_new (pool, JSON_STRING);
+ value->string_value = apr_palloc (pool, len + 1);
+ /* Take off the quotes */
+ memcpy (value->string_value, cur + 1, len - 1);
+ /* TODO: e.g. substitute \" for " */
+ value->string_value[len - 2] = '\0';
+ break;
+
+ case TK_NUMBER:
+ value = JSON_value_new (pool, JSON_NUMBER);
+ value->number_value = number;
+ break;
+
+ case TK_TRUE:
+ case TK_FALSE:
+ value = JSON_value_new (pool, JSON_BOOLEAN);
+ value->boolean_value = tokenType == TK_FALSE ? 0 : 1;
+ break;
+
+ case TK_NULL:
+ value = JSON_value_new (pool, JSON_NULL);
+ break;
+
+ }
+
+ JSONParser (jsonp, tokenType, value, &ctx);
+ if (ctx.error)
+ {
+ return NULL;
+ }
+ }
+ JSONParser (jsonp, 0, value, &ctx);
+ return ctx.result;
+}
+
+JSON_value *
+JSON_parse (apr_pool_t * pool, char *text, int text_len)
+{
+ JSON_value *value;
+ /* Too bad I can't use the pool here... */
+ void *jsonp = JSONParserAlloc (malloc);
+ if (jsonp == NULL)
+ {
+ return NULL;
+ }
+ value = JSON_parse_inner (jsonp, pool, text, text_len);
+ JSONParserFree (jsonp, free);
+ return value;
+}
Added: hadoop/avro/trunk/src/c/json.h
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json.h?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json.h (added)
+++ hadoop/avro/trunk/src/c/json.h Tue Jun 23 20:17:22 2009
@@ -0,0 +1,61 @@
+#ifndef JSON_H
+#define JSON_H
+
+#include <apr.h>
+#include <apr_pools.h>
+#include <apr_tables.h>
+#include <apr_hash.h>
+
+enum JSON_type
+{
+ JSON_UNKNOWN,
+ JSON_OBJECT,
+ JSON_ARRAY,
+ JSON_STRING,
+ JSON_NUMBER,
+ JSON_BOOLEAN,
+ JSON_NULL
+};
+typedef enum JSON_type JSON_type;
+
+struct JSON_value
+{
+ JSON_type type;
+ union
+ {
+ apr_hash_t *object;
+ apr_array_header_t *array;
+ char *z;
+ double number;
+ int boolean;
+ } value_u;
+ apr_pool_t *pool;
+};
+typedef struct JSON_value JSON_value;
+#define object_value value_u.object
+#define array_value value_u.array
+#define string_value value_u.z
+#define number_value value_u.number
+#define boolean_value value_u.boolean
+
+JSON_value *JSON_parse (apr_pool_t * pool, char *text, int text_len);
+
+JSON_value *JSON_value_new (apr_pool_t * pool, int type);
+
+void JSON_print (FILE * file, JSON_value * value);
+
+struct JSON_ctx
+{
+ apr_pool_t *pool;
+ JSON_value *result;
+ int error;
+};
+typedef struct JSON_ctx JSON_ctx;
+
+/* in json_schema.c */
+void *JSONParserAlloc (void *(*mallocProc) (size_t));
+void JSONParser (void *yyp, int yymajor, JSON_value * value, JSON_ctx * ctx);
+void JSONParserFree (void *p, void (*freeProc) (void *));
+void JSONParserTrace (FILE * TraceFILE, char *zTracePrompt);
+
+#endif
Added: hadoop/avro/trunk/src/c/json/README
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/README?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/README (added)
+++ hadoop/avro/trunk/src/c/json/README Tue Jun 23 20:17:22 2009
@@ -0,0 +1,7 @@
+This directory is used by test_json_parser
+
+The "pass" directory contains schema definitions that
+should parse without error.
+
+The "fail" directory contains shema definitions that
+should *not* parse but instead throw an error.
Added: hadoop/avro/trunk/src/c/json/fail/array_not_closed
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/fail/array_not_closed?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/fail/array_not_closed (added)
+++ hadoop/avro/trunk/src/c/json/fail/array_not_closed Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+[
Added: hadoop/avro/trunk/src/c/json/fail/array_not_opened
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/fail/array_not_opened?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/fail/array_not_opened (added)
+++ hadoop/avro/trunk/src/c/json/fail/array_not_opened Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+]
Added: hadoop/avro/trunk/src/c/json/fail/array_with_start_coma
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/fail/array_with_start_coma?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/fail/array_with_start_coma (added)
+++ hadoop/avro/trunk/src/c/json/fail/array_with_start_coma Tue Jun 23 20:17:22
2009
@@ -0,0 +1 @@
+[ , "foo" ]
Added: hadoop/avro/trunk/src/c/json/fail/object_malformed
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/fail/object_malformed?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/fail/object_malformed (added)
+++ hadoop/avro/trunk/src/c/json/fail/object_malformed Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+{"foo:"}
Added: hadoop/avro/trunk/src/c/json/fail/object_not_closed
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/fail/object_not_closed?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/fail/object_not_closed (added)
+++ hadoop/avro/trunk/src/c/json/fail/object_not_closed Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+{
Added: hadoop/avro/trunk/src/c/json/fail/object_not_opened
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/fail/object_not_opened?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/fail/object_not_opened (added)
+++ hadoop/avro/trunk/src/c/json/fail/object_not_opened Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+}
Added: hadoop/avro/trunk/src/c/json/fail/object_with_start_coma
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/fail/object_with_start_coma?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/fail/object_with_start_coma (added)
+++ hadoop/avro/trunk/src/c/json/fail/object_with_start_coma Tue Jun 23
20:17:22 2009
@@ -0,0 +1 @@
+{,"foo" : "bar" }
Added: hadoop/avro/trunk/src/c/json/fail/object_with_string
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/fail/object_with_string?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/fail/object_with_string (added)
+++ hadoop/avro/trunk/src/c/json/fail/object_with_string Tue Jun 23 20:17:22
2009
@@ -0,0 +1 @@
+{ "Fail" }
Added: hadoop/avro/trunk/src/c/json/fail/object_without_one_value
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/fail/object_without_one_value?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/fail/object_without_one_value (added)
+++ hadoop/avro/trunk/src/c/json/fail/object_without_one_value Tue Jun 23
20:17:22 2009
@@ -0,0 +1 @@
+{ "one", "two": "foobar" }
Added: hadoop/avro/trunk/src/c/json/pass/array_multidimensional
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/array_multidimensional?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/array_multidimensional (added)
+++ hadoop/avro/trunk/src/c/json/pass/array_multidimensional Tue Jun 23
20:17:22 2009
@@ -0,0 +1 @@
+[ [ "one", "array" ], [ "two", "array" ], [ "three", [ "four" ] ] ]
Added: hadoop/avro/trunk/src/c/json/pass/array_with_false
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/array_with_false?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/array_with_false (added)
+++ hadoop/avro/trunk/src/c/json/pass/array_with_false Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+[ false ]
Added: hadoop/avro/trunk/src/c/json/pass/array_with_ints
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/array_with_ints?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/array_with_ints (added)
+++ hadoop/avro/trunk/src/c/json/pass/array_with_ints Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+[ 1, 1.0, -1, 3e4, 3e+5, 3e-10, 2.0E+13, 44E-2 ]
Added: hadoop/avro/trunk/src/c/json/pass/array_with_null
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/array_with_null?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/array_with_null (added)
+++ hadoop/avro/trunk/src/c/json/pass/array_with_null Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+[ null ]
Added: hadoop/avro/trunk/src/c/json/pass/array_with_objects
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/array_with_objects?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/array_with_objects (added)
+++ hadoop/avro/trunk/src/c/json/pass/array_with_objects Tue Jun 23 20:17:22
2009
@@ -0,0 +1,2 @@
+[ { "foo" : "bar" }, {"baz": "value"}
+]
Added: hadoop/avro/trunk/src/c/json/pass/array_with_string
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/array_with_string?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/array_with_string (added)
+++ hadoop/avro/trunk/src/c/json/pass/array_with_string Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+[ "Hi" ]
Added: hadoop/avro/trunk/src/c/json/pass/array_with_true
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/array_with_true?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/array_with_true (added)
+++ hadoop/avro/trunk/src/c/json/pass/array_with_true Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+[ true ]
Added: hadoop/avro/trunk/src/c/json/pass/empty_array
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/empty_array?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/empty_array (added)
+++ hadoop/avro/trunk/src/c/json/pass/empty_array Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+[]
Added: hadoop/avro/trunk/src/c/json/pass/empty_object
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/empty_object?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/empty_object (added)
+++ hadoop/avro/trunk/src/c/json/pass/empty_object Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+{}
Added: hadoop/avro/trunk/src/c/json/pass/object_with_false
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/object_with_false?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/object_with_false (added)
+++ hadoop/avro/trunk/src/c/json/pass/object_with_false Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+{ "two" : false }
Added: hadoop/avro/trunk/src/c/json/pass/object_with_multiple_members
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/object_with_multiple_members?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/object_with_multiple_members (added)
+++ hadoop/avro/trunk/src/c/json/pass/object_with_multiple_members Tue Jun 23
20:17:22 2009
@@ -0,0 +1,3 @@
+{ "one" : "value",
+"two" : "value",
+"three" : "value" }
Added: hadoop/avro/trunk/src/c/json/pass/object_with_null
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/object_with_null?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/object_with_null (added)
+++ hadoop/avro/trunk/src/c/json/pass/object_with_null Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+{ "three" : null }
Added: hadoop/avro/trunk/src/c/json/pass/object_with_object_member
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/object_with_object_member?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/object_with_object_member (added)
+++ hadoop/avro/trunk/src/c/json/pass/object_with_object_member Tue Jun 23
20:17:22 2009
@@ -0,0 +1 @@
+{ "foo" : { "This" : "works" } }
Added: hadoop/avro/trunk/src/c/json/pass/object_with_one_member
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/object_with_one_member?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/object_with_one_member (added)
+++ hadoop/avro/trunk/src/c/json/pass/object_with_one_member Tue Jun 23
20:17:22 2009
@@ -0,0 +1 @@
+{ "key" : "value" }
Added: hadoop/avro/trunk/src/c/json/pass/object_with_true
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json/pass/object_with_true?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json/pass/object_with_true (added)
+++ hadoop/avro/trunk/src/c/json/pass/object_with_true Tue Jun 23 20:17:22 2009
@@ -0,0 +1 @@
+{ "one" : true }
Added: hadoop/avro/trunk/src/c/json_schema.y
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json_schema.y?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json_schema.y (added)
+++ hadoop/avro/trunk/src/c/json_schema.y Tue Jun 23 20:17:22 2009
@@ -0,0 +1,106 @@
+/*
+RFC 4627
+http://tools.ietf.org/html/rfc4627
+*/
+%name JSONParser
+
+%token_type {JSON_value *}
+%default_type {JSON_value *}
+
+%extra_argument { JSON_ctx *ctx }
+
+%include {
+#include <stdio.h>
+#include <assert.h>
+#include "json.h"
+#include "json_tokenizer.h"
+
+#if 0
+#define DEBUG_PARSER(stmt) stmt
+#else
+#define DEBUG_PARSER(stmt)
+#endif
+
+#define NUM_INIT_ELEMENTS 16
+}
+
+%parse_accept {
+ DEBUG_PARSER(fprintf(stderr,"Input parsed and accepted\n"));
+}
+
+%syntax_error {
+ ctx->error = 1;
+ DEBUG_PARSER(fprintf(stderr,"Syntax error\n"));
+}
+
+%token_prefix TK_
+
+json ::= jsontext(A).
+{
+ ctx->result = A;
+}
+
+jsontext(A) ::= object(B). { A=B; }
+jsontext(A) ::= array(B). { A=B; }
+
+/* Values */
+value(A) ::= STRING(B). { A=B; }
+value(A) ::= NUMBER(B). { A=B; }
+value(A) ::= object(B). { A=B; }
+value(A) ::= array(B). { A=B; }
+value(A) ::= TRUE(B). { A=B; }
+value(A) ::= FALSE(B). { A=B; }
+value(A) ::= NULL(B). { A=B; }
+
+/* Arrays */
+%type element_list {apr_array_header_t *}
+%type elements {apr_array_header_t *}
+
+element_list(A) ::= elements(B) COMMA.
+{
+ A=B;
+}
+element_list(A) ::= .
+{
+ A=apr_array_make(ctx->pool, NUM_INIT_ELEMENTS, sizeof(JSON_value *));
+}
+elements(A) ::= element_list(B) value(C).
+{
+ A = B;
+ *(JSON_value **)apr_array_push(B) = C;
+}
+elements(A) ::= element_list(B) .
+{
+ A = B;
+}
+array(A) ::= LBRACKET elements(B) RBRACKET.
+{
+ A = JSON_value_new(ctx->pool, JSON_ARRAY);
+ A->array_value = B;
+}
+
+/* Objects */
+%type member_list {apr_hash_t *}
+%type members {apr_hash_t *}
+member_list(A) ::= members(B) COMMA.
+{
+ A = B;
+}
+member_list(A) ::= .
+{
+ A = apr_hash_make(ctx->pool);
+}
+members(A) ::= member_list(B) STRING(C) COLON value(D).
+{
+ A = B;
+ apr_hash_set(B, C->string_value, APR_HASH_KEY_STRING, D);
+}
+members(A) ::= member_list(B).
+{
+ A = B;
+}
+object(A) ::= LCURLY members(B) RCURLY.
+{
+ A = JSON_value_new(ctx->pool, JSON_OBJECT);
+ A->object_value = B;
+}
Added: hadoop/avro/trunk/src/c/json_tokenizer.c
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json_tokenizer.c?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json_tokenizer.c (added)
+++ hadoop/avro/trunk/src/c/json_tokenizer.c Tue Jun 23 20:17:22 2009
@@ -0,0 +1,114 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "json_tokenizer.h"
+
+static struct keyword
+{
+ char *z;
+ int len;
+ int tokenType;
+} keywords[] =
+{
+ {
+ "true", 4, TK_TRUE},
+ {
+ "false", 5, TK_FALSE},
+ {
+ "null", 4, TK_NULL}
+};
+
+#define NUM_KEYWORDS (sizeof(keywords)/sizeof(keywords[0]))
+
+int
+json_get_token (const char *z, const unsigned len, int *tokenType,
+ double *number)
+{
+ char *p;
+ int i;
+ if (!z || !tokenType || len == 0 || !number)
+ {
+ return -1;
+ }
+
+ if (isspace (z[0]))
+ {
+ for (i = 1; isspace (z[i]); i++)
+ {
+ }
+ *tokenType = TK_SPACE;
+ return i;
+ }
+
+ switch (*z)
+ {
+ case '"':
+ {
+ /* Find the end quote */
+ for (i = 1; i < len; i++)
+ {
+ /* TODO: escape characters? */
+ if (z[i] == '"' && z[i - 1] != '\\')
+ {
+ *tokenType = TK_STRING;
+ return i + 1;
+ }
+ }
+ /* TODO: think about this... */
+ break;
+ }
+ case ':':
+ {
+ *tokenType = TK_COLON;
+ return 1;
+ }
+ case ',':
+ {
+ *tokenType = TK_COMMA;
+ return 1;
+ }
+ case '{':
+ {
+ *tokenType = TK_LCURLY;
+ return 1;
+ }
+ case '}':
+ {
+ *tokenType = TK_RCURLY;
+ return 1;
+ }
+ case '[':
+ {
+ *tokenType = TK_LBRACKET;
+ return 1;
+ }
+ case ']':
+ {
+ *tokenType = TK_RBRACKET;
+ return 1;
+ }
+ }
+ /* check for keywords */
+ for (i = 0; i < NUM_KEYWORDS; i++)
+ {
+ struct keyword *kw = keywords + i;
+ if (strncmp ((char *) z, kw->z, kw->len) == 0)
+ {
+ *tokenType = kw->tokenType;
+ return kw->len;
+ }
+ }
+ /* Check for number */
+ *number = strtod (z, &p);
+ if (p != z)
+ {
+ *tokenType = TK_NUMBER;
+ return (p - z);
+ }
+
+ /* ???? */
+ *tokenType = 0;
+ return 1;
+}
Added: hadoop/avro/trunk/src/c/json_tokenizer.h
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/c/json_tokenizer.h?rev=787820&view=auto
==============================================================================
--- hadoop/avro/trunk/src/c/json_tokenizer.h (added)
+++ hadoop/avro/trunk/src/c/json_tokenizer.h Tue Jun 23 20:17:22 2009
@@ -0,0 +1,23 @@
+#ifndef JSON_TOKENIZER_H
+#define JSON_TOKENIZER_H
+
+#include "json_schema.h"
+
+/* Tokens which are not part of the schema */
+enum json_tokens
+{
+ TK_SPACE = 42424242
+};
+
+struct Token
+{
+ char *z;
+ double d;
+ int b;
+};
+typedef struct Token Token;
+
+int json_get_token (const char *z, const unsigned len, int *tokenType,
+ double *number);
+
+#endif