json_writer::json_writer(boost::shared_ptr<output_buffer> &out, bool indent) : pimpl(new pimpl_()) { #ifdef HAVE_YAJL2 pimpl->gen = yajl_gen_alloc(NULL); #else /* older version of YAJL */ // setup whether the generator should produce pretty output if (indent) { pimpl->config.beautify = 1; pimpl->config.indentString = " "; } else { pimpl->config.beautify = 0; pimpl->config.indentString = ""; } pimpl->gen = yajl_gen_alloc2(&wrap_write, &pimpl->config, NULL, out.get()); #endif /* HAVE_YAJL2 */ if (pimpl->gen == 0) { throw std::runtime_error("error creating json writer."); } #ifdef HAVE_YAJL2 if (indent) { yajl_gen_config(pimpl->gen, yajl_gen_beautify, 1); yajl_gen_config(pimpl->gen, yajl_gen_indent_string, " "); } else { yajl_gen_config(pimpl->gen, yajl_gen_beautify, 0); yajl_gen_config(pimpl->gen, yajl_gen_indent_string, ""); } yajl_gen_config(pimpl->gen, yajl_gen_print_callback, &wrap_write, (void *)out.get()); #endif /* HAVE_YAJL2 */ }
void orderly_write_json(const orderly_alloc_funcs * alloc, const orderly_json * json, orderly_buf b, int pretty) { yajl_gen_config cfg = { pretty, NULL }; yajl_gen g = yajl_gen_alloc2(bufAppendCallback, &cfg, (const yajl_alloc_funcs *) alloc, (void *) b); int rv = orderly_write_json2(g, json); yajl_gen_free(g); }
PyObject *_internal_encode(_YajlEncoder *self, PyObject *obj) { yajl_gen generator = NULL; yajl_gen_config genconfig = { 0, NULL}; yajl_gen_status status; struct StringAndUsedCount sauc; /* initialize context for our printer function which * performs low level string appending, using the python * string implementation as a chunked growth buffer */ sauc.used = 0; sauc.str = lowLevelStringAlloc(PY_YAJL_CHUNK_SZ); generator = yajl_gen_alloc2(py_yajl_printer, &genconfig, NULL, (void *) &sauc); self->_generator = generator; status = ProcessObject(self, obj); yajl_gen_free(generator); self->_generator = NULL; /* if resize failed inside our printer function we'll have a null sauc.str */ if (!sauc.str) { PyErr_SetObject(PyExc_ValueError, PyString_FromString("Allocation failure")); return NULL; } if (status != yajl_gen_status_ok) { PyErr_SetObject(PyExc_ValueError, PyString_FromString("Failed to process")); Py_XDECREF(sauc.str); return NULL; } /* truncate to used size, and resize will handle the null plugging */ _PyString_Resize(&sauc.str, sauc.used); return sauc.str; }
yajl_gen yajl_gen_alloc(const yajl_gen_config * config, const yajl_alloc_funcs * afs) { return yajl_gen_alloc2(NULL, config, afs, NULL); }
static VALUE memprof_dump(int argc, VALUE *argv, VALUE self) { VALUE str; FILE *out = NULL; if (!track_objs) rb_raise(rb_eRuntimeError, "object tracking disabled, call Memprof.start first"); rb_scan_args(argc, argv, "01", &str); if (RTEST(str)) { out = fopen(StringValueCStr(str), "w"); if (!out) rb_raise(rb_eArgError, "unable to open output file"); } yajl_gen_config conf = { .beautify = 1, .indentString = " " }; yajl_gen gen = yajl_gen_alloc2((yajl_print_t)&json_print, &conf, NULL, (void*)out); track_objs = 0; yajl_gen_array_open(gen); st_foreach(objs, objs_each_dump, (st_data_t)gen); yajl_gen_array_close(gen); yajl_gen_free(gen); if (out) fclose(out); track_objs = 1; return Qnil; } static VALUE memprof_dump_all(int argc, VALUE *argv, VALUE self) { char *heaps = *(char**)bin_find_symbol("heaps",0); int heaps_used = *(int*)bin_find_symbol("heaps_used",0); #ifndef sizeof__RVALUE size_t sizeof__RVALUE = bin_type_size("RVALUE"); #endif #ifndef sizeof__heaps_slot size_t sizeof__heaps_slot = bin_type_size("heaps_slot"); #endif #ifndef offset__heaps_slot__limit int offset__heaps_slot__limit = bin_type_member_offset("heaps_slot", "limit"); #endif #ifndef offset__heaps_slot__slot int offset__heaps_slot__slot = bin_type_member_offset("heaps_slot", "slot"); #endif char *p, *pend; int i, limit; if (sizeof__RVALUE == 0 || sizeof__heaps_slot == 0) rb_raise(eUnsupported, "could not find internal heap"); VALUE str; FILE *out = NULL; rb_scan_args(argc, argv, "01", &str); if (RTEST(str)) { out = fopen(StringValueCStr(str), "w"); if (!out) rb_raise(rb_eArgError, "unable to open output file"); } yajl_gen_config conf = { .beautify = 0, .indentString = " " }; yajl_gen gen = yajl_gen_alloc2((yajl_print_t)&json_print, &conf, NULL, (void*)out); track_objs = 0; //yajl_gen_array_open(gen); for (i=0; i < heaps_used; i++) { p = *(char**)(heaps + (i * sizeof__heaps_slot) + offset__heaps_slot__slot); limit = *(int*)(heaps + (i * sizeof__heaps_slot) + offset__heaps_slot__limit); pend = p + (sizeof__RVALUE * limit); while (p < pend) { if (RBASIC(p)->flags) { obj_dump((VALUE)p, gen); // XXX ugh yajl_gen_clear(gen); yajl_gen_free(gen); gen = yajl_gen_alloc2((yajl_print_t)&json_print, &conf, NULL, (void*)out); while(fputc('\n', out ? out : stdout) == EOF); } p += sizeof__RVALUE; } } //yajl_gen_array_close(gen); yajl_gen_clear(gen); yajl_gen_free(gen); if (out) fclose(out); track_objs = 1; return Qnil; } void Init_memprof() { VALUE memprof = rb_define_module("Memprof"); eUnsupported = rb_define_class_under(memprof, "Unsupported", rb_eStandardError); rb_define_singleton_method(memprof, "start", memprof_start, 0); rb_define_singleton_method(memprof, "stop", memprof_stop, 0); rb_define_singleton_method(memprof, "stats", memprof_stats, -1); rb_define_singleton_method(memprof, "stats!", memprof_stats_bang, -1); rb_define_singleton_method(memprof, "track", memprof_track, -1); rb_define_singleton_method(memprof, "dump", memprof_dump, -1); rb_define_singleton_method(memprof, "dump_all", memprof_dump_all, -1); pagesize = getpagesize(); objs = st_init_numtable(); bin_init(); create_tramp_table(); gc_hook = Data_Wrap_Struct(rb_cObject, sourcefile_marker, NULL, NULL); rb_global_variable(&gc_hook); ptr_to_rb_mark_table_add_filename = bin_find_symbol("rb_mark_table_add_filename", NULL); rb_classname = bin_find_symbol("classname", 0); rb_add_freelist = bin_find_symbol("add_freelist", 0); insert_tramp("rb_newobj", newobj_tramp); insert_tramp("add_freelist", freelist_tramp); if (getenv("MEMPROF")) track_objs = 1; return; }