From e5dff8b4155c662d4cf2ee6055adad9f75e860d2 Mon Sep 17 00:00:00 2001 From: erickson Date: Fri, 1 Jul 2005 19:53:44 +0000 Subject: [PATCH] added license info and some additional comments git-svn-id: svn://svn.open-ils.org/ILS/trunk@1027 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- OpenSRF/src/objson/Makefile | 17 +++++++ OpenSRF/src/objson/json_parser.c | 20 +++++++- OpenSRF/src/objson/json_parser.h | 32 +++++++++--- OpenSRF/src/objson/object.c | 19 ++++++- OpenSRF/src/objson/object.h | 44 +++++++++++------ OpenSRF/src/objson/objson_test.c | 85 ++++++++++++++++++++++++++------ 6 files changed, 178 insertions(+), 39 deletions(-) diff --git a/OpenSRF/src/objson/Makefile b/OpenSRF/src/objson/Makefile index 2c657093dc..09e7fdf35f 100644 --- a/OpenSRF/src/objson/Makefile +++ b/OpenSRF/src/objson/Makefile @@ -1,3 +1,20 @@ +# -------------------------------------------------------------------- +# Copyright (C) 2005 Georgia Public Library Service +# Bill Erickson +# Mike Rylander + +# 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 diff --git a/OpenSRF/src/objson/json_parser.c b/OpenSRF/src/objson/json_parser.c index f6ebfe0617..b82e93ce07 100644 --- a/OpenSRF/src/objson/json_parser.c +++ b/OpenSRF/src/objson/json_parser.c @@ -1,3 +1,19 @@ +/* +Copyright (C) 2005 Georgia Public Library Service +Bill Erickson + +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; diff --git a/OpenSRF/src/objson/json_parser.h b/OpenSRF/src/objson/json_parser.h index 29d795d873..5fb7d6bfa2 100644 --- a/OpenSRF/src/objson/json_parser.h +++ b/OpenSRF/src/objson/json_parser.h @@ -1,8 +1,24 @@ +/* +Copyright (C) 2005 Georgia Public Library Service +Bill Erickson + +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 #include "object.h" #include "utils.h" @@ -11,11 +27,14 @@ #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); diff --git a/OpenSRF/src/objson/object.c b/OpenSRF/src/objson/object.c index c8d5222d59..59a77d843f 100644 --- a/OpenSRF/src/objson/object.c +++ b/OpenSRF/src/objson/object.c @@ -1,3 +1,18 @@ +/* +Copyright (C) 2005 Georgia Public Library Service +Bill Erickson + +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 @@ -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; diff --git a/OpenSRF/src/objson/object.h b/OpenSRF/src/objson/object.h index f4ad5f2f8f..4d65544470 100644 --- a/OpenSRF/src/objson/object.h +++ b/OpenSRF/src/objson/object.h @@ -1,3 +1,18 @@ +/* +Copyright (C) 2005 Georgia Public Library Service +Bill Erickson + +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.). @@ -11,13 +26,12 @@ #include #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); diff --git a/OpenSRF/src/objson/objson_test.c b/OpenSRF/src/objson/objson_test.c index 5bb181ac1a..89502a0706 100644 --- a/OpenSRF/src/objson/objson_test.c +++ b/OpenSRF/src/objson/objson_test.c @@ -1,62 +1,117 @@ -#include -#include "utils.h" -#include +/* +Copyright (C) 2005 Georgia Public Library Service +Bill Erickson + +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 -#include - +#include +#include /* ---------------------------------------------------------------------- */ /* 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; } -- 2.43.2