Skip to content
This repository
Fetching contributors…

Cannot retrieve contributors at this time

file 135 lines (118 sloc) 5.487 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
/*
* Copyright (c) 2008-2011 Brian Lopez - http://github.com/brianmario
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "api/yajl_parse.h"
#include "api/yajl_gen.h"

/* tell rbx not to use it's caching compat layer
by doing this we're making a promize to RBX that
we'll never modify the pointers we get back from RSTRING_PTR */
#define RSTRING_NOT_MODIFIED

#include <ruby.h>

#ifdef HAVE_RUBY_ENCODING_H
#include <ruby/encoding.h>
static rb_encoding *utf8Encoding;
#endif

#define READ_BUFSIZE 8192
#define WRITE_BUFSIZE 8192

/* Older versions of Ruby (< 1.8.6) need these */
#ifndef RSTRING_PTR
#define RSTRING_PTR(s) (RSTRING(s)->ptr)
#endif
#ifndef RSTRING_LEN
#define RSTRING_LEN(s) (RSTRING(s)->len)
#endif
#ifndef RARRAY_PTR
#define RARRAY_PTR(s) (RARRAY(s)->ptr)
#endif
#ifndef RARRAY_LEN
#define RARRAY_LEN(s) (RARRAY(s)->len)
#endif

static VALUE cParseError, cEncodeError, mYajl, cParser, cEncoder;
static ID intern_io_read, intern_call, intern_keys, intern_to_s,
            intern_to_json, intern_has_key, intern_to_sym, intern_as_json;
static ID sym_allow_comments, sym_check_utf8, sym_pretty, sym_indent, sym_terminator, sym_symbolize_keys, sym_symbolize_names, sym_html_safe;

#define GetParser(obj, sval) Data_Get_Struct(obj, yajl_parser_wrapper, sval);
#define GetEncoder(obj, sval) Data_Get_Struct(obj, yajl_encoder_wrapper, sval);

static void yajl_check_and_fire_callback(void * ctx);
static void yajl_set_static_value(void * ctx, VALUE val);
static void yajl_encode_part(void * wrapper, VALUE obj, VALUE io);
static void yajl_parse_chunk(const unsigned char * chunk, unsigned int len, yajl_handle parser);

static int yajl_found_null(void * ctx);
static int yajl_found_boolean(void * ctx, int boolean);
static int yajl_found_number(void * ctx, const char * numberVal, unsigned int numberLen);
static int yajl_found_string(void * ctx, const unsigned char * stringVal, unsigned int stringLen);
static int yajl_found_hash_key(void * ctx, const unsigned char * stringVal, unsigned int stringLen);
static int yajl_found_start_hash(void * ctx);
static int yajl_found_end_hash(void * ctx);
static int yajl_found_start_array(void * ctx);
static int yajl_found_end_array(void * ctx);

static yajl_callbacks callbacks = {
    yajl_found_null,
    yajl_found_boolean,
    NULL,
    NULL,
    yajl_found_number,
    yajl_found_string,
    yajl_found_start_hash,
    yajl_found_hash_key,
    yajl_found_end_hash,
    yajl_found_start_array,
    yajl_found_end_array
};

typedef struct {
    VALUE builderStack;
    VALUE parse_complete_callback;
    int nestedArrayLevel;
    int nestedHashLevel;
    int objectsFound;
    int symbolizeKeys;
    yajl_handle parser;
} yajl_parser_wrapper;

typedef struct {
    VALUE on_progress_callback;
    VALUE terminator;
    yajl_gen encoder;
    unsigned char *indentString;
} yajl_encoder_wrapper;

static VALUE rb_yajl_parser_new(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_parser_init(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_parser_parse(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_parser_parse_chunk(VALUE self, VALUE chunk);
static VALUE rb_yajl_parser_set_complete_cb(VALUE self, VALUE callback);
static void yajl_parser_wrapper_free(void * wrapper);
static void yajl_parser_wrapper_mark(void * wrapper);

static VALUE rb_yajl_encoder_new(int argc, VALUE * argv, VALUE klass);
static VALUE rb_yajl_encoder_init(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_encoder_encode(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_encoder_set_progress_cb(VALUE self, VALUE callback);
static void yajl_encoder_wrapper_free(void * wrapper);
static void yajl_encoder_wrapper_mark(void * wrapper);

static VALUE rb_yajl_json_ext_hash_to_json(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_json_ext_array_to_json(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_json_ext_fixnum_to_json(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_json_ext_float_to_json(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_json_ext_string_to_json(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_json_ext_true_to_json(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_json_ext_false_to_json(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_json_ext_nil_to_json(int argc, VALUE * argv, VALUE self);
static VALUE rb_yajl_encoder_enable_json_gem_ext(VALUE klass);

void Init_yajl();
Something went wrong with that request. Please try again.