require'ffi_yajl/ffi'moduleFFI_YajlmoduleFFImoduleEncoderdefdo_yajl_encode(obj,yajl_gen_opts={})yajl_gen=FFI_Yajl.yajl_gen_alloc(nil);# configure the yajl encoderifyajl_gen_opts[:yajl_gen_beautify]FFI_Yajl.yajl_gen_config(yajl_gen,:yajl_gen_beautify,:int,1)endifyajl_gen_opts[:yajl_gen_validate_utf8]FFI_Yajl.yajl_gen_config(yajl_gen,:yajl_gen_validate_utf8,:int,1)endindent=yajl_gen_opts[:yajl_gen_indent_string]||" "FFI_Yajl.yajl_gen_config(yajl_gen,:yajl_gen_indent_string,:string,indent)# setup our own statestate={:json_opts=>opts,:processing_key=>false,}# do the encodingobj.ffi_yajl(yajl_gen,state)# get back our encoded JSONstring_ptr=::FFI::MemoryPointer.new(:string)length_ptr=::FFI::MemoryPointer.new(:int)if(status=FFI_Yajl.yajl_gen_get_buf(yajl_gen,string_ptr,length_ptr))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endlength=length_ptr.read_intstring=string_ptr.get_pointer(0).read_stringFFI_Yajl.yajl_gen_free(yajl_gen)returnstringendendendendclassHashdefffi_yajl(yajl_gen,state)if(status=FFI_Yajl.yajl_gen_map_open(yajl_gen))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endself.eachdo|key,value|# Perf Fix: mutate state hash rather than creating new copystate[:processing_key]=truekey.ffi_yajl(yajl_gen,state)state[:processing_key]=falsevalue.ffi_yajl(yajl_gen,state)endif(status=FFI_Yajl.yajl_gen_map_close(yajl_gen))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endendendclassArraydefffi_yajl(yajl_gen,state)if(status=FFI_Yajl.yajl_gen_array_open(yajl_gen))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endself.eachdo|value|value.ffi_yajl(yajl_gen,state)endif(status=FFI_Yajl.yajl_gen_array_close(yajl_gen))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endendendclassNilClassdefffi_yajl(yajl_gen,state)if(status=FFI_Yajl.yajl_gen_null(yajl_gen))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endendendclassTrueClassdefffi_yajl(yajl_gen,state)if(status=FFI_Yajl.yajl_gen_bool(yajl_gen,1))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endendendclassFalseClassdefffi_yajl(yajl_gen,state)if(status=FFI_Yajl.yajl_gen_bool(yajl_gen,0))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endendendclassFixnumdefffi_yajl(yajl_gen,state)str=self.to_sifstr=="NaN"||str=="Infinity"||str=="-Infinity"raise::FFI_Yajl::EncodeError.new("'#{str}' is an invalid number")endifstate[:processing_key]if(status=FFI_Yajl.yajl_gen_string(yajl_gen,str,str.bytesize))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endelseif(status=FFI_Yajl.yajl_gen_integer(yajl_gen,self))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endendendendclassBignumdefffi_yajl(yajl_gen,state)str=self.to_sifstr=="NaN"||str=="Infinity"||str=="-Infinity"raise::FFI_Yajl::EncodeError.new("'#{str}' is an invalid number")endifstate[:processing_key]if(status=FFI_Yajl.yajl_gen_string(yajl_gen,str,str.bytesize))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endelseif(status=FFI_Yajl.yajl_gen_number(yajl_gen,str,str.bytesize))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endendendendclassFloatdefffi_yajl(yajl_gen,state)str=self.to_sifstr=="NaN"||str=="Infinity"||str=="-Infinity"raise::FFI_Yajl::EncodeError.new("'#{str}' is an invalid number")endifstate[:processing_key]if(status=FFI_Yajl.yajl_gen_string(yajl_gen,str,str.bytesize))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endelseif(status=FFI_Yajl.yajl_gen_number(yajl_gen,str,str.bytesize))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endendendendclassSymboldefffi_yajl(yajl_gen,state)str=self.to_sif(status=FFI_Yajl.yajl_gen_string(yajl_gen,str,str.bytesize))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endendendclassStringdefffi_yajl(yajl_gen,state)if(status=FFI_Yajl.yajl_gen_string(yajl_gen,self,self.bytesize))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endendend# I feel dirtyclassObjectdefffi_yajl(yajl_gen,state)json=self.to_json(state[:json_opts])if(status=FFI_Yajl.yajl_gen_number(yajl_gen,json,json.bytesize))!=0FFI_Yajl::Encoder.raise_error_for_status(status)endendend