yajl - JSON library working with the compiler. URL: http://lloyd.github.com/yajl/

Dependencies:   mbed

Committer:
rolf
Date:
Wed Nov 18 17:56:51 2009 +0000
Revision:
0:34f4a53d4ca3

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rolf 0:34f4a53d4ca3 1 /*
rolf 0:34f4a53d4ca3 2 * Copyright 2007-2009, Lloyd Hilaiel.
rolf 0:34f4a53d4ca3 3 *
rolf 0:34f4a53d4ca3 4 * Redistribution and use in source and binary forms, with or without
rolf 0:34f4a53d4ca3 5 * modification, are permitted provided that the following conditions are
rolf 0:34f4a53d4ca3 6 * met:
rolf 0:34f4a53d4ca3 7 *
rolf 0:34f4a53d4ca3 8 * 1. Redistributions of source code must retain the above copyright
rolf 0:34f4a53d4ca3 9 * notice, this list of conditions and the following disclaimer.
rolf 0:34f4a53d4ca3 10 *
rolf 0:34f4a53d4ca3 11 * 2. Redistributions in binary form must reproduce the above copyright
rolf 0:34f4a53d4ca3 12 * notice, this list of conditions and the following disclaimer in
rolf 0:34f4a53d4ca3 13 * the documentation and/or other materials provided with the
rolf 0:34f4a53d4ca3 14 * distribution.
rolf 0:34f4a53d4ca3 15 *
rolf 0:34f4a53d4ca3 16 * 3. Neither the name of Lloyd Hilaiel nor the names of its
rolf 0:34f4a53d4ca3 17 * contributors may be used to endorse or promote products derived
rolf 0:34f4a53d4ca3 18 * from this software without specific prior written permission.
rolf 0:34f4a53d4ca3 19 *
rolf 0:34f4a53d4ca3 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
rolf 0:34f4a53d4ca3 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
rolf 0:34f4a53d4ca3 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
rolf 0:34f4a53d4ca3 23 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
rolf 0:34f4a53d4ca3 24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
rolf 0:34f4a53d4ca3 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
rolf 0:34f4a53d4ca3 26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
rolf 0:34f4a53d4ca3 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
rolf 0:34f4a53d4ca3 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
rolf 0:34f4a53d4ca3 29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
rolf 0:34f4a53d4ca3 30 * POSSIBILITY OF SUCH DAMAGE.
rolf 0:34f4a53d4ca3 31 */
rolf 0:34f4a53d4ca3 32
rolf 0:34f4a53d4ca3 33 #ifdef __cplusplus
rolf 0:34f4a53d4ca3 34 extern "C" {
rolf 0:34f4a53d4ca3 35 #endif
rolf 0:34f4a53d4ca3 36
rolf 0:34f4a53d4ca3 37 #include "yajl/yajl_parse.h"
rolf 0:34f4a53d4ca3 38 #include "yajl_lex.h"
rolf 0:34f4a53d4ca3 39 #include "yajl_parser.h"
rolf 0:34f4a53d4ca3 40 #include "yajl_alloc.h"
rolf 0:34f4a53d4ca3 41
rolf 0:34f4a53d4ca3 42 #include <stdlib.h>
rolf 0:34f4a53d4ca3 43 #include <string.h>
rolf 0:34f4a53d4ca3 44 #include <assert.h>
rolf 0:34f4a53d4ca3 45
rolf 0:34f4a53d4ca3 46 const char *
rolf 0:34f4a53d4ca3 47 yajl_status_to_string(yajl_status stat)
rolf 0:34f4a53d4ca3 48 {
rolf 0:34f4a53d4ca3 49 const char * statStr = "unknown";
rolf 0:34f4a53d4ca3 50 switch (stat) {
rolf 0:34f4a53d4ca3 51 case yajl_status_ok:
rolf 0:34f4a53d4ca3 52 statStr = "ok, no error";
rolf 0:34f4a53d4ca3 53 break;
rolf 0:34f4a53d4ca3 54 case yajl_status_client_canceled:
rolf 0:34f4a53d4ca3 55 statStr = "client canceled parse";
rolf 0:34f4a53d4ca3 56 break;
rolf 0:34f4a53d4ca3 57 case yajl_status_insufficient_data:
rolf 0:34f4a53d4ca3 58 statStr = "eof was met before the parse could complete";
rolf 0:34f4a53d4ca3 59 break;
rolf 0:34f4a53d4ca3 60 case yajl_status_error:
rolf 0:34f4a53d4ca3 61 statStr = "parse error";
rolf 0:34f4a53d4ca3 62 break;
rolf 0:34f4a53d4ca3 63 }
rolf 0:34f4a53d4ca3 64 return statStr;
rolf 0:34f4a53d4ca3 65 }
rolf 0:34f4a53d4ca3 66
rolf 0:34f4a53d4ca3 67 yajl_handle
rolf 0:34f4a53d4ca3 68 yajl_alloc(const yajl_callbacks * callbacks,
rolf 0:34f4a53d4ca3 69 const yajl_parser_config * config,
rolf 0:34f4a53d4ca3 70 const yajl_alloc_funcs * afs,
rolf 0:34f4a53d4ca3 71 void * ctx)
rolf 0:34f4a53d4ca3 72 {
rolf 0:34f4a53d4ca3 73 unsigned int allowComments = 0;
rolf 0:34f4a53d4ca3 74 unsigned int validateUTF8 = 0;
rolf 0:34f4a53d4ca3 75 yajl_handle hand = NULL;
rolf 0:34f4a53d4ca3 76 yajl_alloc_funcs afsBuffer;
rolf 0:34f4a53d4ca3 77
rolf 0:34f4a53d4ca3 78 /* first order of business is to set up memory allocation routines */
rolf 0:34f4a53d4ca3 79 if (afs != NULL) {
rolf 0:34f4a53d4ca3 80 if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL)
rolf 0:34f4a53d4ca3 81 {
rolf 0:34f4a53d4ca3 82 return NULL;
rolf 0:34f4a53d4ca3 83 }
rolf 0:34f4a53d4ca3 84 } else {
rolf 0:34f4a53d4ca3 85 yajl_set_default_alloc_funcs(&afsBuffer);
rolf 0:34f4a53d4ca3 86 afs = &afsBuffer;
rolf 0:34f4a53d4ca3 87 }
rolf 0:34f4a53d4ca3 88
rolf 0:34f4a53d4ca3 89 hand = (yajl_handle) YA_MALLOC(afs, sizeof(struct yajl_handle_t));
rolf 0:34f4a53d4ca3 90
rolf 0:34f4a53d4ca3 91 /* copy in pointers to allocation routines */
rolf 0:34f4a53d4ca3 92 memcpy((void *) &(hand->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
rolf 0:34f4a53d4ca3 93
rolf 0:34f4a53d4ca3 94 if (config != NULL) {
rolf 0:34f4a53d4ca3 95 allowComments = config->allowComments;
rolf 0:34f4a53d4ca3 96 validateUTF8 = config->checkUTF8;
rolf 0:34f4a53d4ca3 97 }
rolf 0:34f4a53d4ca3 98
rolf 0:34f4a53d4ca3 99 hand->callbacks = callbacks;
rolf 0:34f4a53d4ca3 100 hand->ctx = ctx;
rolf 0:34f4a53d4ca3 101 hand->lexer = yajl_lex_alloc(&(hand->alloc), allowComments, validateUTF8);
rolf 0:34f4a53d4ca3 102 hand->errorOffset = 0;
rolf 0:34f4a53d4ca3 103 hand->decodeBuf = yajl_buf_alloc(&(hand->alloc));
rolf 0:34f4a53d4ca3 104 hand->stateBuf = yajl_buf_alloc(&(hand->alloc));
rolf 0:34f4a53d4ca3 105
rolf 0:34f4a53d4ca3 106 yajl_state_push(hand, yajl_state_start);
rolf 0:34f4a53d4ca3 107
rolf 0:34f4a53d4ca3 108 return hand;
rolf 0:34f4a53d4ca3 109 }
rolf 0:34f4a53d4ca3 110
rolf 0:34f4a53d4ca3 111 void
rolf 0:34f4a53d4ca3 112 yajl_free(yajl_handle handle)
rolf 0:34f4a53d4ca3 113 {
rolf 0:34f4a53d4ca3 114 yajl_buf_free(handle->stateBuf);
rolf 0:34f4a53d4ca3 115 yajl_buf_free(handle->decodeBuf);
rolf 0:34f4a53d4ca3 116 yajl_lex_free(handle->lexer);
rolf 0:34f4a53d4ca3 117 YA_FREE(&(handle->alloc), handle);
rolf 0:34f4a53d4ca3 118 }
rolf 0:34f4a53d4ca3 119
rolf 0:34f4a53d4ca3 120 yajl_status
rolf 0:34f4a53d4ca3 121 yajl_parse(yajl_handle hand, const unsigned char * jsonText,
rolf 0:34f4a53d4ca3 122 unsigned int jsonTextLen)
rolf 0:34f4a53d4ca3 123 {
rolf 0:34f4a53d4ca3 124 unsigned int offset = 0;
rolf 0:34f4a53d4ca3 125 yajl_status status;
rolf 0:34f4a53d4ca3 126 status = yajl_do_parse(hand, &offset, jsonText, jsonTextLen);
rolf 0:34f4a53d4ca3 127 return status;
rolf 0:34f4a53d4ca3 128 }
rolf 0:34f4a53d4ca3 129
rolf 0:34f4a53d4ca3 130 yajl_status
rolf 0:34f4a53d4ca3 131 yajl_parse_complete(yajl_handle hand)
rolf 0:34f4a53d4ca3 132 {
rolf 0:34f4a53d4ca3 133 /* The particular case we want to handle is a trailing number.
rolf 0:34f4a53d4ca3 134 * Further input consisting of digits could cause our interpretation
rolf 0:34f4a53d4ca3 135 * of the number to change (buffered "1" but "2" comes in).
rolf 0:34f4a53d4ca3 136 * A very simple approach to this is to inject whitespace to terminate
rolf 0:34f4a53d4ca3 137 * any number in the lex buffer.
rolf 0:34f4a53d4ca3 138 */
rolf 0:34f4a53d4ca3 139 return yajl_parse(hand, (const unsigned char *)" ", 1);
rolf 0:34f4a53d4ca3 140 }
rolf 0:34f4a53d4ca3 141
rolf 0:34f4a53d4ca3 142 unsigned char *
rolf 0:34f4a53d4ca3 143 yajl_get_error(yajl_handle hand, int verbose,
rolf 0:34f4a53d4ca3 144 const unsigned char * jsonText, unsigned int jsonTextLen)
rolf 0:34f4a53d4ca3 145 {
rolf 0:34f4a53d4ca3 146 return yajl_render_error_string(hand, jsonText, jsonTextLen, verbose);
rolf 0:34f4a53d4ca3 147 }
rolf 0:34f4a53d4ca3 148
rolf 0:34f4a53d4ca3 149 void
rolf 0:34f4a53d4ca3 150 yajl_free_error(yajl_handle hand, unsigned char * str)
rolf 0:34f4a53d4ca3 151 {
rolf 0:34f4a53d4ca3 152 /* use memory allocation functions if set */
rolf 0:34f4a53d4ca3 153 YA_FREE(&(hand->alloc), str);
rolf 0:34f4a53d4ca3 154 }
rolf 0:34f4a53d4ca3 155
rolf 0:34f4a53d4ca3 156 /* XXX: add utility routines to parse from file */
rolf 0:34f4a53d4ca3 157 #ifdef __cplusplus
rolf 0:34f4a53d4ca3 158 }
rolf 0:34f4a53d4ca3 159 #endif