static VALUE hash_equal(VALUE hash1, VALUE hash2, bool eql) { if (hash1 == hash2) { return Qtrue; } if (TYPE(hash2) != T_HASH) { if (!rb_respond_to(hash2, rb_intern("to_hash"))) { return Qfalse; } if (eql) { return rb_eql(hash2, hash1); } else { return rb_equal(hash2, hash1); } } if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2)) { return Qfalse; } if (IS_RHASH(hash2)) { struct equal_data data; data.tbl = RHASH(hash2)->tbl; data.eql = eql; return rb_exec_recursive(recursive_eql, hash1, (VALUE)&data); } else { return CFEqual((CFTypeRef)hash1, (CFTypeRef)hash2) ? Qtrue : Qfalse; } }
/* * call-seq: to_json(state = nil, depth = 0) * * Returns a JSON string containing a JSON object, that is unparsed from * this Hash instance. * _state_ is a JSON::State object, that can also be used to configure the * produced JSON string output further. * _depth_ is used to find out nesting depth, to indent accordingly. */ static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self) { VALUE Vstate, Vdepth, result; long depth; rb_scan_args(argc, argv, "02", &Vstate, &Vdepth); depth = NIL_P(Vdepth) ? 0 : FIX2LONG(Vdepth); if (NIL_P(Vstate)) { long len = RHASH_SIZE(self); result = rb_str_buf_new(len); rb_str_buf_cat2(result, "{"); rb_hash_foreach(self, hash_to_json_i, result); rb_str_buf_cat2(result, "}"); } else { GET_STATE(Vstate); check_max_nesting(state, depth); if (state->check_circular) { VALUE self_id = rb_obj_id(self); if (RTEST(rb_hash_aref(state->seen, self_id))) { rb_raise(eCircularDatastructure, "circular data structures not supported!"); } rb_hash_aset(state->seen, self_id, Qtrue); result = mHash_json_transfrom(self, Vstate, LONG2FIX(depth)); rb_hash_delete(state->seen, self_id); } else { result = mHash_json_transfrom(self, Vstate, LONG2FIX(depth)); } } OBJ_INFECT(result, self); FORCE_UTF8(result); return result; }
void mochilo_pack_hash(mochilo_buf *buf, VALUE rb_hash) { struct mochilo_hash_pack hash_pack; long size = RHASH_SIZE(rb_hash); hash_pack.buf = buf; if (size < 0x10) { uint8_t lead = 0x80 | size; mochilo_buf_putc(buf, lead); } else if (size < 0x10000) { uint16_t lead = size; mochilo_buf_putc(buf, MSGPACK_T_MAP16); mochilo_buf_put16be(buf, &lead); } else { mochilo_buf_putc(buf, MSGPACK_T_MAP32); mochilo_buf_put32be(buf, &size); } rb_hash_foreach(rb_hash, &hash_callback, (VALUE)&hash_pack); }
SEXP R_rb_hash_size(SEXP r_obj) { VALUE obj; obj = getRubyObjectFromR(r_obj); return(ScalarInteger(RHASH_SIZE(obj))); }
static void cb_params_store_parse_arguments(struct params_st *params, int argc, VALUE argv) { VALUE keys; if (argc < 1) { rb_raise(rb_eArgError, "the key and value must be specified"); } switch (argc) { case 1: keys = RARRAY_PTR(argv)[0]; switch(TYPE(keys)) { case T_HASH: /* key-value pairs */ cb_params_store_alloc(params, RHASH_SIZE(keys)); rb_hash_foreach(keys, cb_params_store_extract_keys_i, (VALUE)params); break; default: rb_raise(rb_eArgError, "there must be either Hash with key-value pairs" " or two separate arguments: key and value"); } break; case 2: /* just key and value */ cb_params_store_alloc(params, 1); cb_params_store_init_item(params, 0, RARRAY_PTR(argv)[0], RARRAY_PTR(argv)[1], params->cmd.store.flags, params->cmd.store.cas, params->cmd.store.ttl); break; default: rb_raise(rb_eArgError, "too many arguments"); } }
/* Boolean - does the node have features? */ static VALUE birch_has_features(VALUE self) { VALUE features; features = rb_iv_get(self, "@features"); if (RHASH_SIZE(features) == 0) { return Qfalse; } else { return Qtrue; } }
/* * Document-method: Hash#to_msgpack * * call-seq: * hash.to_msgpack(out = '') -> String * * Serializes the Hash into raw bytes. * This calls to_msgpack method reflectively for internal keys and values. */ static VALUE MessagePack_Hash_to_msgpack(int argc, VALUE *argv, VALUE self) { ARG_BUFFER(out, argc, argv); msgpack_pack_map(out, RHASH_SIZE(self)); rb_hash_foreach(self, MessagePack_Hash_to_msgpack_foreach, out); return out; }
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values) { int i = 0, j; int rest = 0; VALUE missing = Qnil; st_data_t key; #define extract_kwarg(keyword, val) \ (key = (st_data_t)(keyword), values ? \ st_delete(rb_hash_tbl_raw(keyword_hash), &key, (val)) : \ st_lookup(rb_hash_tbl_raw(keyword_hash), key, (val))) if (NIL_P(keyword_hash)) keyword_hash = 0; if (optional < 0) { rest = 1; optional = -1-optional; } if (values) { for (j = 0; j < required + optional; j++) { values[j] = Qundef; } } if (required) { for (; i < required; i++) { VALUE keyword = ID2SYM(table[i]); if (keyword_hash) { st_data_t val; if (extract_kwarg(keyword, &val)) { if (values) values[i] = (VALUE)val; continue; } } if (NIL_P(missing)) missing = rb_ary_tmp_new(1); rb_ary_push(missing, keyword); } if (!NIL_P(missing)) { keyword_error("missing", missing); } } j = i; if (optional && keyword_hash) { for (i = 0; i < optional; i++) { st_data_t val; if (extract_kwarg(ID2SYM(table[required+i]), &val)) { if (values) values[required+i] = (VALUE)val; j++; } } } if (!rest && keyword_hash) { if (RHASH_SIZE(keyword_hash) > (unsigned int)j) { unknown_keyword_error(keyword_hash, table, required+optional); } } return j; #undef extract_kwarg }
/* * Document-method: Hash#to_msgpack * * call-seq: * hash.to_msgpack(out = '') -> String * * Serializes the Hash into raw bytes. * This calls to_msgpack method reflectively for internal keys and values. */ static VALUE MessagePack_Hash_to_msgpack(int argc, VALUE *argv, VALUE self) { ARG_BUFFER(out, argc, argv); // FIXME check sizeof(st_index_t) > sizeof(unsigned int) && RARRAY_LEN(self) > UINT_MAX msgpack_pack_map(out, (unsigned int)RHASH_SIZE(self)); rb_hash_foreach(self, MessagePack_Hash_to_msgpack_foreach, out); return out; }
static mrb_value hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql) { if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value(); if (mrb_type(hash2) != MRB_TT_HASH) { if (!mrb_respond_to(mrb, hash2, mrb_intern(mrb, "to_hash"))) { return mrb_false_value(); } if (eql) return mrb_fixnum_value(mrb_eql(mrb, hash2, hash1)); else return mrb_fixnum_value(mrb_equal(mrb, hash2, hash1)); } if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2)) return mrb_false_value(); if (!RHASH(hash1)->ht || !RHASH(hash2)->ht) return mrb_true_value(); return mrb_exec_recursive_paired(mrb, recursive_eql, hash1, hash2, (void*)0); }
static void pack_hash_event(rbkit_hash_event *event, msgpack_packer *packer) { VALUE hash; int size; msgpack_pack_map(packer, 3); pack_event_header(packer, event->event_header.event_type); hash = event->hash; size = (int)RHASH_SIZE(hash); msgpack_pack_int(packer, rbkit_message_field_payload); msgpack_pack_map(packer, size); rb_hash_foreach(hash, hash_pack_iterator, (VALUE)packer); }
static VALUE ov_http_client_send(VALUE self, VALUE request) { ov_http_client_object* ptr; /* Get the pointer to the native object and check that it isn't closed: */ ov_http_client_ptr(self, ptr); ov_http_client_check_closed(ptr); /* If the limit hasn't been reached then submit the request directly to libcurl, otherwise put it in the queue: */ if (RHASH_SIZE(ptr->pending) < ptr->limit) { ov_http_client_submit(self, request); } else { rb_ary_push(ptr->queue, request); } return Qnil; }
static VALUE ov_http_client_build_url( VALUE url, VALUE query) { /* Copy the URL: */ if (NIL_P(url)) { rb_raise(ov_error_class, "The 'url' parameter can't be nil"); } Check_Type(url, T_STRING); /* Append the query: */ if (!NIL_P(query)) { Check_Type(query, T_HASH); if (RHASH_SIZE(query) > 0) { url = rb_sprintf("%"PRIsVALUE"?%"PRIsVALUE"", url, rb_funcall(URI_CLASS, ENCODE_WWW_FORM_ID, 1, query)); } } return url; }
static void cb_params_get_parse_arguments(struct params_st *params, int argc, VALUE argv) { lcb_size_t ii; if (argc < 1) { rb_raise(rb_eArgError, "must be at least one key"); } if (argc == 1) { VALUE keys = RARRAY_PTR(argv)[0]; switch(TYPE(keys)) { case T_ARRAY: /* array of keys as a first argument */ params->cmd.get.array = 1; cb_params_get_alloc(params, RARRAY_LEN(keys)); for (ii = 0; ii < params->cmd.get.num; ++ii) { rb_ary_push(params->cmd.get.keys_ary, RARRAY_PTR(keys)[ii]); cb_params_get_init_item(params, ii, RARRAY_PTR(keys)[ii], params->cmd.get.ttl); } break; case T_HASH: /* key-ttl pairs */ if (params->cmd.get.replica) { rb_raise(rb_eArgError, "must be either list of key or single key"); } params->cmd.get.gat = 1; cb_params_get_alloc(params, RHASH_SIZE(keys)); rb_hash_foreach(keys, cb_params_get_extract_keys_i, (VALUE)params); break; default: /* single key */ cb_params_get_alloc(params, 1); rb_ary_push(params->cmd.get.keys_ary, keys); cb_params_get_init_item(params, 0, keys, params->cmd.get.ttl); } } else { /* just list of arguments */ cb_params_get_alloc(params, argc); for (ii = 0; ii < params->cmd.get.num; ++ii) { rb_ary_push(params->cmd.get.keys_ary, RARRAY_PTR(argv)[ii]); cb_params_get_init_item(params, ii, RARRAY_PTR(argv)[ii], params->cmd.get.ttl); } } }
static VALUE ov_http_client_wait(VALUE self, VALUE request) { VALUE next; VALUE result; ov_http_client_object* ptr; ov_http_client_wait_context context; /* Get the pointer to the native object and check that it isn't closed: */ ov_http_client_ptr(self, ptr); ov_http_client_check_closed(ptr); /* Work till the transfer has been completed. */ context.handle = ptr->handle; context.code = CURLE_OK; context.cancel = false; for (;;) { /* Move requests from the queue to libcurl: */ while (RARRAY_LEN(ptr->queue) > 0 && RHASH_SIZE(ptr->pending) < ptr->limit) { next = rb_ary_shift(ptr->queue); ov_http_client_submit(self, next); } /* Check if the response is already available, if so then return it: */ result = rb_hash_delete(ptr->completed, request); if (!NIL_P(result)) { return result; } /* If the response isn't available yet, then do some real work: */ rb_thread_call_without_gvl( ov_http_client_wait_task, &context, ov_http_client_wait_cancel, &context ); if (context.cancel) { return Qnil; } if (context.code != CURLE_OK) { rb_raise(ov_error_class, "Unexpected error while waiting: %s", curl_easy_strerror(context.code)); } } return Qnil; }
static void cb_params_unlock_parse_arguments(struct params_st *params, int argc, VALUE argv) { if (argc == 1) { VALUE keys = RARRAY_PTR(argv)[0]; switch(TYPE(keys)) { case T_HASH: /* key-cas pairs */ cb_params_unlock_alloc(params, RHASH_SIZE(keys)); rb_hash_foreach(keys, cb_params_unlock_extract_keys_i, (VALUE)params); break; default: /* single key */ cb_params_unlock_alloc(params, 1); cb_params_unlock_init_item(params, 0, keys, params->cmd.unlock.cas); } } else { rb_raise(rb_eArgError, "must be either Hash or single key with cas option"); } }
inline static VALUE mHash_json_transfrom(VALUE self, VALUE Vstate, VALUE Vdepth) { long depth, len = RHASH_SIZE(self); VALUE result; GET_STATE(Vstate); depth = 1 + FIX2LONG(Vdepth); result = rb_str_buf_new(len); state->memo = result; state->depth = LONG2FIX(depth); state->flag = 0; rb_str_buf_cat2(result, "{"); if (RSTRING_LEN(state->object_nl)) rb_str_buf_append(result, state->object_nl); rb_hash_foreach(self, hash_to_json_state_i, Vstate); if (RSTRING_LEN(state->object_nl)) rb_str_buf_append(result, state->object_nl); if (RSTRING_LEN(state->object_nl)) { rb_str_buf_append(result, rb_str_times(state->indent, Vdepth)); } rb_str_buf_cat2(result, "}"); return result; }
void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v) { /* actual return type of RHASH_SIZE is long (if SIZEOF_LONG == SIZEOF_VOIDP * or long long (if SIZEOF_LONG_LONG == SIZEOF_VOIDP. See st.h. */ unsigned long len = RHASH_SIZE(v); if(len > 0xffffffffUL) { rb_raise(rb_eArgError, "size of array is too long to pack: %ld bytes should be <= %lu", len, 0xffffffffUL); } unsigned int len32 = (unsigned int)len; msgpack_packer_write_map_header(pk, len32); #ifdef RUBINIUS VALUE iter = rb_funcall(v, s_to_iter, 0); VALUE entry = Qnil; while(RTEST(entry = rb_funcall(iter, s_next, 1, entry))) { VALUE key = rb_funcall(entry, s_key, 0); VALUE val = rb_funcall(entry, s_value, 0); write_hash_foreach(key, val, (VALUE) pk); } #else rb_hash_foreach(v, write_hash_foreach, (VALUE) pk); #endif }
VALUE ruby_libvirt_set_typed_parameters(VALUE d, VALUE input, unsigned int flags, void *opaque, struct ruby_libvirt_typed_param *allowed, unsigned int num_allowed, const char *(*set_cb)(VALUE d, unsigned int flags, virTypedParameterPtr params, int nparams, void *opaque)) { const char *errname; struct ruby_libvirt_parameter_assign_args args; unsigned long hashsize; /* make sure input is a hash */ Check_Type(input, T_HASH); hashsize = RHASH_SIZE(input); if (hashsize == 0) { return Qnil; } args.allowed = allowed; args.num_allowed = num_allowed; args.params = alloca(sizeof(virTypedParameter) * hashsize); args.i = 0; rb_hash_foreach(input, ruby_libvirt_typed_parameter_assign, (VALUE)&args); errname = set_cb(d, flags, args.params, args.i, opaque); ruby_libvirt_raise_error_if(errname != NULL, e_RetrieveError, errname, ruby_libvirt_connect_get(d)); return Qnil; }
VALUE rb_hash_notempty_p( VALUE hash) { return RHASH_SIZE( hash) == 0 ? Qnil : hash; }
/** * Encodes and appends the hash `hash` to `w` */ void watchman_dump_hash(watchman_t *w, VALUE hash) { watchman_append(w, &watchman_hash_marker, sizeof(watchman_hash_marker)); watchman_dump_int(w, RHASH_SIZE(hash)); rb_hash_foreach(hash, watchman_dump_hash_iterator, (VALUE)w); }
static int setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, struct rb_calling_info *const calling, const struct rb_call_info *ci, VALUE * const locals, const enum arg_setup_type arg_setup_type) { const int min_argc = iseq->body->param.lead_num + iseq->body->param.post_num; const int max_argc = (iseq->body->param.flags.has_rest == FALSE) ? min_argc + iseq->body->param.opt_num : UNLIMITED_ARGUMENTS; int opt_pc = 0; int given_argc; struct args_info args_body, *args; VALUE keyword_hash = Qnil; VALUE * const orig_sp = th->cfp->sp; unsigned int i; /* * Extend SP for GC. * * [pushed values] [uninitialized values] * <- ci->argc --> * <- iseq->body->param.size------------> * ^ locals ^ sp * * => * [pushed values] [initialized values ] * <- ci->argc --> * <- iseq->body->param.size------------> * ^ locals ^ sp */ for (i=calling->argc; i<iseq->body->param.size; i++) { locals[i] = Qnil; } th->cfp->sp = &locals[i]; /* setup args */ args = &args_body; given_argc = args->argc = calling->argc; args->argv = locals; if (ci->flag & VM_CALL_KWARG) { args->kw_arg = ((struct rb_call_info_with_kwarg *)ci)->kw_arg; if (iseq->body->param.flags.has_kw) { int kw_len = args->kw_arg->keyword_len; /* copy kw_argv */ args->kw_argv = ALLOCA_N(VALUE, kw_len); args->argc -= kw_len; given_argc -= kw_len; MEMCPY(args->kw_argv, locals + args->argc, VALUE, kw_len); } else { args->kw_argv = NULL; given_argc = args_kw_argv_to_hash(args); } } else { args->kw_arg = NULL; args->kw_argv = NULL; } if (ci->flag & VM_CALL_ARGS_SPLAT) { args->rest = locals[--args->argc]; args->rest_index = 0; given_argc += RARRAY_LENINT(args->rest) - 1; } else { args->rest = Qfalse; } switch (arg_setup_type) { case arg_setup_method: break; /* do nothing special */ case arg_setup_block: if (given_argc == 1 && (min_argc > 0 || iseq->body->param.opt_num > 1 || iseq->body->param.flags.has_kw || iseq->body->param.flags.has_kwrest) && !iseq->body->param.flags.ambiguous_param0 && args_check_block_arg0(args, th)) { given_argc = RARRAY_LENINT(args->rest); } break; case arg_setup_lambda: if (given_argc == 1 && given_argc != iseq->body->param.lead_num && !iseq->body->param.flags.has_rest && args_check_block_arg0(args, th)) { given_argc = RARRAY_LENINT(args->rest); } } /* argc check */ if (given_argc < min_argc) { if (given_argc == min_argc - 1 && args->kw_argv) { args_stored_kw_argv_to_hash(args); given_argc = args_argc(args); } else { if (arg_setup_type == arg_setup_block) { CHECK_VM_STACK_OVERFLOW(th->cfp, min_argc); given_argc = min_argc; args_extend(args, min_argc); } else { argument_arity_error(th, iseq, given_argc, min_argc, max_argc); } } } if (given_argc > min_argc && (iseq->body->param.flags.has_kw || iseq->body->param.flags.has_kwrest) && args->kw_argv == NULL) { if (args_pop_keyword_hash(args, &keyword_hash, th)) { given_argc--; } } if (given_argc > max_argc && max_argc != UNLIMITED_ARGUMENTS) { if (arg_setup_type == arg_setup_block) { /* truncate */ args_reduce(args, given_argc - max_argc); given_argc = max_argc; } else { argument_arity_error(th, iseq, given_argc, min_argc, max_argc); } } if (iseq->body->param.flags.has_lead) { args_setup_lead_parameters(args, iseq->body->param.lead_num, locals + 0); } if (iseq->body->param.flags.has_post) { args_setup_post_parameters(args, iseq->body->param.post_num, locals + iseq->body->param.post_start); } if (iseq->body->param.flags.has_opt) { int opt = args_setup_opt_parameters(args, iseq->body->param.opt_num, locals + iseq->body->param.lead_num); opt_pc = (int)iseq->body->param.opt_table[opt]; } if (iseq->body->param.flags.has_rest) { args_setup_rest_parameter(args, locals + iseq->body->param.rest_start); } if (iseq->body->param.flags.has_kw) { VALUE * const klocals = locals + iseq->body->param.keyword->bits_start - iseq->body->param.keyword->num; if (args->kw_argv != NULL) { const struct rb_call_info_kw_arg *kw_arg = args->kw_arg; args_setup_kw_parameters(args->kw_argv, kw_arg->keyword_len, kw_arg->keywords, iseq, klocals); } else if (!NIL_P(keyword_hash)) { int kw_len = rb_long2int(RHASH_SIZE(keyword_hash)); struct fill_values_arg arg; /* copy kw_argv */ arg.keys = args->kw_argv = ALLOCA_N(VALUE, kw_len * 2); arg.vals = arg.keys + kw_len; arg.argc = 0; rb_hash_foreach(keyword_hash, fill_keys_values, (VALUE)&arg); VM_ASSERT(arg.argc == kw_len); args_setup_kw_parameters(arg.vals, kw_len, arg.keys, iseq, klocals); } else { VM_ASSERT(args_argc(args) == 0); args_setup_kw_parameters(NULL, 0, NULL, iseq, klocals); } } else if (iseq->body->param.flags.has_kwrest) { args_setup_kw_rest_parameter(keyword_hash, locals + iseq->body->param.keyword->rest_start); } if (iseq->body->param.flags.has_block) { args_setup_block_parameter(th, calling, locals + iseq->body->param.block_start); } #if 0 { int i; for (i=0; i<iseq->body->param.size; i++) { fprintf(stderr, "local[%d] = %p\n", i, (void *)locals[i]); } } #endif th->cfp->sp = orig_sp; return opt_pc; }