bool rubyval_to_dictionary(mrb_state* mrb, mrb_value arg, __Dictionary** outValue, const char* funcName)
{
    if (! mrb_hash_p(arg)) {
        return false;
    }
    
    mrb_value key_arr = mrb_hash_keys(mrb, arg);
    mrb_int len = mrb_ary_len(mrb, key_arr);
    __Dictionary* dic = __Dictionary::create();
    for (mrb_int i = 0; i < len; i++) {
        mrb_value hk = mrb_ary_ref(mrb, key_arr, i);
        mrb_value hv = mrb_hash_get(mrb, arg, hk);
        if (mrb_string_p(hk)) {
            char *kstr = mrb_str_to_cstr(mrb, hk);
            Ref* ref = to_ref_value(mrb, hv);
            dic->setObject(ref, std::string(kstr));
        } else if (mrb_symbol_p(hk)) {
            mrb_sym sym = mrb_symbol(hk);
            const char* kstr = mrb_sym2name(mrb, sym);
            Ref* ref = to_ref_value(mrb, hv);
            dic->setObject(ref, std::string(kstr));
        } else {
            CCASSERT(false, "not supported key value type");
        }
    }
    *outValue = dic;
    
    return true;
}
bool rubyval_to_ccvaluemapintkey(mrb_state* mrb, mrb_value arg, cocos2d::ValueMapIntKey* ret, const char* funcName)
{
    if (! mrb_hash_p(arg)) {
        return false;
    }
    
    mrb_value key_arr = mrb_hash_keys(mrb, arg);
    mrb_int len = mrb_ary_len(mrb, key_arr);
    ValueMapIntKey& dict = *ret;
    for (mrb_int i = 0; i < len; i++) {
        mrb_value hk = mrb_ary_ref(mrb, key_arr, i);
        mrb_value hv = mrb_hash_get(mrb, arg, hk);
        int int_key = 0;
        
        if (mrb_string_p(hk)) {
            char *kstr = mrb_str_to_cstr(mrb, hk);
            int_key = atoi(kstr);
        } else if (mrb_symbol_p(hk)) {
            mrb_sym sym = mrb_symbol(hk);
            const char* kstr = mrb_sym2name(mrb, sym);
            int_key = atoi(kstr);
        } else {
            return false;
        }
        Value val;
        if (! rubyval_to_ccvalue(mrb, hv, &val)) {
            return false;
        }
        
        dict[int_key] = val;
    }
    return true;
}
예제 #3
0
static mrb_value
mrb_value_to_string(mrb_state* mrb, mrb_value value) {
  mrb_value str;
  ARENA_SAVE;
  switch (mrb_type(value)) {
  case MRB_TT_FIXNUM:
  case MRB_TT_FLOAT:
  case MRB_TT_TRUE:
  case MRB_TT_FALSE:
  case MRB_TT_UNDEF:
    str = mrb_funcall(mrb, value, "to_s", 0, NULL);
    break;
  case MRB_TT_STRING:
    str = mrb_funcall(mrb, value, "inspect", 0, NULL);
    break;
  case MRB_TT_HASH:
    {
      str = mrb_str_new_cstr(mrb, "{");
      mrb_value keys = mrb_hash_keys(mrb, value);
      int n, l = RARRAY_LEN(keys);
      for (n = 0; n < l; n++) {
        mrb_value key = mrb_ary_entry(keys, n);
        mrb_value enckey = mrb_funcall(mrb, key, "to_s", 0, NULL);
        enckey = mrb_funcall(mrb, enckey, "inspect", 0, NULL);
        mrb_str_concat(mrb, str, enckey);
        mrb_str_cat2(mrb, str, ":");
        mrb_value obj = mrb_hash_get(mrb, value, key);
        mrb_str_concat(mrb, str, mrb_value_to_string(mrb, obj));
        if (n != l - 1) {
          mrb_str_cat2(mrb, str, ",");
        }
        ARENA_RESTORE;
      }
      mrb_str_cat2(mrb, str, "}");
      break;
    }
  case MRB_TT_ARRAY:
    {
      mrb_value str = mrb_str_new_cstr(mrb, "[");
      int n, l = RARRAY_LEN(value);
      for (n = 0; n < l; n++) {
        mrb_value obj = mrb_ary_entry(value, n);
        mrb_str_concat(mrb, str, mrb_value_to_string(mrb, obj));
        if (n != l - 1) {
          mrb_str_cat2(mrb, str, ",");
        }
        ARENA_RESTORE;
      }
      mrb_str_cat2(mrb, str, "]");
      break;
    }
  default:
    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
  }
  ARENA_RESTORE;
  return str;
}
예제 #4
0
파일: mruby.c 프로젝트: mururu/erlang-mruby
static ERL_NIF_TERM make_hash(ErlNifEnv* env, mrb_state* mrb, mrb_value o) {
  mrb_value keys = mrb_hash_keys(mrb, o);
  size_t len = (int) RARRAY(keys)->len;
  ERL_NIF_TERM list = enif_make_list_from_array(env, NULL, 0);

  for(int i = len; i>0; --i) {
    mrb_value k = mrb_ary_ref(mrb, keys, (mrb_int)i - 1);
    ERL_NIF_TERM key = mruby2erl(env, mrb, k);
    ERL_NIF_TERM value = mruby2erl(env, mrb, mrb_hash_get(mrb, o, k));
    list = enif_make_list_cell(env, enif_make_tuple2(env, key, value), list);
  }

  return enif_make_tuple1(env, list);
}
예제 #5
0
파일: mruby.cpp 프로젝트: taksatou/embench
std::map<std::string, std::string> MRuby::invert(const std::map<std::string, std::string> &lis) const {
    std::map<std::string, std::string> res;

    mrb_value a = mrb_hash_new_capa(mMrb, lis.size());
    for (auto it = lis.begin(); it != lis.end(); ++it) {
        mrb_hash_set(mMrb, a, mrb_str_new_cstr(mMrb, it->first.c_str()), mrb_str_new_cstr(mMrb, it->second.c_str()));
    }
    mrb_value r = mrb_funcall(mMrb, mrb_top_self(mMrb), "invert", 1, a);
    mrb_value keys = mrb_hash_keys(mMrb, r);
    for (int i = 0; i < RARRAY_LEN(keys); ++i) {
        mrb_value k = mrb_ary_ref(mMrb, keys, i);
        mrb_value v = mrb_hash_get(mMrb, r, k);
        res[mrb_str_to_cstr(mMrb, k)] = mrb_str_to_cstr(mMrb, v);
    }
    return res;
}
예제 #6
0
static mrb_value mrb_vedis_append_hash(mrb_state *mrb, mrb_value self)
{
    int ai;
    vedis *vstore = DATA_PTR(self);
    mrb_value hash, keys, key, val;

    mrb_get_args(mrb, "H", &hash);
    keys = mrb_hash_keys(mrb, hash);
    ai = mrb_gc_arena_save(mrb);
    while (!mrb_nil_p(key = mrb_ary_pop(mrb, keys))) {
        val = mrb_hash_get(mrb, hash, key);
        mrb_vedis_append_s(mrb, key, val, vstore);
        mrb_gc_arena_restore(mrb, ai);
    }
    return mrb_true_value();
}
예제 #7
0
void
mrb_mruby_wslay_gem_init(mrb_state* mrb) {
  struct RClass *wslay_mod, *wslay_error_cl, *wslay_event_mod,
  *wslay_event_context_cl, *wslay_event_context_server_cl, *wslay_event_context_client_cl;

  wslay_mod = mrb_define_module(mrb, "Wslay");
  mrb_define_module_function(mrb, wslay_mod, "get_rsv1", mrb_wslay_get_rsv1, MRB_ARGS_REQ(1));
  mrb_define_module_function(mrb, wslay_mod, "get_rsv2", mrb_wslay_get_rsv2, MRB_ARGS_REQ(1));
  mrb_define_module_function(mrb, wslay_mod, "get_rsv3", mrb_wslay_get_rsv3, MRB_ARGS_REQ(1));
  wslay_error_cl = mrb_define_class_under(mrb, wslay_mod, "Err", E_RUNTIME_ERROR);
  mrb_value wslay_error_hash = mrb_hash_new_capa(mrb, 9 * 2);
  mrb_define_const(mrb, wslay_mod, "Error", wslay_error_hash);
  mrb_hash_set(mrb, wslay_error_hash, mrb_fixnum_value(WSLAY_ERR_WANT_READ), mrb_symbol_value(mrb_intern_lit(mrb, "want_read")));
  mrb_hash_set(mrb, wslay_error_hash, mrb_fixnum_value(WSLAY_ERR_WANT_WRITE), mrb_symbol_value(mrb_intern_lit(mrb, "want_write")));
  mrb_hash_set(mrb, wslay_error_hash, mrb_fixnum_value(WSLAY_ERR_PROTO), mrb_symbol_value(mrb_intern_lit(mrb, "proto")));
  mrb_hash_set(mrb, wslay_error_hash, mrb_fixnum_value(WSLAY_ERR_INVALID_ARGUMENT), mrb_symbol_value(mrb_intern_lit(mrb, "invalid_argument")));
  mrb_hash_set(mrb, wslay_error_hash, mrb_fixnum_value(WSLAY_ERR_INVALID_CALLBACK), mrb_symbol_value(mrb_intern_lit(mrb, "invalid_callback")));
  mrb_hash_set(mrb, wslay_error_hash, mrb_fixnum_value(WSLAY_ERR_NO_MORE_MSG), mrb_symbol_value(mrb_intern_lit(mrb, "no_more_msg")));
  mrb_hash_set(mrb, wslay_error_hash, mrb_fixnum_value(WSLAY_ERR_CALLBACK_FAILURE), mrb_symbol_value(mrb_intern_lit(mrb, "callback_failure")));
  mrb_hash_set(mrb, wslay_error_hash, mrb_fixnum_value(WSLAY_ERR_WOULDBLOCK), mrb_symbol_value(mrb_intern_lit(mrb, "wouldblock")));
  mrb_hash_set(mrb, wslay_error_hash, mrb_fixnum_value(WSLAY_ERR_NOMEM), mrb_symbol_value(mrb_intern_lit(mrb, "nomem")));
  mrb_value wslay_error_hash_keys = mrb_hash_keys(mrb, wslay_error_hash);
  for (mrb_int i = 0; i < RARRAY_LEN(wslay_error_hash_keys); i++) {
    mrb_value key = mrb_ary_ref(mrb, wslay_error_hash_keys, i);
    mrb_hash_set(mrb, wslay_error_hash,
      mrb_hash_get(mrb, wslay_error_hash, key), key);
  }

  mrb_value wslay_status_code_hash = mrb_hash_new_capa(mrb, 12 * 2);
  mrb_define_const(mrb, wslay_mod, "StatusCode", wslay_status_code_hash);
  mrb_hash_set(mrb, wslay_status_code_hash, mrb_fixnum_value(WSLAY_CODE_NORMAL_CLOSURE), mrb_symbol_value(mrb_intern_lit(mrb, "normal_closure")));
  mrb_hash_set(mrb, wslay_status_code_hash, mrb_fixnum_value(WSLAY_CODE_GOING_AWAY), mrb_symbol_value(mrb_intern_lit(mrb, "going_away")));
  mrb_hash_set(mrb, wslay_status_code_hash, mrb_fixnum_value(WSLAY_CODE_PROTOCOL_ERROR), mrb_symbol_value(mrb_intern_lit(mrb, "protocol_error")));
  mrb_hash_set(mrb, wslay_status_code_hash, mrb_fixnum_value(WSLAY_CODE_UNSUPPORTED_DATA), mrb_symbol_value(mrb_intern_lit(mrb, "unsupported_data")));
  mrb_hash_set(mrb, wslay_status_code_hash, mrb_fixnum_value(WSLAY_CODE_NO_STATUS_RCVD), mrb_symbol_value(mrb_intern_lit(mrb, "no_status_rcvd")));
  mrb_hash_set(mrb, wslay_status_code_hash, mrb_fixnum_value(WSLAY_CODE_ABNORMAL_CLOSURE), mrb_symbol_value(mrb_intern_lit(mrb, "abnormal_closure")));
  mrb_hash_set(mrb, wslay_status_code_hash, mrb_fixnum_value(WSLAY_CODE_INVALID_FRAME_PAYLOAD_DATA), mrb_symbol_value(mrb_intern_lit(mrb, "invalid_frame_payload_data")));
  mrb_hash_set(mrb, wslay_status_code_hash, mrb_fixnum_value(WSLAY_CODE_POLICY_VIOLATION), mrb_symbol_value(mrb_intern_lit(mrb, "policy_violation")));
  mrb_hash_set(mrb, wslay_status_code_hash, mrb_fixnum_value(WSLAY_CODE_MESSAGE_TOO_BIG), mrb_symbol_value(mrb_intern_lit(mrb, "message_too_big")));
  mrb_hash_set(mrb, wslay_status_code_hash, mrb_fixnum_value(WSLAY_CODE_MANDATORY_EXT), mrb_symbol_value(mrb_intern_lit(mrb, "mandatory_ext")));
  mrb_hash_set(mrb, wslay_status_code_hash, mrb_fixnum_value(WSLAY_CODE_INTERNAL_SERVER_ERROR), mrb_symbol_value(mrb_intern_lit(mrb, "internal_server_error")));
  mrb_hash_set(mrb, wslay_status_code_hash, mrb_fixnum_value(WSLAY_CODE_TLS_HANDSHAKE), mrb_symbol_value(mrb_intern_lit(mrb, "tls_handshake")));
  mrb_value wslay_status_code_hash_keys = mrb_hash_keys(mrb, wslay_status_code_hash);
  for (mrb_int i = 0; i < RARRAY_LEN(wslay_status_code_hash_keys); i++) {
    mrb_value key = mrb_ary_ref(mrb, wslay_status_code_hash_keys, i);
    mrb_hash_set(mrb, wslay_status_code_hash,
      mrb_hash_get(mrb, wslay_status_code_hash, key), key);
  }

  mrb_value io_flags_hash = mrb_hash_new_capa(mrb, 2);
  mrb_define_const(mrb, wslay_mod, "IoFlags", io_flags_hash);
  mrb_hash_set(mrb, io_flags_hash, mrb_fixnum_value(WSLAY_MSG_MORE), mrb_symbol_value(mrb_intern_lit(mrb, "msg_more")));
  mrb_hash_set(mrb, io_flags_hash, mrb_symbol_value(mrb_intern_lit(mrb, "msg_more")), mrb_fixnum_value(WSLAY_MSG_MORE));

  mrb_value wslay_opcode_hash = mrb_hash_new_capa(mrb, 6 * 2);
  mrb_define_const(mrb, wslay_mod, "OpCode", wslay_opcode_hash);
  mrb_hash_set(mrb, wslay_opcode_hash, mrb_fixnum_value(WSLAY_CONTINUATION_FRAME), mrb_symbol_value(mrb_intern_lit(mrb, "continuation_frame")));
  mrb_hash_set(mrb, wslay_opcode_hash, mrb_fixnum_value(WSLAY_TEXT_FRAME), mrb_symbol_value(mrb_intern_lit(mrb, "text_frame")));
  mrb_hash_set(mrb, wslay_opcode_hash, mrb_fixnum_value(WSLAY_BINARY_FRAME), mrb_symbol_value(mrb_intern_lit(mrb, "binary_frame")));
  mrb_hash_set(mrb, wslay_opcode_hash, mrb_fixnum_value(WSLAY_CONNECTION_CLOSE), mrb_symbol_value(mrb_intern_lit(mrb, "connection_close")));
  mrb_hash_set(mrb, wslay_opcode_hash, mrb_fixnum_value(WSLAY_PING), mrb_symbol_value(mrb_intern_lit(mrb, "ping")));
  mrb_hash_set(mrb, wslay_opcode_hash, mrb_fixnum_value(WSLAY_PONG), mrb_symbol_value(mrb_intern_lit(mrb, "pong")));
  mrb_value wslay_opcode_hash_keys = mrb_hash_keys(mrb, wslay_opcode_hash);
  for (mrb_int i = 0; i < RARRAY_LEN(wslay_opcode_hash_keys); i++) {
    mrb_value key = mrb_ary_ref(mrb, wslay_opcode_hash_keys, i);
    mrb_hash_set(mrb, wslay_opcode_hash,
      mrb_hash_get(mrb, wslay_opcode_hash, key), key);
  }

  wslay_event_mod = mrb_define_module_under(mrb, wslay_mod, "Event");
  wslay_event_context_cl = mrb_define_class_under(mrb, wslay_event_mod, "Context", mrb->object_class);
  MRB_SET_INSTANCE_TT(wslay_event_context_cl, MRB_TT_DATA);
  mrb_define_method(mrb, wslay_event_context_cl, "no_buffering=",         mrb_wslay_event_config_set_no_buffering,        MRB_ARGS_REQ(1));
  mrb_define_method(mrb, wslay_event_context_cl, "max_recv_msg_length=",  mrb_wslay_event_config_set_max_recv_msg_length, MRB_ARGS_REQ(1));
  mrb_define_method(mrb, wslay_event_context_cl, "recv",                  mrb_wslay_event_recv,                           MRB_ARGS_NONE());
  mrb_define_method(mrb, wslay_event_context_cl, "send",                  mrb_wslay_event_send,                           MRB_ARGS_NONE());
  mrb_define_method(mrb, wslay_event_context_cl, "queue_msg",             mrb_wslay_event_queue_msg,                      MRB_ARGS_REQ(2));
  mrb_define_method(mrb, wslay_event_context_cl, "queue_close",           mrb_wslay_event_queue_close,                    MRB_ARGS_ARG(1, 1));
  mrb_define_method(mrb, wslay_event_context_cl, "want_read?",            mrb_wslay_event_want_read,                      MRB_ARGS_NONE());
  mrb_define_method(mrb, wslay_event_context_cl, "want_write?",           mrb_wslay_event_want_write,                     MRB_ARGS_NONE());
  mrb_define_method(mrb, wslay_event_context_cl, "close_received?",       mrb_wslay_event_get_close_received,             MRB_ARGS_NONE());
  mrb_define_method(mrb, wslay_event_context_cl, "close_sent?",           mrb_wslay_event_get_close_sent,                 MRB_ARGS_NONE());
  mrb_define_method(mrb, wslay_event_context_cl, "status_code_received",  mrb_wslay_event_get_status_code_received,       MRB_ARGS_NONE());
  mrb_define_method(mrb, wslay_event_context_cl, "status_code_sent",      mrb_wslay_event_get_status_code_sent,           MRB_ARGS_NONE());
  mrb_define_method(mrb, wslay_event_context_cl, "queued_msg_count",      mrb_wslay_event_get_queued_msg_count,           MRB_ARGS_NONE());
  mrb_define_method(mrb, wslay_event_context_cl, "queued_msg_length",     mrb_wslay_event_get_queued_msg_length,          MRB_ARGS_NONE());

  wslay_event_context_server_cl = mrb_define_class_under(mrb, wslay_event_context_cl, "Server", wslay_event_context_cl);
  mrb_define_method(mrb, wslay_event_context_server_cl, "initialize", mrb_wslay_event_context_server_init, MRB_ARGS_REQ(1));

  wslay_event_context_client_cl = mrb_define_class_under(mrb, wslay_event_context_cl, "Client", wslay_event_context_cl);
  mrb_define_method(mrb, wslay_event_context_client_cl, "initialize", mrb_wslay_event_context_client_init, MRB_ARGS_REQ(1));
}
예제 #8
0
static mrb_value
mrb_curl_get(mrb_state *mrb, mrb_value self)
{
  char error[CURL_ERROR_SIZE] = {0};
  CURL* curl;
  CURLcode res = CURLE_OK;
  MEMFILE* mf;
  struct RClass* _class_curl;
  int ssl_verifypeer;
  struct curl_slist* headerlist = NULL;
  mrb_value str;
  struct RClass* _class_http;
  struct RClass* _class_http_parser;
  mrb_value parser;
  mrb_value args[1];

  mrb_value url = mrb_nil_value();
  mrb_value headers = mrb_nil_value();
  mrb_value b = mrb_nil_value();
  mrb_get_args(mrb, "S|H&", &url, &headers, &b);

  if (!mrb_nil_p(headers) && mrb_type(headers) != MRB_TT_HASH) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
  }
  mf = memfopen();
  curl = curl_easy_init();
  _class_curl = mrb_class_get(mrb, "Curl");
  ssl_verifypeer = mrb_fixnum(mrb_const_get(mrb, mrb_obj_value(_class_curl), mrb_intern_cstr(mrb, "SSL_VERIFYPEER")));
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, ssl_verifypeer);
  curl_easy_setopt(curl, CURLOPT_URL, RSTRING_PTR(url));
  curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, mf);
  if (mrb_nil_p(b)) {
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite);
  } else {
    mf->mrb = mrb;
    mf->proc = b;
    mf->header = mrb_nil_value();
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite_callback);
  }
  curl_easy_setopt(curl, CURLOPT_HEADERDATA, mf);
  curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, memfwrite);
  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 0);

  if (!mrb_nil_p(headers)) {
    mrb_value keys = mrb_hash_keys(mrb, headers);
    int i, l = RARRAY_LEN(keys);
    for (i = 0; i < l; i++) {
      mrb_value key = mrb_ary_entry(keys, i);
      mrb_value header = mrb_str_dup(mrb, key);
      mrb_str_cat2(mrb, header, ": ");
      mrb_str_concat(mrb, header, mrb_hash_get(mrb, headers, key));
      headerlist = curl_slist_append(headerlist, RSTRING_PTR(header));
    }
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
  }

  res = curl_easy_perform(curl);

  if (headerlist)
    curl_slist_free_all(headerlist);

  curl_easy_cleanup(curl);
  if (res != CURLE_OK) {
    mrb_raise(mrb, E_RUNTIME_ERROR, error);
  }
  if (!mrb_nil_p(b)) {
    return mrb_nil_value();
  }

  str = mrb_str_new(mrb, mf->data, mf->size);
  memfclose(mf);

  _class_http = mrb_class_get(mrb, "HTTP");
  _class_http_parser = mrb_class_ptr(mrb_const_get(mrb, mrb_obj_value(_class_http), mrb_intern_cstr(mrb, "Parser")));
  parser = mrb_obj_new(mrb, _class_http_parser, 0, NULL);
  args[0] = str;
  return mrb_funcall_argv(mrb, parser, mrb_intern_cstr(mrb, "parse_response"), 1, args);
}
예제 #9
0
파일: yaml.c 프로젝트: hone/mruby-yaml
int value_to_node(mrb_state *mrb,
  yaml_document_t *document, mrb_value value)
{
  int node;

  switch (mrb_type(value))
  {
    case MRB_TT_ARRAY:
    {
      mrb_int len = mrb_ary_len(mrb, value);
      mrb_int i;
      int ai = mrb_gc_arena_save(mrb);

      node = yaml_document_add_sequence(document, NULL,
        YAML_ANY_SEQUENCE_STYLE);

      for (i = 0; i < len; i++)
      {
        mrb_value child = mrb_ary_ref(mrb, value, i);
        int child_node = value_to_node(mrb, document, child);

        /* Add the child to the sequence */
        yaml_document_append_sequence_item(document, node, child_node);
        mrb_gc_arena_restore(mrb, ai);
      }

      break;
    }

    case MRB_TT_HASH:
    {
      /* Iterating a list of keys is slow, but it only
       * requires use of the interface defined in `hash.h`.
       */

      mrb_value keys = mrb_hash_keys(mrb, value);
      mrb_int len = mrb_ary_len(mrb, keys);
      mrb_int i;
      int ai = mrb_gc_arena_save(mrb);

      node = yaml_document_add_mapping(document, NULL,
        YAML_ANY_MAPPING_STYLE);

      for (i = 0; i < len; i++)
      {
        mrb_value key = mrb_ary_ref(mrb, keys, i);
        mrb_value child = mrb_hash_get(mrb, value, key);

        int key_node = value_to_node(mrb, document, key);
        int child_node = value_to_node(mrb, document, child);

        /* Add the key/value pair to the mapping */
        yaml_document_append_mapping_pair(document, node,
          key_node, child_node);
        mrb_gc_arena_restore(mrb, ai);
      }

      break;
    }

    default:
    {
      if (mrb_nil_p(value)) {
        /* http://yaml.org/type/null.html
           Canonical form */
        value = mrb_str_new_lit(mrb, "~");
      } else {
        /* Equivalent to `obj = obj#to_s` */
        value = mrb_obj_as_string(mrb, value);
      }
      /* Fallthrough */
    }

    case MRB_TT_STRING:
    {
      yaml_scalar_style_t style = YAML_ANY_SCALAR_STYLE;
      if (RSTRING_LEN(value) == 0) {
        /* If the String is empty, it may be reloaded as a nil instead of an
         * empty string, to avoid that place a quoted string instead */
        style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
      }
      yaml_char_t *value_chars = (unsigned char *) RSTRING_PTR(value);
      node = yaml_document_add_scalar(document, NULL,
        value_chars, RSTRING_LEN(value), style);
      break;
    }
  }

  return node;
}
예제 #10
0
/*********************************************************
 * main
 *********************************************************/
static mrb_value
mrb_value_to_string(mrb_state* mrb, mrb_value value) {
  mrb_value str;

  if (mrb_nil_p(value)) {
    return mrb_str_new_cstr(mrb, "null");
  }

  switch (mrb_type(value)) {
  case MRB_TT_FIXNUM:
  case MRB_TT_FLOAT:
  case MRB_TT_TRUE:
  case MRB_TT_FALSE:
  case MRB_TT_UNDEF:
    str = mrb_funcall(mrb, value, "to_s", 0, NULL);
    break;
  case MRB_TT_SYMBOL:
    value = mrb_funcall(mrb, value, "to_s", 0, NULL);
    /* FALLTHROUGH */
  case MRB_TT_STRING:
    {
      int ai = mrb_gc_arena_save(mrb);
      char* ptr = RSTRING_PTR(value);
      char* end = RSTRING_END(value);
      str = mrb_str_new_cstr(mrb, "\""); 
      while (ptr < end && *ptr) {
        switch (*ptr) {
        case '\\':
          str = mrb_str_cat_cstr(mrb, str, "\\\\");
          break;
        case '"':
          str = mrb_str_cat_cstr(mrb, str, "\\\"");
          break;
        case '\b':
          str = mrb_str_cat_cstr(mrb, str, "\\b");
          break;
        case '\f':
          str = mrb_str_cat_cstr(mrb, str, "\\f");
          break;
        case '\n':
          str = mrb_str_cat_cstr(mrb, str, "\\n");
          break;
        case '\r':
          str = mrb_str_cat_cstr(mrb, str, "\\r");
          break;
        case '\t':
          str = mrb_str_cat_cstr(mrb, str, "\\t");
          break;
        default:
          // TODO: handle unicode
          str = mrb_str_cat(mrb, str, ptr, 1);
        }
        ptr++;
      }
      mrb_str_cat_cstr(mrb, str, "\""); 
      mrb_gc_arena_restore(mrb, ai);
    }
    break;
  case MRB_TT_HASH:
    {
      mrb_value keys;
      int n, l;
      str = mrb_str_new_cstr(mrb, "{");
      keys = mrb_hash_keys(mrb, value);
      l = RARRAY_LEN(keys);
      for (n = 0; n < l; n++) {
        mrb_value obj;
        int ai = mrb_gc_arena_save(mrb);
        mrb_value key = mrb_ary_entry(keys, n);
        mrb_value enckey = mrb_funcall(mrb, key, "to_s", 0, NULL);
        enckey = mrb_funcall(mrb, enckey, "inspect", 0, NULL);
        mrb_str_concat(mrb, str, enckey);
        mrb_str_cat_cstr(mrb, str, ":");
        obj = mrb_hash_get(mrb, value, key);
        mrb_str_concat(mrb, str, mrb_value_to_string(mrb, obj));
        if (n != l - 1) {
          mrb_str_cat_cstr(mrb, str, ",");
        }
        mrb_gc_arena_restore(mrb, ai);
      }
      mrb_str_cat_cstr(mrb, str, "}");
      break;
    }
  case MRB_TT_ARRAY:
    {
      int n, l;
      str = mrb_str_new_cstr(mrb, "[");
      l = RARRAY_LEN(value);
      for (n = 0; n < l; n++) {
        int ai = mrb_gc_arena_save(mrb);
        mrb_value obj = mrb_ary_entry(value, n);
        mrb_str_concat(mrb, str, mrb_value_to_string(mrb, obj));
        if (n != l - 1) {
          mrb_str_cat_cstr(mrb, str, ",");
        }
        mrb_gc_arena_restore(mrb, ai);
      }
      mrb_str_cat_cstr(mrb, str, "]");
      break;
    }
  default:
    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
  }
  return str;
}
예제 #11
0
// based on https://gist.github.com/3066997
static mrb_value
migrate_simple_value(mrb_state *mrb, mrb_value v, mrb_state *mrb2) {
  mrb_value nv;

  switch (mrb_type(v)) {
  case MRB_TT_OBJECT:
  case MRB_TT_EXCEPTION:
    {
      struct RObject *o = mrb_obj_ptr(v);
      mrb_value path = mrb_class_path(mrb, o->c);
      struct RClass *c;

      if (mrb_nil_p(path)) {
        mrb_raise(mrb, E_TYPE_ERROR, "cannot migrate class");
      }
      c = mrb_class_get(mrb2, RSTRING_PTR(path));
      nv = mrb_obj_value(mrb_obj_alloc(mrb2, mrb_type(v), c));
    }
    migrate_simple_iv(mrb, v, mrb2, nv);
    break;
  case MRB_TT_FALSE:
  case MRB_TT_TRUE:
  case MRB_TT_FIXNUM:
    nv = v;
    break;
  case MRB_TT_SYMBOL:
    nv = mrb_symbol_value(migrate_sym(mrb, mrb_symbol(v), mrb2));
    break;
  case MRB_TT_FLOAT:
    nv = mrb_float_value(mrb2, mrb_float(v));
    break;
  case MRB_TT_STRING:
    nv = mrb_str_new(mrb2, RSTRING_PTR(v), RSTRING_LEN(v));
    break;
  case MRB_TT_RANGE:
    {
      struct RRange *r = mrb_range_ptr(v);
      nv = mrb_range_new(mrb2,
                         migrate_simple_value(mrb, r->edges->beg, mrb2),
                         migrate_simple_value(mrb, r->edges->end, mrb2),
                         r->excl);
    }
    break;
  case MRB_TT_ARRAY:
    {
      struct RArray *a0, *a1;
      int i;

      a0 = mrb_ary_ptr(v);
      nv = mrb_ary_new_capa(mrb2, a0->len);
      a1 = mrb_ary_ptr(nv);
      for (i=0; i<a0->len; i++) {
        int ai = mrb_gc_arena_save(mrb2);
        a1->ptr[i] = migrate_simple_value(mrb, a0->ptr[i], mrb2);
        a1->len++;
        mrb_gc_arena_restore(mrb2, ai);
      }
    }
    break;
  case MRB_TT_HASH:
    {
      mrb_value ka;
      int i, l;

      nv = mrb_hash_new(mrb2);
      ka = mrb_hash_keys(mrb, v);
      l = RARRAY_LEN(ka);
      for (i = 0; i < l; i++) {
        int ai = mrb_gc_arena_save(mrb2);
        mrb_value k = migrate_simple_value(mrb, mrb_ary_entry(ka, i), mrb2);
        mrb_value o = migrate_simple_value(mrb, mrb_hash_get(mrb, v, k), mrb2);
        mrb_hash_set(mrb2, nv, k, o);
        mrb_gc_arena_restore(mrb2, ai);
      }
    }
    migrate_simple_iv(mrb, v, mrb2, nv);
    break;
  case MRB_TT_DATA:
    if (!is_safe_migratable_datatype(DATA_TYPE(v)))
      mrb_raise(mrb, E_TYPE_ERROR, "cannot migrate object");
    nv = v;
    DATA_PTR(nv) = DATA_PTR(v);
    DATA_TYPE(nv) = DATA_TYPE(v);
    migrate_simple_iv(mrb, v, mrb2, nv);
    break;
  default:
    mrb_raise(mrb, E_TYPE_ERROR, "cannot migrate object");
    break;
  }
  return nv;
}
예제 #12
0
static mrb_bool
is_safe_migratable_simple_value(mrb_state *mrb, mrb_value v, mrb_state *mrb2)
{
  switch (mrb_type(v)) {
  case MRB_TT_OBJECT:
  case MRB_TT_EXCEPTION:
    {
      struct RObject *o = mrb_obj_ptr(v);
      mrb_value path = mrb_class_path(mrb, o->c);

      if (mrb_nil_p(path) || !mrb_class_defined(mrb2, RSTRING_PTR(path))) {
        return FALSE;
      }
    }
    break;
  case MRB_TT_FALSE:
  case MRB_TT_TRUE:
  case MRB_TT_FIXNUM:
  case MRB_TT_SYMBOL:
  case MRB_TT_FLOAT:
  case MRB_TT_STRING:
    break;
  case MRB_TT_RANGE:
    {
      struct RRange *r = mrb_range_ptr(v);
      if (!is_safe_migratable_simple_value(mrb, r->edges->beg, mrb2) ||
          !is_safe_migratable_simple_value(mrb, r->edges->end, mrb2)) {
        return FALSE;
      }
    }
    break;
  case MRB_TT_ARRAY:
    {
      struct RArray *a0;
      int i;
      a0 = mrb_ary_ptr(v);
      for (i=0; i<a0->len; i++) {
        if (!is_safe_migratable_simple_value(mrb, a0->ptr[i], mrb2)) {
          return FALSE;
        }
      }
    }
    break;
  case MRB_TT_HASH:
    {
      mrb_value ka;
      int i, l;
      ka = mrb_hash_keys(mrb, v);
      l = RARRAY_LEN(ka);
      for (i = 0; i < l; i++) {
        mrb_value k = mrb_ary_entry(ka, i);
        if (!is_safe_migratable_simple_value(mrb, k, mrb2) ||
            !is_safe_migratable_simple_value(mrb, mrb_hash_get(mrb, v, k), mrb2)) {
          return FALSE;
        }
      }
    }
    break;
  case MRB_TT_DATA:
    if (!is_safe_migratable_datatype(DATA_TYPE(v)))
      return FALSE;
    break;
  default:
    return FALSE;
    break;
  }
  return TRUE;
}
예제 #13
0
// based on https://gist.github.com/3066997
static mrb_value
migrate_simple_value(mrb_state *mrb, mrb_value v, mrb_state *mrb2) {
  mrb_value nv = mrb_nil_value();

  nv.tt = v.tt;
  switch (mrb_type(v)) {
  case MRB_TT_OBJECT:
    nv.value.p = v.value.p;
    break;
  case MRB_TT_FALSE:
  case MRB_TT_TRUE:
  case MRB_TT_FIXNUM:
    nv.value.i = v.value.i;
    break;
  case MRB_TT_SYMBOL:
    nv = mrb_symbol_value(mrb_intern_str(mrb2, v));
    break;
  case MRB_TT_FLOAT:
    nv.value.f = v.value.f;
    break;
  case MRB_TT_STRING:
    nv = mrb_str_new(mrb2, RSTRING_PTR(v), RSTRING_LEN(v));
    break;
  case MRB_TT_ARRAY:
    {
      struct RArray *a0, *a1;
      int i;

      a0 = mrb_ary_ptr(v);
      nv = mrb_ary_new_capa(mrb2, a0->len);
      a1 = mrb_ary_ptr(nv);
      for (i=0; i<a0->len; i++) {
        int ai = mrb_gc_arena_save(mrb2);
        a1->ptr[i] = migrate_simple_value(mrb, a0->ptr[i], mrb2);
        a1->len++;
        mrb_gc_arena_restore(mrb2, ai);
      }
    }
    break;
  case MRB_TT_HASH:
    {
      mrb_value ka;
      int i, l;

      nv = mrb_hash_new(mrb2);
      ka = mrb_hash_keys(mrb, v);
      l = RARRAY_LEN(ka);
      for (i = 0; i < l; i++) {
        int ai = mrb_gc_arena_save(mrb2);
        mrb_value k = migrate_simple_value(mrb, mrb_ary_entry(ka, i), mrb2);
        mrb_value o = migrate_simple_value(mrb, mrb_hash_get(mrb, v, k), mrb2);
        mrb_hash_set(mrb2, nv, k, o);
        mrb_gc_arena_restore(mrb2, ai);
      }
    }
    break;
  default:
    mrb_raise(mrb, E_TYPE_ERROR, "cannot migrate object");
    break;
  }
  return nv;
}