added license info and some additional comments
authorerickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Fri, 1 Jul 2005 19:53:44 +0000 (19:53 +0000)
committererickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Fri, 1 Jul 2005 19:53:44 +0000 (19:53 +0000)
git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@377 9efc2488-bf62-4759-914b-345cdb29e865

src/objson/Makefile
src/objson/json_parser.c
src/objson/json_parser.h
src/objson/object.c
src/objson/object.h
src/objson/objson_test.c

index 2c65709..09e7fdf 100644 (file)
@@ -1,3 +1,20 @@
+# --------------------------------------------------------------------
+# Copyright (C) 2005  Georgia Public Library Service 
+# Bill Erickson <highfalutin@gmail.com>
+# Mike Rylander <mrylander@gmail.com>
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# --------------------------------------------------------------------
+
+
 OBJS                   = object.o json_parser.o utils.o
 UTIL_DIR               = ../utils
 DEST_INCLUDE = objson
index f6ebfe0..b82e93c 100644 (file)
@@ -1,3 +1,19 @@
+/*
+Copyright (C) 2005  Georgia Public Library Service 
+Bill Erickson <highfalutin@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+*/
+
+
 #include "json_parser.h"
 
 /* keep a copy of the length of the current json string so we don't 
@@ -406,7 +422,8 @@ int json_parse_json_string(char* string, unsigned long* index, object* obj) {
 
                                        /* ----------------------------------------------------------------------- */
                                        /* ----------------------------------------------------------------------- */
-                                       /* This was taken directly from json-c http://oss.metaparadigm.com/json-c/ */
+                                       /* The following chunk was borrowed with permission from 
+                                               json-c http://oss.metaparadigm.com/json-c/ */
                                        unsigned char utf_out[3];
                                        memset(utf_out,0,3);
 
@@ -436,7 +453,6 @@ int json_parse_json_string(char* string, unsigned long* index, object* obj) {
                                        /* ----------------------------------------------------------------------- */
                                        /* ----------------------------------------------------------------------- */
 
-
                                        (*index) += 3;
                                        in_escape = 0;
 
index 29d795d..5fb7d6b 100644 (file)
@@ -1,8 +1,24 @@
+/*
+Copyright (C) 2005  Georgia Public Library Service 
+Bill Erickson <highfalutin@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+*/
+
+
+
+
 /* ---------------------------------------------------------------------------------------
        JSON parser.
  * --------------------------------------------------------------------------------------- */
-
-
 #include <stdio.h>
 #include "object.h"
 #include "utils.h"
 #define JSON_PARSER_H
 
 
+/* Parses the given JSON string and returns the built object. 
+ *     returns NULL (and prints parser error to stderr) on error.  
+ * if string is NULL, returns an object whose is_null flag  is set to true. 
+ */
+object* json_parse_string(char* string);
+
 
 
-/* returns NULL on error.  if string is NULL, returns an object whose is_null flag  
- * is set to true */
-object* json_parse_string(char* string);
 
 /* does the actual parsing work.  returns 0 on success.  -1 on error and
  * -2 if there was no object to build (string was all comments) 
@@ -28,13 +47,14 @@ int json_parse_json_string(char* string, unsigned long* index, object* obj);
 /* returns 0 on success and turns obj into a number or double object */
 int json_parse_json_number(char* string, unsigned long* index, object* obj);
 
+/* returns 0 on success and turns obj into an 'object' object */
 int json_parse_json_object(char* string, unsigned long* index, object* obj);
 
 /* returns 0 on success and turns object into an array object */
 int json_parse_json_array(char* string, unsigned long* index, object* obj);
 
 /* churns through whitespace and increments index as it goes.
- * eat_all means we should eat newlines, tabs
+ * eat_all == true means we should eat newlines, tabs
  */
 void json_eat_ws(char* string, unsigned long* index, int eat_all);
 
index c8d5222..59a77d8 100644 (file)
@@ -1,3 +1,18 @@
+/*
+Copyright (C) 2005  Georgia Public Library Service 
+Bill Erickson <highfalutin@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+*/
+
 #include "object.h"
 #include "json_parser.h"
 #include <fcntl.h>
@@ -19,7 +34,7 @@ object* _init_object(char* string_value) {
        obj->data                       = NULL;
 
        obj->push                       = &object_push;
-       obj->add_index          = &object_add_index;
+       obj->set_index          = &object_set_index;
        obj->add_key            = &object_add_key;
        obj->get_index          = &object_get_index;
        obj->get_key            = &object_get_key;
@@ -81,7 +96,7 @@ unsigned long object_push(object* obj, object* new_obj) {
        return obj->size;
 }
 
-unsigned long  object_add_index(object* obj, unsigned long index, object* new_obj) {
+unsigned long  object_set_index(object* obj, unsigned long index, object* new_obj) {
        assert(obj != NULL && index <= MAX_OBJECT_NODES);
        object_clear_type(obj);
        obj->is_array = 1;
index f4ad5f2..4d65544 100644 (file)
@@ -1,3 +1,18 @@
+/*
+Copyright (C) 2005  Georgia Public Library Service 
+Bill Erickson <highfalutin@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+*/
+
 /* ---------------------------------------------------------------------------------------
        Generic object framework for C.  An object can be either a string, boolean, null, 
        number, array or hash (think Perl hash, dictionary, etc.).   
 #include <assert.h>
 #include "utils.h"
 
-/* does we need this? */
 #define MAX_OBJECT_NODES 1000000
 
 #ifndef OBJECT_H
 #define OBJECT_H
 
-/* top leve generic object structuure */
+/* top level generic object structuure */
 struct object_struct {
 
        /* how many sub-objects do we contain.  Note that this includes null
@@ -38,7 +52,7 @@ struct object_struct {
 
        /* attached accessor/mutator methods for the OO inclined*/
        unsigned long                           (*push)                         (struct object_struct* src, struct object_struct*);
-       unsigned long                           (*add_index)            (struct object_struct* src, unsigned long index, struct object_struct*);
+       unsigned long                           (*set_index)            (struct object_struct* src, unsigned long index, struct object_struct*);
        unsigned long                           (*add_key)                      (struct object_struct* src, char* key, struct object_struct*);
        struct object_struct*   (*get_index)            (struct object_struct*, unsigned long index);
        struct object_struct*   (*get_key)                      (struct object_struct*, char* key);
@@ -112,7 +126,8 @@ object_node* object_iterator_next(object_iterator*);
 int object_iterator_has_next(object_iterator*);
 
 
-/* allocates a new object. classname is optional */
+/* allocates a new object. 'string' is the string data if this object
+       is to be a string.  if not, string should be NULL */
 object* new_object(char* string);
 
 /* utility method for initing an object */
@@ -125,7 +140,8 @@ object* object_get_index( object* obj, unsigned long index );
 /* returns a pointer to the object with the given key */
 object* object_get_key( object* obj, char* key );
 
-/* de-allocates a object */
+/* de-allocates a object ( * should only be called on objects that are not
+       children of other objects ) */
 void free_object(object*);
 
 /* allocates a new object node */
@@ -134,17 +150,21 @@ object_node* new_object_node(object* obj);
 /* de-allocates a object node */
 void free_object_node(object_node*);
 
+
 /* pushes the given object onto the end of the list, 
  * returns the size on success, -1 on error 
+ * If obj is NULL, inserts a new object into the list with is_null set to true
  */
 unsigned long object_push(object*, object* obj);
 
-/* removes the object at the given index (if one exists) and inserts 
+/* removes (and deallocates) the object at the given index (if one exists) and inserts 
  * the new one.  returns the size on success, -1 on error 
+ * If obj is NULL, inserts a new object into the list with is_null set to true
  */
-unsigned long object_add_index(object*, unsigned long index, object* obj);
+unsigned long object_set_index(object*, unsigned long index, object* obj);
 
-/* inserts the new object, overwriting any previous object with the given key 
+/* inserts the new object, overwriting (removing, deallocating) any 
+ * previous object with the given key.
  * returns the size on success, -1 on error 
  * if 'obj' is NULL, a new object is inserted at key 'key' with 'is_null' 
  * set to true
@@ -156,11 +176,7 @@ unsigned long object_add_key(object*, char* key, object* obj);
  */
 unsigned long object_remove_index(object*, unsigned long index);
 
-/* de-allocates the object at index 'index' and sets the field to null.
- * this will *not* change the object size */
-//unsigned long object_clear_index(object*, unsigned long index);
-
-/* removes the object with key 'key' if it exists */
+/* removes (and deallocates) the object with key 'key' if it exists */
 unsigned long object_remove_key(object*, char* key);
 
 /* returns a pointer to the string data held by this object */
@@ -187,7 +203,7 @@ void object_clear_type(object*);
 /* set this object's comment string */
 void object_set_comment(object*, char*);
 
-/* starting at index 'index', shifts all indices down by one and 
+/* utility method.  starting at index 'index', shifts all indices down by one and 
  * decrements the objects size by 1 
  */
 void object_shift_index(object*, unsigned long index);
index 5bb181a..89502a0 100644 (file)
-#include <stdio.h>
-#include "utils.h"
-#include <fcntl.h>
+/*
+Copyright (C) 2005  Georgia Public Library Service 
+Bill Erickson <highfalutin@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+*/
+
+//#include "utils.h"
 #include "object.h"
 #include "json_parser.h"
 
-#include <wchar.h>
-#include <locale.h>
-
+#include <stdio.h>
+#include <fcntl.h>
 
 /* ---------------------------------------------------------------------- */
 /* See object.h for function info */
 /* ---------------------------------------------------------------------- */
 int main() {
 
+       /* sample JSON string with some encoded UTF8 */
        char* jsons = "/*--S mvr--*/[null,null,null,\"Griswold del Castillo, Richard\",[],null,\"1405676\",null,null,\"1558853243 (alk. paper) :\",\"c2002\",\"Pin\\u0303ata Books\",null,[],[[\"Chavez, Cesar 1927-\",\"Juvenile literature\"],[\"Labor leaders\",\"United States\",\"Biography\",\"Juvenile literature\"],[\"Mexican Americans\",\"Biography\",\"Juvenile literature\"],[\"Agricultural laborers\",\"Labor unions\",\"United States\",\"History\",\"Juvenile literature\"],[\"United Farm Workers\",\"History\",\"Juvenile literature\"],[\"Chavez, Cesar 1927-\"],[\"Labor leaders\"],[\"Mexican Americans\",\"Biography\"],[\"United Farm Workers.\"],[\"Spanish language materials\",\"Bilingual\"],[\"Chavez, Cesar 1927-\",\"Literatura juvenil\"],[\"Li\\u0301deres obreros\",\"Estados Unidos\",\"Biografi\\u0301a\",\"Literatura juvenil\"],[\"Mexicano-americanos\",\"Biografi\\u0301a\",\"Literatura juvenil\"],[\"Sindicatos\",\"Trabajadores agri\\u0301colas\",\"Estados Unidos\",\"Historia\",\"Literatura juvenil\"],[\"Unio\\u0301n de Trabajadores Agri\\u0301colas\",\"Historia\",\"Literatura juvenil\"]],\"ocm48083852 \",\"Ce\\u0301sar Cha\\u0301vez : the struggle for justice = Ce\\u0301sar Cha\\u0301vez : la lucha por la justicia\",[\"text\"], { \"hi\":\"you\"} ]/*--E mvr--*/";
 
 
-       //char* jsons = buffer_data(buffer);
        printf("\nOriginal JSON\n%s\n", jsons); 
 
+       /* parse the JSON string */
        object* yuk = json_parse_string(jsons); 
+
+       /* grab the class name from the object */
+       printf("\nParsed object with class %s\n", yuk->classname );
+
+       /* turn the resulting object back into JSON */
        char* ccc = yuk->to_json(yuk); 
        
+       /* extract a sub-object from the object and print its data*/
        object* o = yuk->get_index(yuk, 11);
        printf("\nRandom unicode string => %s\n", o->string_data);
 
+       /* parse the new JSON string to build yet another object */
        object* yuk2 = json_parse_string(ccc);
-       char* cccc = yuk2->to_json(yuk2);
 
+       /* turn that one back into JSON and print*/
+       char* cccc = yuk2->to_json(yuk2);
        printf("\nFinal JSON: \n%s\n", cccc);
 
+       char* string2 = strdup(jsons);
+
        int x = 0;
-       printf("\nParsing 10,000 round trips at %f...\n", get_timestamp_millis());
+       int count = 10000;
+       printf("\nParsing %d round trips at %f...\n", count, get_timestamp_millis());
 
-       char* string2 = strdup(jsons);
-       while(x++ < 10000) {
+       /* parse and stringify many times in a loop to check speed */
+       while(x++ < count) {
 
                object* o = json_parse_string(string2); 
                free(string2);
                string2 = o->to_json(o);
                free_object(o);
 
-               if(!(x%1000))
+               if(!(x % 500))
                        fprintf(stderr, "Round trip at %d\n", x);
        }
 
-       printf("\nAfter Loop: %f\n", get_timestamp_millis());
+       printf("After Loop: %f\n", get_timestamp_millis());
 
 
+       /* to_json() generates a string that must be freed by the caller */
        free(string2);
        free(ccc); 
        free(cccc); 
+
+       /* only free the top level objects.  objects that are 'children'
+               of other objects should not be freed */
        free_object(yuk); 
        free_object(yuk2); 
-       //buffer_free(buffer);
 
-       return 0;
 
+
+       /* ------------------------------------------------------------------------ */
+
+       /* parse a big JSON file */
+       FILE* F = fopen("test.json", "r");
+       if(!F) {
+               perror("unable to open test.json for testing");
+               exit(99);
+       }
+
+       char buf[10240];
+       char smallbuf[512];
+       bzero(buf, 10240);
+       bzero(smallbuf, 512);
+
+       while(fgets(smallbuf, 512, F)) 
+               strcat(buf, smallbuf);
+
+       /* dig our way into the JSON object we parsed, see test.json to get
+          an idea of the object structure */
+       object* big = json_parse_string(buf);
+       object* k = big->get_key(big,"web-app");
+       object* k2 = k->get_key(k,"servlet");
+       object* k3 = k2->get_index(k2, 0);
+       object* k4 = k3->get_key(k3,"servlet-class");
+
+       printf("\nValue for object with key 'servlet-class' in the JSON file => %s\n", k4->get_string(k4));
+
+       return 0;
 }