Return-Path: Delivered-To: apmail-hadoop-avro-commits-archive@minotaur.apache.org Received: (qmail 23683 invoked from network); 23 Jun 2009 20:17:44 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 23 Jun 2009 20:17:44 -0000 Received: (qmail 80537 invoked by uid 500); 23 Jun 2009 20:17:55 -0000 Delivered-To: apmail-hadoop-avro-commits-archive@hadoop.apache.org Received: (qmail 80522 invoked by uid 500); 23 Jun 2009 20:17:55 -0000 Mailing-List: contact avro-commits-help@hadoop.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: avro-dev@hadoop.apache.org Delivered-To: mailing list avro-commits@hadoop.apache.org Received: (qmail 80512 invoked by uid 99); 23 Jun 2009 20:17:55 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 23 Jun 2009 20:17:55 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 23 Jun 2009 20:17:45 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 761822388893; Tue, 23 Jun 2009 20:17:25 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r787820 [1/3] - in /hadoop/avro/trunk: ./ src/c/ src/c/json/ src/c/json/fail/ src/c/json/pass/ Date: Tue, 23 Jun 2009 20:17:23 -0000 To: avro-commits@hadoop.apache.org From: cutting@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090623201725.761822388893@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 +#include + +#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 +#include +#include +#include + +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 +#include +#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 +#include +#include +#include + +#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