Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 112 lines (96 sloc) 2.207 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
/*
* MacRuby Hash.
*
* Copyright (C) 2011, Apple Inc. All rights reserved.
*/

#ifndef __HASH_H_
#define __HASH_H_

#if defined(__cplusplus)
extern "C" {
#endif

typedef struct {
    struct RBasic basic;
    st_table *tbl;
    VALUE ifnone;
    bool has_proc_default;
} rb_hash_t;

#define RHASH(x) ((rb_hash_t *)x)

static inline bool
rb_klass_is_rhash(VALUE klass)
{
    do {
if (klass == rb_cRubyHash) {
return true;
}
if (klass == rb_cNSHash) {
return false;
}
klass = RCLASS_SUPER(klass);
    }
    while (klass != 0);
    return false;
}

#define IS_RHASH(x) (rb_klass_is_rhash(*(VALUE *)x))

static inline void
rhash_modify(VALUE hash)
{
    const long mask = RBASIC(hash)->flags;
    if ((mask & FL_FREEZE) == FL_FREEZE) {
rb_raise(rb_eRuntimeError, "can't modify frozen/immutable hash");
    }
    if ((mask & FL_UNTRUSTED) != FL_UNTRUSTED) {
if (rb_safe_level() >= 4) {
rb_raise(rb_eSecurityError, "Insecure: can't modify hash");
}
    }
}

static inline long
rhash_len(VALUE hash)
{
    return RHASH(hash)->tbl->num_entries;
}

static inline void
rhash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg)
{
    st_foreach_safe(RHASH(hash)->tbl, func, (st_data_t)farg);
}

static inline VALUE
rhash_lookup(VALUE hash, VALUE key)
{
    VALUE val;
    if (st_lookup(RHASH(hash)->tbl, key, &val)) {
return val;
    }
    return Qundef;
}

static inline VALUE
rhash_store(VALUE hash, VALUE key, VALUE val)
{
    rhash_modify(hash);
    if (TYPE(key) == T_STRING) {
        key = rb_str_dup(key);
        OBJ_FREEZE(key);
    }
    st_insert(RHASH(hash)->tbl, key, val);
    return val;
}

static inline VALUE
rhash_delete_key(VALUE hash, VALUE key)
{
    VALUE val;
    if (st_delete(RHASH(hash)->tbl, &key, &val)) {
return val;
    }
    return Qundef;
}

VALUE rhash_dup(VALUE rcv, SEL sel);
VALUE rhash_aref(VALUE hash, SEL sel, VALUE key);
VALUE rhash_aset(VALUE hash, SEL sel, VALUE key, VALUE val);
VALUE rhash_keys(VALUE hash, SEL sel);
VALUE rhash_has_key(VALUE hash, SEL sel, VALUE key);
VALUE rhash_set_default(VALUE hash, SEL sel, VALUE ifnone);

unsigned long rb_hash_code(VALUE obj);

#if defined(__cplusplus)
} // extern "C"
#endif

#endif // __HASH_H_
Something went wrong with that request. Please try again.