Beispiel #1
1
static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
  VALUE defaults, opts, block;
  ID db_timezone, app_timezone, dbTz, appTz;
  unsigned long i;
  const char * errstr;
  int symbolizeKeys, asArray, castBool, cacheRows, cast;
  MYSQL_FIELD * fields = NULL;

  GET_RESULT(self);

  defaults = rb_iv_get(self, "@query_options");
  Check_Type(defaults, T_HASH);
  if (rb_scan_args(argc, argv, "01&", &opts, &block) == 1) {
    opts = rb_funcall(defaults, intern_merge, 1, opts);
  } else {
    opts = defaults;
  }

  symbolizeKeys = RTEST(rb_hash_aref(opts, sym_symbolize_keys));
  asArray       = rb_hash_aref(opts, sym_as) == sym_array;
  castBool      = RTEST(rb_hash_aref(opts, sym_cast_booleans));
  cacheRows     = RTEST(rb_hash_aref(opts, sym_cache_rows));
  cast          = RTEST(rb_hash_aref(opts, sym_cast));

  if (wrapper->is_streaming && cacheRows) {
    rb_warn(":cache_rows is ignored if :stream is true");
  }

  dbTz = rb_hash_aref(opts, sym_database_timezone);
  if (dbTz == sym_local) {
    db_timezone = intern_local;
  } else if (dbTz == sym_utc) {
    db_timezone = intern_utc;
  } else {
    if (!NIL_P(dbTz)) {
      rb_warn(":database_timezone option must be :utc or :local - defaulting to :local");
    }
    db_timezone = intern_local;
  }

  appTz = rb_hash_aref(opts, sym_application_timezone);
  if (appTz == sym_local) {
    app_timezone = intern_local;
  } else if (appTz == sym_utc) {
    app_timezone = intern_utc;
  } else {
    app_timezone = Qnil;
  }

  if (wrapper->is_streaming) {
    /* When streaming, we will only yield rows, not return them. */
    if (wrapper->rows == Qnil) {
      wrapper->rows = rb_ary_new();
    }

    if (!wrapper->streamingComplete) {
      VALUE row;

      fields = mysql_fetch_fields(wrapper->result);

      do {
        row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool, cast, fields);
        if (row != Qnil) {
          wrapper->numberOfRows++;
          if (block != Qnil) {
            rb_yield(row);
          }
        }
      } while(row != Qnil);

      rb_mysql_result_free_result(wrapper);
      wrapper->streamingComplete = 1;

      // Check for errors, the connection might have gone out from under us
      // mysql_error returns an empty string if there is no error
      errstr = mysql_error(wrapper->client_wrapper->client);
      if (errstr[0]) {
        rb_raise(cMysql2Error, "%s", errstr);
      }
    } else {
      rb_raise(cMysql2Error, "You have already fetched all the rows for this query and streaming is true. (to reiterate you must requery).");
    }
  } else {
    if (wrapper->lastRowProcessed == 0) {
      wrapper->numberOfRows = mysql_num_rows(wrapper->result);
      if (wrapper->numberOfRows == 0) {
        wrapper->rows = rb_ary_new();
        return wrapper->rows;
      }
      wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
    } else if (!cacheRows && wrapper->lastRowProcessed == wrapper->numberOfRows) {
      mysql_data_seek(wrapper->result, 0);
      wrapper->lastRowProcessed = 0;
      wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
    }

    if (cacheRows && wrapper->lastRowProcessed == wrapper->numberOfRows) {
      /* we've already read the entire dataset from the C result into our */
      /* internal array. Lets hand that over to the user since it's ready to go */
      for (i = 0; i < wrapper->numberOfRows; i++) {
        rb_yield(rb_ary_entry(wrapper->rows, i));
      }
    } else {
      unsigned long rowsProcessed = 0;
      rowsProcessed = RARRAY_LEN(wrapper->rows);
      fields = mysql_fetch_fields(wrapper->result);

      for (i = 0; i < wrapper->numberOfRows; i++) {
        VALUE row;
        if (cacheRows && i < rowsProcessed) {
          row = rb_ary_entry(wrapper->rows, i);
        } else {
          row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool, cast, fields);
          if (cacheRows) {
            rb_ary_store(wrapper->rows, i, row);
          }
          wrapper->lastRowProcessed++;
        }

        if (row == Qnil) {
          /* we don't need the mysql C dataset around anymore, peace it */
          if (cacheRows) {
            rb_mysql_result_free_result(wrapper);
          }
          return Qnil;
        }

        if (block != Qnil) {
          rb_yield(row);
        }
      }
      if (wrapper->lastRowProcessed == wrapper->numberOfRows && cacheRows) {
        /* we don't need the mysql C dataset around anymore, peace it */
        rb_mysql_result_free_result(wrapper);
      }
    }
  }

  return wrapper->rows;
}
Beispiel #2
0
static VALUE
Game_initialize(int argc, VALUE* argv, VALUE self)
{
  if (!NIL_P(Game_s_current(rb_cGame))) {
    rb_raise(strb_GetStarRubyErrorClass(), "already run");
  }

  volatile VALUE rbWidth, rbHeight, rbOptions;
  rb_scan_args(argc, argv, "21", &rbWidth, &rbHeight, &rbOptions);
  if (NIL_P(rbOptions)) {
    rbOptions = rb_hash_new();
  } else {
    Check_Type(rbOptions, T_HASH);
  }
  Game* game;
  Data_Get_Struct(self, Game, game);

  if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER)) {
    rb_raise_sdl_error();
  }

  const int width  = NUM2INT(rbWidth);
  const int height = NUM2INT(rbHeight);

  volatile VALUE rbFps = rb_hash_aref(rbOptions, symbol_fps);
  Game_fps_eq(self, !NIL_P(rbFps) ? rbFps : INT2FIX(30));

  volatile VALUE rbTitle = rb_hash_aref(rbOptions, symbol_title);
  Game_title_eq(self, !NIL_P(rbTitle) ? rbTitle : rb_str_new2(""));

  bool cursor = false;

  volatile VALUE val;
  Check_Type(rbOptions, T_HASH);
  if (!NIL_P(val = rb_hash_aref(rbOptions, symbol_cursor))) {
    cursor = RTEST(val);
  }
  if (!NIL_P(val = rb_hash_aref(rbOptions, symbol_fullscreen))) {
    game->isFullscreen = RTEST(val);
  }
  if (!NIL_P(val = rb_hash_aref(rbOptions, symbol_window_scale))) {
    game->windowScale = NUM2INT(val);
    if (game->windowScale < 1) {
      rb_raise(rb_eArgError, "invalid window scale: %d",
               game->windowScale);
    }
  }
  if (!NIL_P(val = rb_hash_aref(rbOptions, symbol_vsync))) {
    game->isVsync = RTEST(val);
  }

  SDL_ShowCursor(cursor ? SDL_ENABLE : SDL_DISABLE);

  volatile VALUE rbScreen =
    rb_class_new_instance(2, (VALUE[]){INT2NUM(width), INT2NUM(height)},
                          strb_GetTextureClass());
  game->screen = rbScreen;

  InitializeScreen(game);

  rb_iv_set(rb_cGame, "current", self);

  return Qnil;
}
Beispiel #3
0
/*
 * 各レコードをキーで管理するテーブルを生成する。ブロックを指
 * 定すると、そのブロックに生成したテーブルが渡され、ブロック
 * を抜けると自動的にテーブルが破棄される。
 *
 * @example
 *   #無名一時テーブルを生成する。
 *   Groonga::Hash.create
 *
 *   #無名永続テーブルを生成する。
 *   Groonga::Hash.create(:path => "/tmp/hash.grn")
 *
 *   #名前付き永続テーブルを生成する。ただし、ファイル名は気にしない。
 *   Groonga::Hash.create(:name => "Bookmarks",
 *                        :persistent => true)
 *
 *   #それぞれのレコードに512バイトの値を格納できる無名一時テーブルを生成する。
 *   Groonga::Hash.create(:value => 512)
 *
 *   #キーとして文字列を使用する無名一時テーブルを生成する。
 *   Groonga::Hash.create(:key_type => Groonga::Type::SHORT_TEXT)
 *
 *   #キーとして文字列を使用する無名一時テーブルを生成する。
 *   (キーの種類を表すオブジェクトは文字列で指定。)
 *   Groonga::Hash.create(:key_type => "ShortText")
 *
 *   #キーとしてBookmarksテーブルのレコードを使用す
 *   る無名一時テーブルを生成する。
 *   bookmarks = Groonga::Hash.create(:name => "Bookmarks")
 *   Groonga::Hash.create(:key_type => bookmarks)
 *
 *   #キーとしてBookmarksテーブルのレコードを使用す
 *   #る無名一時テーブルを生成する。(テーブルは文字列で指定。)
 *   Groonga::Hash.create(:name => "Bookmarks")
 *   Groonga::Hash.create(:key_type => "Bookmarks")
 *
 *   #全文検索用のトークンをバイグラムで切り出す無名一時テーブ
 *   #ルを生成する。
 *   bookmarks = Groonga::Hash.create(:name => "Bookmarks")
 *   bookmarks.define_column("comment", "Text")
 *   terms = Groonga::Hash.create(:name => "Terms",
 *                                :default_tokenizer => "TokenBigram")
 *   terms.define_index_column("content", bookmarks,
 *                             :source => "Bookmarks.comment")
 *
 * @overload create(options={})
 *   @return [Groonga::Hash]
 *   @!macro hash.create.options
 *     @param [::Hash] options The name and value
 *       pairs. Omitted names are initialized as the default value
 *     @option options [Groonga::Context] :context (Groonga::Context.default)
 *       テーブルが利用する {Groonga::Context} 。省略すると
 *       {Groonga::Context.default} を用いる。
 *     @option options [Groonga::Context#[]] :name
 *       テーブルの名前。名前をつけると、 {Groonga::Context#[]} に名
 *       前を指定してテーブルを取得することができる。省略すると
 *       無名テーブルになり、テーブルIDでのみ取得できる。
 *     @option options [Groonga::Context#[]] :path
 *       テーブルを保存するパス。パスを指定すると永続テーブルとな
 *       り、プロセス終了後もレコードは保持される。次回起動時に
 *       {Groonga::Context#[]} で保存されたレコードを利用することが
 *       できる。省略すると一時テーブルになり、プロセスが終了する
 *       とレコードは破棄される。
 *     @option options :persistent
 *       +true+ を指定すると永続テーブルとなる。 +path+ を省略した
 *       場合は自動的にパスが付加される。 +:context+ で指定した
 *       {Groonga::Context} に結びついているデータベースが一時デー
 *       タベースの場合は例外が発生する。
 *
 *     @option options :key_normalize (false) Keys are normalized
 *       if this value is @true@.
 *
 *       @deprecated Use @:normalizer => "NormalizerAuto"@ instead.
 *
 *     @option options :key_type
 *       キーの種類を示すオブジェクトを指定する。キーの種類には型
 *       名("Int32"や"ShortText"など)または {Groonga::Type} または
 *       テーブル( {Groonga::Array} 、 {Groonga::Hash} 、
 *       {Groonga::PatriciaTrie} のどれか)を指定する。
 *
 *       {Groonga::Type} を指定した場合は、その型が示す範囲の値をキー
 *       として使用する。ただし、キーの最大サイズは4096バイトで
 *       あるため、 {Groonga::Type::TEXT} や {Groonga::Type::LONG_TEXT}
 *       は使用できない。
 *
 *       テーブルを指定した場合はレコードIDをキーとして使用する。
 *       指定したテーブルの {Groonga::Record} をキーとして使用するこ
 *       ともでき、その場合は自動的に {Groonga::Record} からレコード
 *       IDを取得する。
 *
 *       省略した場合はShortText型をキーとして使用する。この場合、
 *       4096バイトまで使用可能である。
 *     @option options :value_type
 *       値の型を指定する。省略すると値のための領域を確保しない。
 *       値を保存したい場合は必ず指定すること。
 *
 *       参考: {Groonga::Type.new}
 *     @option options [Groonga::IndexColumn] :default_tokenizer
 *       {Groonga::IndexColumn} で使用するトークナイザを指定する。
 *       デフォルトでは何も設定されていないので、テーブルに
 *       {Groonga::IndexColumn} を定義する場合は
 *       @"TokenBigram"@ などを指定する必要がある。
 *
 *     @option options [::Array<String, Groonga::Procedure>, nil]
 *       :token_filters (nil) The token filters to be used in the
 *       table.
 *
 *     @option options [Groonga::Record#n_sub_records] :sub_records
 *       +true+ を指定すると {#group} でグループ化したときに、
 *       {Groonga::Record#n_sub_records} でグループに含まれるレコー
 *       ドの件数を取得できる。
 *
 *     @option options [String, Groonga::Procedure, nil] :normalizer
 *       The normalizer that is used by {Groonga::IndexColumn}. You
 *       can specify this by normalizer name as String such as
 *       @"NormalizerAuto"@ or normalizer object.
 *
 *   @!macro hash.create.options
 * @overload create(options={})
 *   @yield [table]
 *   @!macro hash.create.options
 */
static VALUE
rb_grn_hash_s_create (int argc, VALUE *argv, VALUE klass)
{
    grn_ctx *context;
    grn_obj *key_type = NULL, *value_type = NULL, *table;
    const char *name = NULL, *path = NULL;
    unsigned name_size = 0;
    grn_obj_flags flags = GRN_OBJ_TABLE_HASH_KEY;
    VALUE rb_table;
    VALUE options, rb_context, rb_name, rb_path, rb_persistent;
    VALUE rb_key_normalize, rb_key_type, rb_value_type, rb_default_tokenizer;
    VALUE rb_token_filters;
    VALUE rb_sub_records;
    VALUE rb_normalizer;

    rb_scan_args(argc, argv, "01", &options);

    rb_grn_scan_options(options,
                        "context", &rb_context,
                        "name", &rb_name,
                        "path", &rb_path,
                        "persistent", &rb_persistent,
                        "key_normalize", &rb_key_normalize,
                        "key_type", &rb_key_type,
                        "value_type", &rb_value_type,
                        "default_tokenizer", &rb_default_tokenizer,
                        "token_filters", &rb_token_filters,
                        "sub_records", &rb_sub_records,
                        "normalizer", &rb_normalizer,
                        NULL);

    context = rb_grn_context_ensure(&rb_context);

    if (!NIL_P(rb_name)) {
        name = StringValuePtr(rb_name);
        name_size = RSTRING_LEN(rb_name);
        flags |= GRN_OBJ_PERSISTENT;
    }

    if (!NIL_P(rb_path)) {
        path = StringValueCStr(rb_path);
        flags |= GRN_OBJ_PERSISTENT;
    }

    if (RVAL2CBOOL(rb_persistent))
        flags |= GRN_OBJ_PERSISTENT;

    if (RVAL2CBOOL(rb_key_normalize))
        flags |= GRN_OBJ_KEY_NORMALIZE;

    if (NIL_P(rb_key_type)) {
        key_type = grn_ctx_at(context, GRN_DB_SHORT_TEXT);
    } else {
        key_type = RVAL2GRNOBJECT(rb_key_type, &context);
    }

    if (!NIL_P(rb_value_type))
        value_type = RVAL2GRNOBJECT(rb_value_type, &context);

    if (RVAL2CBOOL(rb_sub_records))
        flags |= GRN_OBJ_WITH_SUBREC;

    table = grn_table_create(context, name, name_size, path,
                             flags, key_type, value_type);
    if (!table)
        rb_grn_context_check(context, rb_ary_new_from_values(argc, argv));
    rb_table = GRNOBJECT2RVAL(klass, context, table, GRN_TRUE);

    if (!NIL_P(rb_default_tokenizer))
        rb_funcall(rb_table, rb_intern("default_tokenizer="), 1,
                   rb_default_tokenizer);
    if (!NIL_P(rb_token_filters))
        rb_funcall(rb_table, rb_intern("token_filters="), 1,
                   rb_token_filters);
    if (!NIL_P(rb_normalizer))
        rb_funcall(rb_table, rb_intern("normalizer="), 1,
                   rb_normalizer);

    if (rb_block_given_p())
        return rb_ensure(rb_yield, rb_table, rb_grn_object_close, rb_table);
    else
        return rb_table;
}
Beispiel #4
0
static VALUE
range_step(VALUE range, SEL sel, int argc, VALUE *argv)
{
    VALUE b, e, step, tmp;

    RETURN_ENUMERATOR(range, argc, argv);

    b = RANGE_BEG(range);
    e = RANGE_END(range);
    if (argc == 0) {
	step = INT2FIX(1);
    }
    else {
	rb_scan_args(argc, argv, "01", &step);
	if (!rb_obj_is_kind_of(step, rb_cNumeric)) {
	    step = rb_to_int(step);
	}
	VALUE zero = INT2FIX(0);
	if (rb_vm_call(step, selLT, 1, &zero)) {
	    rb_raise(rb_eArgError, "step can't be negative");
	}
	else if (!rb_vm_call(step, selGT, 1, &zero)) {
	    rb_raise(rb_eArgError, "step can't be 0");
	}
    }

    if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */
	long end = FIX2LONG(e);
	long i, unit = FIX2LONG(step);

	if (!EXCL(range))
	    end += 1;
	i = FIX2LONG(b);	
	while (i < end) {
	    rb_yield(LONG2NUM(i));
	    RETURN_IF_BROKEN();
	    if (i + unit < i) break;
	    i += unit;
	}

    }
    else if (SYMBOL_P(b) && SYMBOL_P(e)) { /* symbols are special */
	VALUE args[2];
	VALUE iter[2];

	args[0] = rb_sym_to_s(e);
	args[1] = EXCL(range) ? Qtrue : Qfalse;
	iter[0] = INT2FIX(1);
	iter[1] = step;
	rb_objc_block_call(rb_sym_to_s(b), selUpto, 2, args, sym_step_i, (VALUE)iter);
    }
    else if (ruby_float_step(b, e, step, EXCL(range))) {
	/* done */
    }
    else if (rb_obj_is_kind_of(b, rb_cNumeric) ||
	     !NIL_P(rb_check_to_integer(b, "to_int")) ||
	     !NIL_P(rb_check_to_integer(e, "to_int"))) {
	SEL op = EXCL(range) ? selLT : selLE;
	VALUE v = b;
	int i = 0;

	while (RTEST(rb_vm_call(v, op, 1, &e))) {
	    rb_yield(v);
	    RETURN_IF_BROKEN();
	    i++;
	    VALUE tmp = rb_vm_call(INT2NUM(i), selMULT, 1, &step);
	    v = rb_vm_call(b, selPLUS, 1, &tmp);
	}
    }
    else {
	tmp = rb_check_string_type(b);

	if (!NIL_P(tmp)) {
	    VALUE args[2], iter[2];

	    b = tmp;
	    args[0] = e;
	    args[1] = EXCL(range) ? Qtrue : Qfalse;
	    iter[0] = INT2FIX(1);
	    iter[1] = step;
	    rb_objc_block_call(b, selUpto, 2, args, step_i, (VALUE)iter);
	}
	else {
	    VALUE args[2];

	    if (!discrete_object_p(b)) {
		rb_raise(rb_eTypeError, "can't iterate from %s",
			 rb_obj_classname(b));
	    }
	    args[0] = INT2FIX(1);
	    args[1] = step;
	    return range_each_func(range, step_i, args);
	}
    }
    return range;
}
Beispiel #5
0
static VALUE
ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
{
    SSL *ssl;
    int ilen, nread = 0;
    VALUE len, str;
    rb_io_t *fptr;

    rb_scan_args(argc, argv, "11", &len, &str);
    ilen = NUM2INT(len);
    if(NIL_P(str)) {
	str = rb_bstr_new();
    }
    else{
        StringValue(str);
	rb_str_modify(str);
	str = rb_str_bstr(str);
    }
    rb_bstr_resize(str, ilen);
    if(ilen == 0) return str;

    Data_Get_Struct(self, SSL, ssl);
    GetOpenFile(ossl_ssl_get_io(self), fptr);
    if (ssl) {
	if(!nonblock && SSL_pending(ssl) <= 0)
	    rb_thread_wait_fd(FPTR_TO_FD(fptr));
	for (;;){
	    nread = SSL_read(ssl, rb_bstr_bytes(str),
		    rb_bstr_length(str));
	    switch(ssl_get_error(ssl, nread)){
	    case SSL_ERROR_NONE:
		goto end;
	    case SSL_ERROR_ZERO_RETURN:
		rb_eof_error();
	    case SSL_ERROR_WANT_WRITE:
                write_would_block(nonblock);
                rb_io_wait_writable(FPTR_TO_FD(fptr));
                continue;
	    case SSL_ERROR_WANT_READ:
                read_would_block(nonblock);
                rb_io_wait_readable(FPTR_TO_FD(fptr));
		continue;
	    case SSL_ERROR_SYSCALL:
		if(ERR_peek_error() == 0 && nread == 0) rb_eof_error();
		rb_sys_fail(0);
	    default:
		ossl_raise(eSSLError, "SSL_read:");
	    }
        }
    }
    else {
        ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
        rb_warning("SSL session is not started yet.");
        return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str);
    }

  end:
    rb_bstr_resize(str, nread);
    OBJ_TAINT(str);

    return str;
}
Beispiel #6
0
static VALUE
count_objects_size(int argc, VALUE *argv, VALUE os)
{
    size_t counts[T_MASK+1];
    size_t total = 0;
    size_t i;
    VALUE hash;

    if (rb_scan_args(argc, argv, "01", &hash) == 1) {
        if (TYPE(hash) != T_HASH)
            rb_raise(rb_eTypeError, "non-hash given");
    }

    for (i = 0; i <= T_MASK; i++) {
	counts[i] = 0;
    }

    rb_objspace_each_objects(cos_i, &counts[0]);

    if (hash == Qnil) {
        hash = rb_hash_new();
    }
    else if (!RHASH_EMPTY_P(hash)) {
        st_foreach(RHASH_TBL(hash), set_zero_i, hash);
    }

    for (i = 0; i <= T_MASK; i++) {
	if (counts[i]) {
	    VALUE type;
	    switch (i) {
#define COUNT_TYPE(t) case t: type = ID2SYM(rb_intern(#t)); break;
		COUNT_TYPE(T_NONE);
		COUNT_TYPE(T_OBJECT);
		COUNT_TYPE(T_CLASS);
		COUNT_TYPE(T_MODULE);
		COUNT_TYPE(T_FLOAT);
		COUNT_TYPE(T_STRING);
		COUNT_TYPE(T_REGEXP);
		COUNT_TYPE(T_ARRAY);
		COUNT_TYPE(T_HASH);
		COUNT_TYPE(T_STRUCT);
		COUNT_TYPE(T_BIGNUM);
		COUNT_TYPE(T_FILE);
		COUNT_TYPE(T_DATA);
		COUNT_TYPE(T_MATCH);
		COUNT_TYPE(T_COMPLEX);
		COUNT_TYPE(T_RATIONAL);
		COUNT_TYPE(T_NIL);
		COUNT_TYPE(T_TRUE);
		COUNT_TYPE(T_FALSE);
		COUNT_TYPE(T_SYMBOL);
		COUNT_TYPE(T_FIXNUM);
		COUNT_TYPE(T_UNDEF);
		COUNT_TYPE(T_NODE);
		COUNT_TYPE(T_ICLASS);
		COUNT_TYPE(T_ZOMBIE);
#undef COUNT_TYPE
	      default: type = INT2NUM(i); break;
	    }
	    total += counts[i];
	    rb_hash_aset(hash, type, SIZET2NUM(counts[i]));
	}
    }
    rb_hash_aset(hash, ID2SYM(rb_intern("TOTAL")), SIZET2NUM(total));
    return hash;
}
Beispiel #7
0
/* 
 *  call-seq:
 *     QueryParser.new(options = {}) -> QueryParser
 *
 *  Create a new QueryParser. The QueryParser is used to convert string
 *  queries into Query objects. The options are;
 *
 *  === Options
 *
 *  :default_field::       Default: "*" (all fields). The default field to
 *                         search when no field is specified in the search
 *                         string. It can also be an array of fields.
 *  :analyzer::            Default: StandardAnalyzer. Analyzer used by the
 *                         query parser to parse query terms
 *  :wild_card_downcase::  Default: true. Specifies whether wild-card queries
 *                         and range queries should be downcased or not since
 *                         they are not passed through the parser
 *  :fields::              Default: []. Lets the query parser know what
 *                         fields are available for searching, particularly
 *                         when the "*" is specified as the search field
 *  :tokenized_fields::    Default: :fields. Lets the query parser know which
 *                         fields are tokenized so it knows which fields to
 *                         run the analyzer over.
 *  :validate_fields::     Default: false. Set to true if you want an
 *                         exception to be raised if there is an attempt to
 *                         search a non-existent field
 *  :or_default::          Default: true. Use "OR" as the default boolean
 *                         operator
 *  :default_slop::        Default: 0. Default slop to use in PhraseQuery
 *  :handle_parse_errors:: Default: true. QueryParser will quietly handle all
 *                         parsing errors internally. If you'd like to handle
 *                         them yourself, set this parameter to false.
 *  :clean_string::        Default: true. QueryParser will do a quick
 *                         once-over the query string make sure that quotes
 *                         and brackets match up and special characters are
 *                         escaped
 *  :max_clauses::         Default: 512. the maximum number of clauses
 *                         allowed in boolean queries and the maximum number
 *                         of terms allowed in multi, prefix, wild-card or
 *                         fuzzy queries when those queries are generated by
 *                         rewriting other queries
 */                   
static VALUE
frt_qp_init(int argc, VALUE *argv, VALUE self)
{
    VALUE roptions;
    VALUE rval;
    Analyzer *analyzer = NULL;
    bool has_options = false;

    HashSet *all_fields = NULL;
    HashSet *tkz_fields = NULL;
    HashSet *def_fields = NULL;
    QParser *qp;

    if (rb_scan_args(argc, argv, "01", &roptions) > 0) {
        if (TYPE(roptions) == T_HASH) {
            has_options = true;
            if (Qnil != (rval = rb_hash_aref(roptions, sym_default_field))) {
                def_fields = frt_get_fields(rval);
            }
            if (Qnil != (rval = rb_hash_aref(roptions, sym_analyzer))) {
                analyzer = frt_get_cwrapped_analyzer(rval);
            }
            if (Qnil != (rval = rb_hash_aref(roptions, sym_all_fields))) {
                all_fields = frt_get_fields(rval);
            }
            if (Qnil != (rval = rb_hash_aref(roptions, sym_fields))) {
                all_fields = frt_get_fields(rval);
            }
            if (Qnil != (rval = rb_hash_aref(roptions, sym_tkz_fields))) {
                tkz_fields = frt_get_fields(rval);
            }
        } else {
            def_fields = frt_get_fields(roptions);
        }
    }
    if (all_fields == NULL) {
        all_fields = hs_new_str(&free);
    }

    if (!analyzer) {
        analyzer = mb_standard_analyzer_new(true);
    }

    qp = qp_new(all_fields, def_fields, tkz_fields, analyzer);
    qp->allow_any_fields = true;
    qp->clean_str = true;
    qp->handle_parse_errors = true;
    /* handle options */
    if (argc > 0) {
        if (Qnil != (rval = rb_hash_aref(roptions, sym_handle_parse_errors))) {
            qp->handle_parse_errors = RTEST(rval);
        }
        if (Qnil != (rval = rb_hash_aref(roptions, sym_validate_fields))) {
            qp->allow_any_fields = !RTEST(rval);
        }
        if (Qnil != (rval = rb_hash_aref(roptions, sym_wild_card_downcase))) {
            qp->wild_lower = RTEST(rval);
        }
        if (Qnil != (rval = rb_hash_aref(roptions, sym_or_default))) {
            qp->or_default = RTEST(rval);
        }
        if (Qnil != (rval = rb_hash_aref(roptions, sym_default_slop))) {
            qp->def_slop = FIX2INT(rval);
        }
        if (Qnil != (rval = rb_hash_aref(roptions, sym_clean_string))) {
            qp->clean_str = RTEST(rval);
        }
        if (Qnil != (rval = rb_hash_aref(roptions, sym_max_clauses))) {
            qp->max_clauses = FIX2INT(rval);
        }
    }
    Frt_Wrap_Struct(self, frt_qp_mark, frt_qp_free, qp);
    object_add(qp, self);
    return self;
}
    VALUE
cb_bucket_observe(int argc, VALUE *argv, VALUE self)
{
    struct bucket_st *bucket = DATA_PTR(self);
    struct context_st *ctx;
    VALUE args, rv, proc, exc;
    lcb_error_t err;
    struct params_st params;

    if (bucket->handle == NULL) {
        rb_raise(eConnectError, "closed connection");
    }
    rb_scan_args(argc, argv, "0*&", &args, &proc);
    if (!bucket->async && proc != Qnil) {
        rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
    }
    memset(&params, 0, sizeof(struct params_st));
    params.type = cmd_observe;
    params.bucket = bucket;
    cb_params_build(&params, RARRAY_LEN(args), args);
    ctx = xcalloc(1, sizeof(struct context_st));
    if (ctx == NULL) {
        rb_raise(eClientNoMemoryError, "failed to allocate memory for context");
    }
    ctx->proc = cb_gc_protect(bucket, proc);
    ctx->bucket = bucket;
    rv = rb_hash_new();
    ctx->rv = &rv;
    ctx->exception = Qnil;
    ctx->nqueries = params.cmd.observe.num;
    err = lcb_observe(bucket->handle, (const void *)ctx,
            params.cmd.observe.num, params.cmd.observe.ptr);
    cb_params_destroy(&params);
    exc = cb_check_error(err, "failed to schedule observe request", Qnil);
    if (exc != Qnil) {
        xfree(ctx);
        rb_exc_raise(exc);
    }
    bucket->nbytes += params.npayload;
    if (bucket->async) {
        maybe_do_loop(bucket);
        return Qnil;
    } else {
        if (ctx->nqueries > 0) {
            /* we have some operations pending */
            lcb_wait(bucket->handle);
        }
        exc = ctx->exception;
        xfree(ctx);
        if (exc != Qnil) {
            cb_gc_unprotect(bucket, exc);
            rb_exc_raise(exc);
        }
        if (bucket->exception != Qnil) {
            rb_exc_raise(bucket->exception);
        }
        if (params.cmd.observe.num > 1 || params.cmd.observe.array) {
            return rv;  /* return as a hash {key => {}, ...} */
        } else {
            VALUE vv = Qnil;
            rb_hash_foreach(rv, cb_first_value_i, (VALUE)&vv);
            return vv;  /* return first value */
        }
    }
}
Beispiel #9
0
static VALUE each(int argc, VALUE *argv, VALUE self)
{
    struct readerdata *reader;
    png_infop winfo;
    png_structp wpng;
    VALUE opts;
    int cmp, state;
    struct each_args args;
    uint32_t i, height, width;
    png_byte ctype;
    unsigned char **scanlines;
    size_t row_bytes;

    rb_scan_args(argc, argv, "01", &opts);

    Data_Get_Struct(self, struct readerdata, reader);

    raise_if_locked(reader);
    reader->locked = 1;

    wpng = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
                                   (png_error_ptr)error, (png_error_ptr)warning);
    winfo = png_create_info_struct(wpng);
    png_set_write_fn(wpng, 0, write_data_fn, flush_data_fn);

    cmp = png_get_channels(reader->png, reader->info);
    ctype = png_get_color_type(reader->png, reader->info);

    png_set_IHDR(wpng, winfo, reader->scale_width, reader->scale_height, 8,
                 ctype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
                 PNG_FILTER_TYPE_DEFAULT);

    width = png_get_image_width(reader->png, reader->info);
    height = png_get_image_height(reader->png, reader->info);
    row_bytes = png_get_rowbytes(reader->png, reader->info);

    args.reader = reader;
    args.wpng = wpng;
    args.winfo = winfo;
    args.inwidthbuf = malloc(row_bytes);
    args.outwidthbuf = malloc(reader->scale_width * cmp);

    xscaler_init(&args.xs, width, reader->scale_width, cmp, 0);

    if (png_get_interlace_type(reader->png, reader->info) == PNG_INTERLACE_NONE) {
        yscaler_init(&args.ys, height, reader->scale_height,
                     reader->scale_width * cmp);
        rb_protect((VALUE(*)(VALUE))each_interlace_none, (VALUE)&args, &state);
        yscaler_free(&args.ys);
    } else {
        scanlines = malloc(height * sizeof(unsigned char *));
        for (i=0; i<height; i++) {
            scanlines[i] = malloc(row_bytes);
        }

        args.scanlines = scanlines;
        rb_protect((VALUE(*)(VALUE))each_interlace, (VALUE)&args, &state);

        for (i=0; i<height; i++) {
            free(scanlines[i]);
        }
        free(scanlines);
    }

    xscaler_free(&args.xs);
    free(args.inwidthbuf);
    free(args.outwidthbuf);
    png_destroy_write_struct(&wpng, &winfo);

    if (state) {
        rb_jump_tag(state);
    }

    return self;
}
Beispiel #10
0
static VALUE rb_redcarpet_html_init(int argc, VALUE *argv, VALUE self)
{
    struct rb_redcarpet_rndr *rndr;
    unsigned int render_flags = 0;
    VALUE hash, link_attr = Qnil;

    Data_Get_Struct(self, struct rb_redcarpet_rndr, rndr);

    if (rb_scan_args(argc, argv, "01", &hash) == 1) {
        Check_Type(hash, T_HASH);

        /* escape_html */
        if (rb_hash_aref(hash, CSTR2SYM("escape_html")) == Qtrue)
            render_flags |= HTML_ESCAPE;

        /* filter_html */
        if (rb_hash_aref(hash, CSTR2SYM("filter_html")) == Qtrue)
            render_flags |= HTML_SKIP_HTML;

        /* no_image */
        if (rb_hash_aref(hash, CSTR2SYM("no_images")) == Qtrue)
            render_flags |= HTML_SKIP_IMAGES;

        /* no_links */
        if (rb_hash_aref(hash, CSTR2SYM("no_links")) == Qtrue)
            render_flags |= HTML_SKIP_LINKS;

        /* prettify */
        if (rb_hash_aref(hash, CSTR2SYM("prettify")) == Qtrue)
            render_flags |= HTML_PRETTIFY;

        /* filter_style */
        if (rb_hash_aref(hash, CSTR2SYM("no_styles")) == Qtrue)
            render_flags |= HTML_SKIP_STYLE;

        /* safelink */
        if (rb_hash_aref(hash, CSTR2SYM("safe_links_only")) == Qtrue)
            render_flags |= HTML_SAFELINK;

        if (rb_hash_aref(hash, CSTR2SYM("with_toc_data")) == Qtrue)
            render_flags |= HTML_TOC;

        if (rb_hash_aref(hash, CSTR2SYM("hard_wrap")) == Qtrue)
            render_flags |= HTML_HARD_WRAP;

        if (rb_hash_aref(hash, CSTR2SYM("xhtml")) == Qtrue)
            render_flags |= HTML_USE_XHTML;

        link_attr = rb_hash_aref(hash, CSTR2SYM("link_attributes"));
    }

    sdhtml_renderer(&rndr->callbacks, (struct html_renderopt *)&rndr->options.html, render_flags);
    rb_redcarpet__overload(self, rb_cRenderHTML);

    if (!NIL_P(link_attr)) {
        rndr->options.link_attributes = link_attr;
        rndr->options.html.link_attributes = &rndr_link_attributes;
    }

    return Qnil;
}
Beispiel #11
0
static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
  VALUE defaults, opts, block;
  ID db_timezone, app_timezone, dbTz, appTz;
  mysql2_result_wrapper * wrapper;
  unsigned long i;
  int symbolizeKeys = 0, asArray = 0, castBool = 0, cacheRows = 1, cast = 1, streaming = 0;
  MYSQL_FIELD * fields = NULL;

  GetMysql2Result(self, wrapper);

  defaults = rb_iv_get(self, "@query_options");
  Check_Type(defaults, T_HASH);
  if (rb_scan_args(argc, argv, "01&", &opts, &block) == 1) {
    opts = rb_funcall(defaults, intern_merge, 1, opts);
  } else {
    opts = defaults;
  }

  if (rb_hash_aref(opts, sym_symbolize_keys) == Qtrue) {
    symbolizeKeys = 1;
  }

  if (rb_hash_aref(opts, sym_as) == sym_array) {
    asArray = 1;
  }

  if (rb_hash_aref(opts, sym_cast_booleans) == Qtrue) {
    castBool = 1;
  }

  if (rb_hash_aref(opts, sym_cache_rows) == Qfalse) {
    cacheRows = 0;
  }

  if (rb_hash_aref(opts, sym_cast) == Qfalse) {
    cast = 0;
  }

  if(rb_hash_aref(opts, sym_stream) == Qtrue) {
    streaming = 1;
  }

  if(streaming && cacheRows) {
    rb_warn("cacheRows is ignored if streaming is true");
  }

  dbTz = rb_hash_aref(opts, sym_database_timezone);
  if (dbTz == sym_local) {
    db_timezone = intern_local;
  } else if (dbTz == sym_utc) {
    db_timezone = intern_utc;
  } else {
    if (!NIL_P(dbTz)) {
      rb_warn(":database_timezone option must be :utc or :local - defaulting to :local");
    }
    db_timezone = intern_local;
  }

  appTz = rb_hash_aref(opts, sym_application_timezone);
  if (appTz == sym_local) {
    app_timezone = intern_local;
  } else if (appTz == sym_utc) {
    app_timezone = intern_utc;
  } else {
    app_timezone = Qnil;
  }

  if (wrapper->lastRowProcessed == 0) {
    if(streaming) {
      /* We can't get number of rows if we're streaming, */
      /* until we've finished fetching all rows */
      wrapper->numberOfRows = 0;
      wrapper->rows = rb_ary_new();
    } else {
      wrapper->numberOfRows = mysql_num_rows(wrapper->result);
      if (wrapper->numberOfRows == 0) {
        wrapper->rows = rb_ary_new();
        return wrapper->rows;
      }
      wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
    }
  }

  if (streaming) {
    if(!wrapper->streamingComplete) {
      VALUE row;

      fields = mysql_fetch_fields(wrapper->result);

      do {
        row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool, cast, fields);

        if (block != Qnil && row != Qnil) {
          rb_yield(row);
          wrapper->lastRowProcessed++;
        }
      } while(row != Qnil);

      rb_mysql_result_free_result(wrapper);

      wrapper->numberOfRows = wrapper->lastRowProcessed;
      wrapper->streamingComplete = 1;
    } else {
      rb_raise(cMysql2Error, "You have already fetched all the rows for this query and streaming is true. (to reiterate you must requery).");
    }
  } else {
    if (cacheRows && wrapper->lastRowProcessed == wrapper->numberOfRows) {
      /* we've already read the entire dataset from the C result into our */
      /* internal array. Lets hand that over to the user since it's ready to go */
      for (i = 0; i < wrapper->numberOfRows; i++) {
        rb_yield(rb_ary_entry(wrapper->rows, i));
      }
    } else {
      unsigned long rowsProcessed = 0;
      rowsProcessed = RARRAY_LEN(wrapper->rows);
      fields = mysql_fetch_fields(wrapper->result);

      for (i = 0; i < wrapper->numberOfRows; i++) {
        VALUE row;
        if (cacheRows && i < rowsProcessed) {
          row = rb_ary_entry(wrapper->rows, i);
        } else {
          row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool, cast, fields);
          if (cacheRows) {
            rb_ary_store(wrapper->rows, i, row);
          }
          wrapper->lastRowProcessed++;
        }

        if (row == Qnil) {
          /* we don't need the mysql C dataset around anymore, peace it */
          rb_mysql_result_free_result(wrapper);
          return Qnil;
        }

        if (block != Qnil) {
          rb_yield(row);
        }
      }
      if (wrapper->lastRowProcessed == wrapper->numberOfRows) {
        /* we don't need the mysql C dataset around anymore, peace it */
        rb_mysql_result_free_result(wrapper);
      }
    }
  }

  return wrapper->rows;
}
Beispiel #12
0
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;
}
Beispiel #13
0
static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
  VALUE hostPort=Qnil;
  VALUE options=Qnil;

  rb_scan_args(argc, argv, "11", &hostPort, &options);

  if (NIL_P(options)) {
    options = rb_hash_new();
  } else {
    Check_Type(options, T_HASH);
  }

  Check_Type(hostPort, T_STRING);

  // Look up :zkc_log_level
  VALUE log_level = rb_hash_aref(options, ID2SYM(rb_intern("zkc_log_level")));
  if (NIL_P(log_level)) {
    zoo_set_debug_level(0); // no log messages
  } else {
    Check_Type(log_level, T_FIXNUM);
    zoo_set_debug_level(FIX2INT(log_level));
  }

  volatile VALUE data;
  zkrb_instance_data_t *zk_local_ctx;
  data = Data_Make_Struct(CZookeeper, zkrb_instance_data_t, 0, free_zkrb_instance_data, zk_local_ctx);

  zk_local_ctx->queue = zkrb_queue_alloc();

  if (zk_local_ctx->queue == NULL)
    rb_raise(rb_eRuntimeError, "could not allocate zkrb queue!");

  zoo_deterministic_conn_order(0);

  zkrb_calling_context *ctx =
    zkrb_calling_context_alloc(ZKRB_GLOBAL_REQ, zk_local_ctx->queue);

  zk_local_ctx->object_id = FIX2LONG(rb_obj_id(self));

  zk_local_ctx->zh =
      zookeeper_init(
          RSTRING_PTR(hostPort),        // const char *host
          zkrb_state_callback,          // watcher_fn
          session_timeout_msec(self),   // recv_timeout
          &zk_local_ctx->myid,          // cilentid_t
          ctx,                          // void *context
          0);                           // flags

  zkrb_debug("method_zkrb_init, zk_local_ctx: %p, zh: %p, queue: %p, calling_ctx: %p",
      zk_local_ctx, zk_local_ctx->zh, zk_local_ctx->queue, ctx);

  if (!zk_local_ctx->zh) {
    rb_raise(rb_eRuntimeError, "error connecting to zookeeper: %d", errno);
  }

  zk_local_ctx->orig_pid = getpid();

  rb_iv_set(self, "@_data", data);
  rb_funcall(self, rb_intern("zkc_set_running_and_notify!"), 0);

  return Qnil;
}
Beispiel #14
0
/*
 * call-seq: configure(opts)
 *
 * Configure this State instance with the Hash _opts_, and return
 * itself.
 */
static inline VALUE cState_configure(VALUE self, VALUE opts)
{
    VALUE tmp;
    GET_STATE(self);
    tmp = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
    if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h");
    if (NIL_P(tmp)) {
        rb_raise(rb_eArgError, "opts has to be hash like or convertable into a hash");
    }
    opts = tmp;
    tmp = rb_hash_aref(opts, ID2SYM(i_indent));
    if (RTEST(tmp)) {
        Check_Type(tmp, T_STRING);
        state->indent = tmp;
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_space));
    if (RTEST(tmp)) {
        Check_Type(tmp, T_STRING);
        state->space = tmp;
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_space_before));
    if (RTEST(tmp)) {
        Check_Type(tmp, T_STRING);
        state->space_before = tmp;
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_array_nl));
    if (RTEST(tmp)) {
        Check_Type(tmp, T_STRING);
        state->array_nl = tmp;
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_object_nl));
    if (RTEST(tmp)) {
        Check_Type(tmp, T_STRING);
        state->object_nl = tmp;
    }
    tmp = ID2SYM(i_check_circular);

#if WITH_OBJC
    if (CFDictionaryGetValueIfPresent((CFDictionaryRef)opts, (const void *)RB2OC(tmp), 0)) {
#else
    if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
#endif
        tmp = rb_hash_aref(opts, ID2SYM(i_check_circular));
        state->check_circular = RTEST(tmp);
    } else {
        state->check_circular = 1;
    }
    tmp = ID2SYM(i_max_nesting);
    state->max_nesting = 19;
#if WITH_OBJC
    if (CFDictionaryGetValueIfPresent((CFDictionaryRef)opts, (const void *)RB2OC(tmp), 0)) {
#else
    if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
#endif
        VALUE max_nesting = rb_hash_aref(opts, tmp);
        if (RTEST(max_nesting)) {
            Check_Type(max_nesting, T_FIXNUM);
            state->max_nesting = FIX2LONG(max_nesting);
        } else {
            state->max_nesting = 0;
        }
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan));
    state->allow_nan = RTEST(tmp);
    return self;
}

/*
 * call-seq: to_h
 *
 * Returns the configuration instance variables as a hash, that can be
 * passed to the configure method.
 */
static VALUE cState_to_h(VALUE self)
{
    VALUE result = rb_hash_new();
    GET_STATE(self);
    rb_hash_aset(result, ID2SYM(i_indent), state->indent);
    rb_hash_aset(result, ID2SYM(i_space), state->space);
    rb_hash_aset(result, ID2SYM(i_space_before), state->space_before);
    rb_hash_aset(result, ID2SYM(i_object_nl), state->object_nl);
    rb_hash_aset(result, ID2SYM(i_array_nl), state->array_nl);
    rb_hash_aset(result, ID2SYM(i_check_circular), state->check_circular ? Qtrue : Qfalse);
    rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
    rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
    return result;
}


/*
 * call-seq: new(opts = {})
 *
 * Instantiates a new State object, configured by _opts_.
 *
 * _opts_ can have the following keys:
 *
 * * *indent*: a string used to indent levels (default: ''),
 * * *space*: a string that is put after, a : or , delimiter (default: ''),
 * * *space_before*: a string that is put before a : pair delimiter (default: ''),
 * * *object_nl*: a string that is put at the end of a JSON object (default: ''), 
 * * *array_nl*: a string that is put at the end of a JSON array (default: ''),
 * * *check_circular*: true if checking for circular data structures
 *   should be done, false (the default) otherwise.
 * * *allow_nan*: true if NaN, Infinity, and -Infinity should be
 *   generated, otherwise an exception is thrown, if these values are
 *   encountered. This options defaults to false.
 */
static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE opts;
    GET_STATE(self);

    rb_scan_args(argc, argv, "01", &opts);
    state->indent = rb_str_new2("");
    state->space = rb_str_new2("");
    state->space_before = rb_str_new2("");
    state->array_nl = rb_str_new2("");
    state->object_nl = rb_str_new2("");
    if (NIL_P(opts)) {
        state->check_circular = 1;
        state->allow_nan = 0;
        state->max_nesting = 19;
    } else {
        cState_configure(self, opts);
    }
    state->seen = rb_hash_new();
    state->memo = Qnil;
    state->depth = INT2FIX(0);
    return self;
}
Beispiel #15
0
/*
 * call-seq:
 *   Watchcat.new([options])                      => watchcat_obj
 *   Watchcat.new([options]) { |watchcat| block } => watchcat_obj
 *
 * Create a new Watchcat object. The parameter hash may have the following
 * symbols:
 * +timeout+::
 *   If watchcatd doesn't receive a heartbeat after this period (in seconds),
 *   it will signal the process. (default: 60)
 * +signal+::
 *   Defines which signal will be sent to the process after the timeout
 *   expires. Can be a string like 'HUP' or 'SIGHUP' or an integer like 9.
 *   (default: 9)
 * +info+::
 *   Should be a string which is added to the log generated by watchcatd
 *   when it signals a process. (default: nil)
 * +device+::
 *   The watchcat device. (default: +/var/run/watchcat.socket+). Use for
 *   debugging purposes.
 *
 * If a block is given, the Watchcat object will be yielded and automatically
 * closed on block termination.
 */
static VALUE
rb_wcat_open(int argc, VALUE *argv, VALUE self)
{
    int sock, timeout, signal;
    char *signame;
    const char *info;
    VALUE opt, vtimeout, vsignal, vinfo, vdevice, vsiglist, mSignal;

    rb_scan_args(argc, argv, "01", &opt);
    if (NIL_P(opt)) {
        sock = cat_open();
        if (sock == -1)
            rb_sys_fail("cat_open");
        rb_iv_set(self, "@sock", INT2NUM(sock));
        return(self);
    }

    /* Defaults. */
    timeout = 60;
    signal = SIGKILL;
    info = NULL;
    
    vtimeout = rb_hash_aref(opt, SYMBOL("timeout"));
    if (!NIL_P(vtimeout)) {
        if (FIXNUM_P(vtimeout))
            timeout = NUM2INT(vtimeout);
        else
            rb_raise(rb_eArgError, "timeout must be an integer");
    }

    vsignal = rb_hash_aref(opt, SYMBOL("signal"));
    if (!NIL_P(vsignal)) {
        switch (TYPE(vsignal)) {
        case T_FIXNUM:
            signal = NUM2INT(vsignal);
            break;
        case T_STRING:
            signame = StringValuePtr(vsignal);
            if (strncmp("SIG", signame, 3) == 0) {
                signame += 3;
                vsignal = rb_str_new2(signame);
            }
            mSignal = rb_const_get(rb_cObject, rb_intern("Signal"));
            vsiglist = rb_funcall(mSignal, rb_intern("list"), 0);
            vsignal = rb_hash_aref(vsiglist, vsignal);
            if (NIL_P(vsignal))
                rb_raise(rb_eArgError, "invalid signal name");
            else
                signal = NUM2INT(vsignal);
            break;
        default:
            rb_raise(rb_eArgError, "signal must be an integer or a string");
        }
    }

    vinfo = rb_hash_aref(opt, SYMBOL("info"));
    if (!NIL_P(vinfo))
        info = StringValuePtr(vinfo);

    vdevice = rb_hash_aref(opt, SYMBOL("device"));
    if (!NIL_P(vdevice))
        cat_set_device(StringValuePtr(vdevice));

    sock = cat_open1(timeout, signal, info);
    if (sock == -1)
        rb_sys_fail("cat_open");

    rb_iv_set(self, "@sock", INT2NUM(sock));

    if (rb_block_given_p())
        rb_ensure(rb_yield, self, (void *)cat_close, sock);

    return(self);
}
Beispiel #16
0
static VALUE array_spec_rb_ary_aref(int argc, VALUE *argv, VALUE self) {
  VALUE ary, args;
  rb_scan_args(argc, argv, "1*", &ary, &args);
  return rb_ary_aref((int)RARRAY_LEN(args), RARRAY_PTR(args), ary);
}
Beispiel #17
0
VALUE rb_blas_xscal_mod(int argc, VALUE *argv, VALUE self)
{
  Matrix *dx;
  int incx;
  int n;
  float da_f;
  double da_d;
  float da_c[2];
  double da_z[2];
  //char error_msg[64];
  VALUE da_value,  n_value,  incx_value;
  
  rb_scan_args(argc, argv, "12", &da_value, &incx_value, &n_value);
  
  Data_Get_Struct(self, Matrix, dx);

  if(incx_value == Qnil)
    incx = 1;
  else
    incx = NUM2INT(incx_value);
  
  if(n_value == Qnil)
    n = dx->nrows;
  else
    n = NUM2INT(n_value);

  if(dx == NULL || dx->ncols != 1)
  { //sprintf(error_msg, "Self is not a Vector");
    rb_raise(rb_eRuntimeError, "Self is not a Vector");
  }
  
  switch(dx->data_type)
  {
  case Single_t: //s
    if(da_value == Qnil)
      da_f = (float) 1.0;
    else
      da_f = (float) NUM2DBL(da_value);
    cblas_sscal(n , da_f, (float *)dx->data, incx ); 
    break;
  case Double_t: //d
    if(da_value == Qnil)
      da_d = (double) 1.0;
    else
      da_d = NUM2DBL(da_value);
    cblas_dscal(n , da_d, (double *)dx->data, incx ); 
    break;
  case Complex_t: //c
    if(da_value == Qnil)
    {
      da_c[0] = (float) 1.0;
      da_c[1] = (float) 0.0;
    }
    else
    {
      da_c[0] = (float) NUM2DBL(rb_funcall( rb_intern("Complex"),  rb_intern("real"),  1, da_value) );
      da_c[1] = (float) NUM2DBL(rb_funcall(rb_intern("Complex"),  rb_intern("image"),  1, da_value ) );
    }
    cblas_cscal(n , da_c, dx->data, incx ); 
    break;
  case Double_Complex_t: //z
    if(da_value == Qnil)
    {
      da_z[0] = (double) 1.0;
      da_z[1] = (double) 0.0;
    }
    else
    {
      da_z[0] = NUM2DBL(rb_funcall( rb_intern("Complex"),  rb_intern("real"),  1, da_value) );
      da_z[1] = NUM2DBL(rb_funcall(rb_intern("Complex"),  rb_intern("image"),  1, da_value ) );
    }
    cblas_zscal(n , da_z, dx->data, incx ); 
    break;
  default:
    //sprintf(error_msg, "Invalid data_type (%d) in Matrix", dx->data_type);
    rb_raise(rb_eRuntimeError, "Invalid data_type (%d) in Matrix", dx->data_type);
    break; //Never reaches here.
  }

  return self;
}
Beispiel #18
0
static VALUE
vm_backtrace_to_ary(rb_thread_t *th, int argc, const VALUE *argv, int lev_default, int lev_plus, int to_str)
{
    VALUE level, vn;
    long lev, n;
    VALUE btval = backtrace_object(th);
    VALUE r;
    rb_backtrace_t *bt;

    GetCoreDataFromValue(btval, rb_backtrace_t, bt);

    rb_scan_args(argc, argv, "02", &level, &vn);

    if (argc == 2 && NIL_P(vn)) argc--;

    switch (argc) {
      case 0:
	lev = lev_default + lev_plus;
	n = bt->backtrace_size - lev;
	break;
      case 1:
	{
	    long beg, len;
	    switch (rb_range_beg_len(level, &beg, &len, bt->backtrace_size - lev_plus, 0)) {
	      case Qfalse:
		lev = NUM2LONG(level);
		if (lev < 0) {
		    rb_raise(rb_eArgError, "negative level (%ld)", lev);
		}
		lev += lev_plus;
		n = bt->backtrace_size - lev;
		break;
	      case Qnil:
		return Qnil;
	      default:
		lev = beg + lev_plus;
		n = len;
		break;
	    }
	    break;
	}
      case 2:
	lev = NUM2LONG(level);
	n = NUM2LONG(vn);
	if (lev < 0) {
	    rb_raise(rb_eArgError, "negative level (%ld)", lev);
	}
	if (n < 0) {
	    rb_raise(rb_eArgError, "negative size (%ld)", n);
	}
	lev += lev_plus;
	break;
      default:
	lev = n = 0; /* to avoid warning */
	break;
    }

    if (n == 0) {
	return rb_ary_new();
    }

    if (to_str) {
	r = backtrace_to_str_ary(btval, lev, n);
    }
    else {
	r = backtrace_to_location_ary(btval, lev, n);
    }
    RB_GC_GUARD(btval);
    return r;
}
/*
ポリゴン描画
*/
static VALUE drawing_draw_polygon(int argc, VALUE *argv, VALUE self)
{
  VALUE vdst;
  VALUE pairs;
  VALUE mcolor;
  VALUE fill;
  VALUE aa;
  Uint8 alpha;
  Uint32 color;
  int i, vertexes;
  
  rb_scan_args(argc, argv, "32", &vdst, &pairs, &mcolor, &fill, &aa);
  
  // bitmapメソッドを持っていれば、メソッドの値をvdstとする
  VALUE methods = rb_funcall(vdst, rb_intern("methods"), 0);
  if(rb_ary_includes(methods, rb_str_intern(rb_str_new2("to_unit"))) == Qfalse &&
     rb_ary_includes(methods, rb_str_intern(rb_str_new2("bitmap"))) == Qfalse
    )
    rb_raise(eMiyakoError, "this method needs sprite have to_method or bitmap method!");
  if(rb_ary_includes(methods, rb_str_intern(rb_str_new2("to_unit"))) == Qtrue)
    vdst = rb_funcall(vdst, rb_intern("to_unit"), 0);
  vdst = rb_funcall(vdst, rb_intern("bitmap"), 0);

  vertexes = RARRAY_LEN(pairs);
  // 頂点数チェック
  if(vertexes > 65536)
    rb_raise(eMiyakoError, "too many pairs. pairs is less than 65536.");
  
  // 範囲チェック
  for(i=0; i<vertexes; i++)
  {
    VALUE vertex = *(RARRAY_PTR(pairs)+i);
    Sint16 x, y;
    get_position(vertex, &x, &y);
  }
  
	SDL_Surface  *dst = GetSurface(vdst)->surface;

  color = value_2_color(rb_funcall(cColor, rb_intern("to_rgb"), 1, mcolor), dst->format, &alpha);

  if(RTEST(fill) && RTEST(aa) && alpha < 255)
    rb_raise(eMiyakoError, "can't draw filled antialiased alpha polygon");

  Sint16 *px = (Sint16 *)malloc(sizeof(Sint16) * vertexes);
  Sint16 *py = (Sint16 *)malloc(sizeof(Sint16) * vertexes);
  for(i=0; i<vertexes; i++)
  {
    VALUE vertex = *(RARRAY_PTR(pairs)+i);
    get_position(vertex, px+i, py+i);
  }
  
  if(!RTEST(fill) && !RTEST(aa) && alpha == 255)
  {
    for(i=0; i<vertexes-1; i++)
      sge_Line(dst, px[i], py[i], px[i+1], py[i+1], color);
    sge_Line(dst, px[vertexes-1], py[vertexes-1], px[0], py[0], color);
  }
  else if(!RTEST(fill) && !RTEST(aa) && alpha < 255)
  {
    for(i=0; i<vertexes-1; i++)
      sge_LineAlpha(dst, px[i], py[i], px[i+1], py[i+1], color, alpha);
    sge_LineAlpha(dst, px[vertexes-1], py[vertexes-1], px[0], py[0], color, alpha);
  }
  else if(!RTEST(fill) && RTEST(aa) && alpha == 255)
  {
    for(i=0; i<vertexes-1; i++)
      sge_AALine(dst, px[i], py[i], px[i+1], py[i+1], color);
    sge_AALine(dst, px[vertexes-1], py[vertexes-1], px[0], py[0], color);
  }
  else if(!RTEST(fill) && RTEST(aa) && alpha < 255)
  {
    for(i=0; i<vertexes-1; i++)
      sge_AALineAlpha(dst, px[i], py[i], px[i+1], py[i+1], color, alpha);
    sge_AALineAlpha(dst, px[vertexes-1], py[vertexes-1], px[0], py[0], color, alpha);
  }
  else if(RTEST(fill) && !RTEST(aa) && alpha == 255)
    sge_FilledPolygon(dst, (Uint16)vertexes, px, py, color);
  else if(RTEST(fill) && !RTEST(aa) && alpha < 255)
    sge_FilledPolygonAlpha(dst, (Uint16)vertexes, px, py, color, alpha);
  else if(RTEST(fill) && RTEST(aa) && alpha == 255)
    sge_AAFilledPolygon(dst, (Uint16)vertexes, px, py, color);
  
  free(py);
  free(px);

  return Qnil;
}
Beispiel #20
0
/* call-seq:
 *    client.query(sql, options = {})
 *
 * Query the database with +sql+, with optional +options+.  For the possible
 * options, see @@default_query_options on the Mysql2::Client class.
 */
static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
#ifndef _WIN32
  struct async_query_args async_args;
#endif
  struct nogvl_send_query_args args;
  int async = 0;
  VALUE opts, current;
  VALUE thread_current = rb_thread_current();
#ifdef HAVE_RUBY_ENCODING_H
  rb_encoding *conn_enc;
#endif
  GET_CLIENT(self);

  REQUIRE_CONNECTED(wrapper);
  args.mysql = wrapper->client;

  current = rb_hash_dup(rb_iv_get(self, "@query_options"));
  RB_GC_GUARD(current);
  Check_Type(current, T_HASH);
  rb_iv_set(self, "@current_query_options", current);

  if (rb_scan_args(argc, argv, "11", &args.sql, &opts) == 2) {
    rb_funcall(current, intern_merge_bang, 1, opts);

    if (rb_hash_aref(current, sym_async) == Qtrue) {
      async = 1;
    }
  }

  Check_Type(args.sql, T_STRING);
#ifdef HAVE_RUBY_ENCODING_H
  conn_enc = rb_to_encoding(wrapper->encoding);
  /* ensure the string is in the encoding the connection is expecting */
  args.sql = rb_str_export_to_enc(args.sql, conn_enc);
#endif
  args.sql_ptr = StringValuePtr(args.sql);
  args.sql_len = RSTRING_LEN(args.sql);

  /* see if this connection is still waiting on a result from a previous query */
  if (NIL_P(wrapper->active_thread)) {
    /* mark this connection active */
    wrapper->active_thread = thread_current;
  } else if (wrapper->active_thread == thread_current) {
    rb_raise(cMysql2Error, "This connection is still waiting for a result, try again once you have the result");
  } else {
    VALUE inspect = rb_inspect(wrapper->active_thread);
    const char *thr = StringValueCStr(inspect);

    rb_raise(cMysql2Error, "This connection is in use by: %s", thr);
    RB_GC_GUARD(inspect);
  }

  args.wrapper = wrapper;

#ifndef _WIN32
  rb_rescue2(do_send_query, (VALUE)&args, disconnect_and_raise, self, rb_eException, (VALUE)0);

  if (!async) {
    async_args.fd = wrapper->client->net.fd;
    async_args.self = self;

    rb_rescue2(do_query, (VALUE)&async_args, disconnect_and_raise, self, rb_eException, (VALUE)0);

    return rb_mysql_client_async_result(self);
  } else {
    return Qnil;
  }
#else
  do_send_query(&args);

  /* this will just block until the result is ready */
  return rb_ensure(rb_mysql_client_async_result, self, finish_and_mark_inactive, self);
#endif
}
Beispiel #21
0
static VALUE
tstore_insert(int argc, VALUE *argv, VALUE self)
{
    VALUE parent, position, values, ret;
    GtkTreeIter iter;
    GtkTreeStore* model = _SELF(self);

    rb_scan_args(argc, argv, "21", &parent, &position, &values);

    if (NIL_P(values)){
        gtk_tree_store_insert(model, &iter, 
                              NIL_P(parent) ? NULL : RVAL2GTKTREEITER(parent), 
                              NUM2INT(position));
        iter.user_data3 = model;
        ret = GTKTREEITER2RVAL(&iter);
        G_CHILD_ADD(self, ret);
    } else {
#if GTK_CHECK_VERSION(2,10,0)
        gint *c_columns;
        GValue *c_values;
        long size, i;

        size = NUM2INT(rb_funcall(values, rb_intern("size"), 0));
        c_columns = ALLOCA_N(gint, size);
        c_values = ALLOCA_N(GValue, size);
        
        if(TYPE(values)==T_ARRAY) {
            for(i=0; i<size; i++) {
                c_columns[i] = i;
                GType gtype = gtk_tree_model_get_column_type(GTK_TREE_MODEL(RVAL2GOBJ(self)),
                                                             c_columns[i]);
        
                GValue gval = {0,};
                g_value_init(&gval, gtype);
                rbgobj_rvalue_to_gvalue(rb_ary_shift(values), &gval);
                c_values[i] = gval;
            }
        } else if(TYPE(values)==T_HASH) {
            VALUE r_columns;
            r_columns = rb_funcall(values, rb_intern("keys"), 0);
            
            for(i=0; i<size; i++) {
                c_columns[i] = NUM2INT (rb_ary_entry(r_columns, i));
                
                GType gtype = gtk_tree_model_get_column_type(GTK_TREE_MODEL(RVAL2GOBJ(self)),
                                                             c_columns[i]);
                
                GValue gval = {0,};
                g_value_init(&gval, gtype);
                rbgobj_rvalue_to_gvalue(rb_hash_aref(values, INT2NUM(c_columns[i])), &gval);
                c_values[i] = gval;
            }
        } else {
            rb_raise(rb_eArgError, "values must be of type Hash or Array");
        }

        gtk_tree_store_insert_with_valuesv(model, &iter,
                                           NIL_P(parent) ? NULL : RVAL2GTKTREEITER(parent),
                                           NUM2INT(position),
                                           c_columns,
                                           c_values,
                                           size);
        iter.user_data3 = model;

        ret = GTKTREEITER2RVAL(&iter);
        G_CHILD_ADD(self, ret);

        for(i=0; i<size; i++) {
            G_CHILD_ADD(ret, rbgobj_gvalue_to_rvalue(&(c_values[i])));
            g_value_unset(&(c_values[i]));
        }
#else
        rb_warn("Gtk::TreeStore#insert(parent, position, values) requires GTK+-2.10.0 or later");
        gtk_tree_store_insert(model, &iter, 
                              NIL_P(parent) ? NULL : RVAL2GTKTREEITER(parent), 
                              NUM2INT(position));
        iter.user_data3 = model;
        ret = GTKTREEITER2RVAL(&iter);
        G_CHILD_ADD(self, ret);
#endif
    }

    return ret;
}
Beispiel #22
0
/* call-seq:
 *    client.query(sql, options = {})
 *
 * Query the database with +sql+, with optional +options+.  For the possible
 * options, see @@default_query_options on the Mysql2::Client class.
 */
static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
#ifndef _WIN32
  struct async_query_args async_args;
#endif
  struct nogvl_send_query_args args;
  int async = 0;
  VALUE opts, defaults;
#ifdef HAVE_RUBY_ENCODING_H
  rb_encoding *conn_enc;
#endif
  GET_CLIENT(self);

  REQUIRE_OPEN_DB(wrapper);
  args.mysql = wrapper->client;


  defaults = rb_iv_get(self, "@query_options");
  if (rb_scan_args(argc, argv, "11", &args.sql, &opts) == 2) {
    opts = rb_funcall(defaults, intern_merge, 1, opts);
    rb_iv_set(self, "@query_options", opts);

    if (rb_hash_aref(opts, sym_async) == Qtrue) {
      async = 1;
    }
  } else {
    opts = defaults;
  }

  Check_Type(args.sql, T_STRING);
#ifdef HAVE_RUBY_ENCODING_H
  conn_enc = rb_to_encoding(wrapper->encoding);
  // ensure the string is in the encoding the connection is expecting
  args.sql = rb_str_export_to_enc(args.sql, conn_enc);
#endif
  args.sql_ptr = StringValuePtr(args.sql);
  args.sql_len = RSTRING_LEN(args.sql);

  // see if this connection is still waiting on a result from a previous query
  if (wrapper->active == 0) {
    // mark this connection active
    wrapper->active = 1;
  } else {
    rb_raise(cMysql2Error, "This connection is still waiting for a result, try again once you have the result");
  }

  args.wrapper = wrapper;

#ifndef _WIN32
  rb_rescue2(do_send_query, (VALUE)&args, disconnect_and_raise, self, rb_eException, (VALUE)0);

  if (!async) {
    async_args.fd = wrapper->client->net.fd;
    async_args.self = self;

    rb_rescue2(do_query, (VALUE)&async_args, disconnect_and_raise, self, rb_eException, (VALUE)0);

    return rb_mysql_client_async_result(self);
  } else {
    return Qnil;
  }
#else
  do_send_query(&args);

  // this will just block until the result is ready
  return rb_ensure(rb_mysql_client_async_result, self, finish_and_mark_inactive, self);
#endif
}
Beispiel #23
0
static VALUE
count_nodes(int argc, VALUE *argv, VALUE os)
{
    size_t nodes[NODE_LAST+1];
    size_t i;
    VALUE hash;

    if (rb_scan_args(argc, argv, "01", &hash) == 1) {
        if (TYPE(hash) != T_HASH)
            rb_raise(rb_eTypeError, "non-hash given");
    }

    for (i = 0; i <= NODE_LAST; i++) {
	nodes[i] = 0;
    }

    rb_objspace_each_objects(cn_i, &nodes[0]);

    if (hash == Qnil) {
        hash = rb_hash_new();
    }
    else if (!RHASH_EMPTY_P(hash)) {
        st_foreach(RHASH_TBL(hash), set_zero_i, hash);
    }

    for (i=0; i<NODE_LAST; i++) {
	if (nodes[i] != 0) {
	    VALUE node;
	    switch (i) {
#define COUNT_NODE(n) case n: node = ID2SYM(rb_intern(#n)); break;
		COUNT_NODE(NODE_SCOPE);
		COUNT_NODE(NODE_BLOCK);
		COUNT_NODE(NODE_IF);
		COUNT_NODE(NODE_CASE);
		COUNT_NODE(NODE_WHEN);
		COUNT_NODE(NODE_OPT_N);
		COUNT_NODE(NODE_WHILE);
		COUNT_NODE(NODE_UNTIL);
		COUNT_NODE(NODE_ITER);
		COUNT_NODE(NODE_FOR);
		COUNT_NODE(NODE_BREAK);
		COUNT_NODE(NODE_NEXT);
		COUNT_NODE(NODE_REDO);
		COUNT_NODE(NODE_RETRY);
		COUNT_NODE(NODE_BEGIN);
		COUNT_NODE(NODE_RESCUE);
		COUNT_NODE(NODE_RESBODY);
		COUNT_NODE(NODE_ENSURE);
		COUNT_NODE(NODE_AND);
		COUNT_NODE(NODE_OR);
		COUNT_NODE(NODE_MASGN);
		COUNT_NODE(NODE_LASGN);
		COUNT_NODE(NODE_DASGN);
		COUNT_NODE(NODE_DASGN_CURR);
		COUNT_NODE(NODE_GASGN);
		COUNT_NODE(NODE_IASGN);
		COUNT_NODE(NODE_IASGN2);
		COUNT_NODE(NODE_CDECL);
		COUNT_NODE(NODE_CVASGN);
		COUNT_NODE(NODE_CVDECL);
		COUNT_NODE(NODE_OP_ASGN1);
		COUNT_NODE(NODE_OP_ASGN2);
		COUNT_NODE(NODE_OP_ASGN_AND);
		COUNT_NODE(NODE_OP_ASGN_OR);
		COUNT_NODE(NODE_CALL);
		COUNT_NODE(NODE_FCALL);
		COUNT_NODE(NODE_VCALL);
		COUNT_NODE(NODE_SUPER);
		COUNT_NODE(NODE_ZSUPER);
		COUNT_NODE(NODE_ARRAY);
		COUNT_NODE(NODE_ZARRAY);
		COUNT_NODE(NODE_VALUES);
		COUNT_NODE(NODE_HASH);
		COUNT_NODE(NODE_RETURN);
		COUNT_NODE(NODE_YIELD);
		COUNT_NODE(NODE_LVAR);
		COUNT_NODE(NODE_DVAR);
		COUNT_NODE(NODE_GVAR);
		COUNT_NODE(NODE_IVAR);
		COUNT_NODE(NODE_CONST);
		COUNT_NODE(NODE_CVAR);
		COUNT_NODE(NODE_NTH_REF);
		COUNT_NODE(NODE_BACK_REF);
		COUNT_NODE(NODE_MATCH);
		COUNT_NODE(NODE_MATCH2);
		COUNT_NODE(NODE_MATCH3);
		COUNT_NODE(NODE_LIT);
		COUNT_NODE(NODE_STR);
		COUNT_NODE(NODE_DSTR);
		COUNT_NODE(NODE_XSTR);
		COUNT_NODE(NODE_DXSTR);
		COUNT_NODE(NODE_EVSTR);
		COUNT_NODE(NODE_DREGX);
		COUNT_NODE(NODE_DREGX_ONCE);
		COUNT_NODE(NODE_ARGS);
		COUNT_NODE(NODE_ARGS_AUX);
		COUNT_NODE(NODE_OPT_ARG);
		COUNT_NODE(NODE_POSTARG);
		COUNT_NODE(NODE_ARGSCAT);
		COUNT_NODE(NODE_ARGSPUSH);
		COUNT_NODE(NODE_SPLAT);
		COUNT_NODE(NODE_TO_ARY);
		COUNT_NODE(NODE_BLOCK_ARG);
		COUNT_NODE(NODE_BLOCK_PASS);
		COUNT_NODE(NODE_DEFN);
		COUNT_NODE(NODE_DEFS);
		COUNT_NODE(NODE_ALIAS);
		COUNT_NODE(NODE_VALIAS);
		COUNT_NODE(NODE_UNDEF);
		COUNT_NODE(NODE_CLASS);
		COUNT_NODE(NODE_MODULE);
		COUNT_NODE(NODE_SCLASS);
		COUNT_NODE(NODE_COLON2);
		COUNT_NODE(NODE_COLON3);
		COUNT_NODE(NODE_DOT2);
		COUNT_NODE(NODE_DOT3);
		COUNT_NODE(NODE_FLIP2);
		COUNT_NODE(NODE_FLIP3);
		COUNT_NODE(NODE_SELF);
		COUNT_NODE(NODE_NIL);
		COUNT_NODE(NODE_TRUE);
		COUNT_NODE(NODE_FALSE);
		COUNT_NODE(NODE_ERRINFO);
		COUNT_NODE(NODE_DEFINED);
		COUNT_NODE(NODE_POSTEXE);
		COUNT_NODE(NODE_ALLOCA);
		COUNT_NODE(NODE_BMETHOD);
		COUNT_NODE(NODE_MEMO);
		COUNT_NODE(NODE_IFUNC);
		COUNT_NODE(NODE_DSYM);
		COUNT_NODE(NODE_ATTRASGN);
		COUNT_NODE(NODE_PRELUDE);
		COUNT_NODE(NODE_LAMBDA);
		COUNT_NODE(NODE_OPTBLOCK);
#undef COUNT_NODE
	      default: node = INT2FIX(nodes[i]);
	    }
	    rb_hash_aset(hash, node, SIZET2NUM(nodes[i]));
	}
    }
    return hash;
}
Beispiel #24
0
/*
 * call-seq:
 *   DBM.new(filename[, mode[, flags]]) -> dbm
 *
 * Open a dbm database with the specified name, which can include a directory
 * path. Any file extensions needed will be supplied automatically by the dbm
 * library. For example, Berkeley DB appends '.db', and GNU gdbm uses two
 * physical files with extensions '.dir' and '.pag'.
 *
 * The mode should be an integer, as for Unix chmod.
 *
 * Flags should be one of READER, WRITER, WRCREAT or NEWDB.
 */
static VALUE
fdbm_initialize(int argc, VALUE *argv, VALUE obj)
{
    volatile VALUE file;
    VALUE vmode, vflags;
    DBM *dbm;
    struct dbmdata *dbmp;
    int mode, flags = 0;

    if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
	mode = 0666;		/* default value */
    }
    else if (NIL_P(vmode)) {
	mode = -1;		/* return nil if DB not exist */
    }
    else {
	mode = NUM2INT(vmode);
    }

    if (!NIL_P(vflags))
        flags = NUM2INT(vflags);

    FilePathValue(file);

    /*
     * Note:
     * gdbm 1.10 works with O_CLOEXEC.  gdbm 1.9.1 silently ignore it.
     */
#ifndef O_CLOEXEC
#   define O_CLOEXEC 0
#endif

    if (flags & RUBY_DBM_RW_BIT) {
        flags &= ~RUBY_DBM_RW_BIT;
        dbm = dbm_open(RSTRING_PTR(file), flags|O_CLOEXEC, mode);
    }
    else {
        dbm = 0;
        if (mode >= 0) {
            dbm = dbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT|O_CLOEXEC, mode);
        }
        if (!dbm) {
            dbm = dbm_open(RSTRING_PTR(file), O_RDWR|O_CLOEXEC, 0);
        }
        if (!dbm) {
            dbm = dbm_open(RSTRING_PTR(file), O_RDONLY|O_CLOEXEC, 0);
        }
    }

    if (dbm) {
    /*
     * History of dbm_pagfno() and dbm_dirfno() in ndbm and its compatibles.
     * (dbm_pagfno() and dbm_dirfno() is not standardized.)
     *
     * 1986: 4.3BSD provides ndbm.
     *       It provides dbm_pagfno() and dbm_dirfno() as macros.
     * 1991: gdbm-1.5 provides them as functions.
     *       They returns a same descriptor.
     *       (Earlier releases may have the functions too.)
     * 1991: Net/2 provides Berkeley DB.
     *       It doesn't provide dbm_pagfno() and dbm_dirfno().
     * 1992: 4.4BSD Alpha provides Berkeley DB with dbm_dirfno() as a function.
     *       dbm_pagfno() is a macro as DBM_PAGFNO_NOT_AVAILABLE.
     * 1997: Berkeley DB 2.0 is released by Sleepycat Software, Inc.
     *       It defines dbm_pagfno() and dbm_dirfno() as macros.
     * 2011: gdbm-1.9 creates a separate dir file.
     *       dbm_pagfno() and dbm_dirfno() returns different descriptors.
     */
#if defined(HAVE_DBM_PAGFNO)
        rb_fd_fix_cloexec(dbm_pagfno(dbm));
#endif
#if defined(HAVE_DBM_DIRFNO)
        rb_fd_fix_cloexec(dbm_dirfno(dbm));
#endif

#if defined(RUBYDBM_DB_HEADER) && defined(HAVE_TYPE_DBC)
    /* Disable Berkeley DB error messages such as:
     * DB->put: attempt to modify a read-only database */
        ((DBC*)dbm)->dbp->set_errfile(((DBC*)dbm)->dbp, NULL);
#endif
    }

    if (!dbm) {
	if (mode == -1) return Qnil;
	rb_sys_fail_str(file);
    }

    dbmp = ALLOC(struct dbmdata);
    DATA_PTR(obj) = dbmp;
    dbmp->di_dbm = dbm;
    dbmp->di_size = -1;

    return obj;
}
static VALUE rb_libarchive_reader_read_data(int argc, VALUE *argv, VALUE self) {
  VALUE v_size;
  struct rb_libarchive_archive_container *p;
  char *buff;
  size_t size = DATA_BUFFER_SIZE;
  ssize_t n;
  rb_scan_args(argc, argv, "01", &v_size);

  if (!NIL_P(v_size)) {
    size = NUM2INT(v_size);
  }

  Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
  Check_Archive(p);

  if (p->eof) {
    return Qnil;
  }

  if (rb_block_given_p()) {
    ssize_t len = 0;
    int status = 0;
    buff = xmalloc(size);

    while ((n = archive_read_data(p->ar, buff, size)) > 0) {
      rb_protect(rb_yield, rb_str_new(buff, n), &status);

      if (status != 0) {
        break;
      }

      len += n;
    }

    xfree(buff);

    if (status != 0) {
      rb_jump_tag(status);
    }

    if (n < 0) {
      rb_raise(rb_eArchiveError, "Read data failed: %s", archive_error_string(p->ar));
    }

    return LONG2NUM(len);
  } else {
    VALUE retval = rb_str_new("", 0);
    buff = xmalloc(size);

    while ((n = archive_read_data(p->ar, buff, size)) > 0) {
      rb_str_cat(retval, buff, n);
    }

    xfree(buff);

    if (n < 0) {
      rb_raise(rb_eArchiveError, "Read data failed: %s", archive_error_string(p->ar));
    }

    return retval;
  }
}
Beispiel #26
0
/*
 *  call-seq:
 *     Dir.new( string ) -> aDir
 *
 *  Returns a new directory object for the named directory.
 */
static VALUE
dir_initialize(int argc, VALUE *argv, VALUE dir)
{
    struct dir_data *dp;
    static rb_encoding *fs_encoding;
    rb_encoding  *intencoding, *extencoding;
    VALUE dirname, opt;
    static VALUE sym_intenc, sym_extenc;

    if (!sym_intenc) {
	sym_intenc = ID2SYM(rb_intern("internal_encoding"));
	sym_extenc = ID2SYM(rb_intern("external_encoding"));
	fs_encoding = rb_filesystem_encoding();
    }

    intencoding = NULL;
    extencoding = fs_encoding;
    rb_scan_args(argc, argv, "11", &dirname, &opt);

    if (!NIL_P(opt)) {
        VALUE v, extenc=Qnil, intenc=Qnil;
        opt = rb_check_convert_type(opt, T_HASH, "Hash", "to_hash");

        v = rb_hash_aref(opt, sym_intenc);
        if (!NIL_P(v)) intenc = v;
        v = rb_hash_aref(opt, sym_extenc);
        if (!NIL_P(v)) extenc = v;

	if (!NIL_P(extenc)) {
	    extencoding = rb_to_encoding(extenc);
	    if (!NIL_P(intenc)) {
		intencoding = rb_to_encoding(intenc);
		if (extencoding == intencoding) {
		    rb_warn("Ignoring internal encoding '%s': it is identical to external encoding '%s'",
			    RSTRING_PTR(rb_inspect(intenc)),
			    RSTRING_PTR(rb_inspect(extenc)));
		    intencoding = NULL;
		}
	    }
	}
	else if (!NIL_P(intenc)) {
	    rb_raise(rb_eArgError, "External encoding must be specified when internal encoding is given");
	}
    }

    {
	rb_encoding  *dirname_encoding = rb_enc_get(dirname);
	if (rb_usascii_encoding() != dirname_encoding
	    && rb_ascii8bit_encoding() != dirname_encoding
#if defined __APPLE__
	    && rb_utf8_encoding() != dirname_encoding
#endif
	    && extencoding != dirname_encoding) {
	    if (!intencoding) intencoding = dirname_encoding;
	    dirname = rb_str_transcode(dirname, rb_enc_from_encoding(extencoding));
	}
    }
    FilePathValue(dirname);

    Data_Get_Struct(dir, struct dir_data, dp);
    if (dp->dir) closedir(dp->dir);
    if (dp->path) xfree(dp->path);
    dp->dir = NULL;
    dp->path = NULL;
    dp->intenc = intencoding;
    dp->extenc = extencoding;
    dp->dir = opendir(RSTRING_PTR(dirname));
    if (dp->dir == NULL) {
	if (errno == EMFILE || errno == ENFILE) {
	    rb_gc();
	    dp->dir = opendir(RSTRING_PTR(dirname));
	}
	if (dp->dir == NULL) {
	    rb_sys_fail(RSTRING_PTR(dirname));
	}
    }
    dp->path = strdup(RSTRING_PTR(dirname));

    return dir;
}
Beispiel #27
0
static VALUE
fntype_initialize(int argc, VALUE* argv, VALUE self)
{
    FunctionType *fnInfo;
    ffi_status status;
    VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbOptions = Qnil;
    VALUE rbEnums = Qnil, rbConvention = Qnil, rbBlocking = Qnil;
    int i, nargs;

    nargs = rb_scan_args(argc, argv, "21", &rbReturnType, &rbParamTypes, &rbOptions);
    if (nargs >= 3 && rbOptions != Qnil) {
        rbConvention = rb_hash_aref(rbOptions, ID2SYM(rb_intern("convention")));
        rbEnums = rb_hash_aref(rbOptions, ID2SYM(rb_intern("enums")));
        rbBlocking = rb_hash_aref(rbOptions, ID2SYM(rb_intern("blocking")));
    }

    Check_Type(rbParamTypes, T_ARRAY);

    Data_Get_Struct(self, FunctionType, fnInfo);
    fnInfo->parameterCount = RARRAY_LEN(rbParamTypes);
    fnInfo->parameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->parameterTypes));
    fnInfo->ffiParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(ffi_type *));
    fnInfo->nativeParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->nativeParameterTypes));
    fnInfo->rbParameterTypes = rb_ary_new2(fnInfo->parameterCount);
    fnInfo->rbEnums = rbEnums;
    fnInfo->blocking = RTEST(rbBlocking);
    fnInfo->hasStruct = false;

    for (i = 0; i < fnInfo->parameterCount; ++i) {
        VALUE entry = rb_ary_entry(rbParamTypes, i);
        VALUE type = rbffi_Type_Lookup(entry);

        if (!RTEST(type)) {
            VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL);
            rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName));
        }

        if (rb_obj_is_kind_of(type, rbffi_FunctionTypeClass)) {
            REALLOC_N(fnInfo->callbackParameters, VALUE, fnInfo->callbackCount + 1);
            fnInfo->callbackParameters[fnInfo->callbackCount++] = type;
        }

        if (rb_obj_is_kind_of(type, rbffi_StructByValueClass)) {
            fnInfo->hasStruct = true;
        }

        rb_ary_push(fnInfo->rbParameterTypes, type);
        Data_Get_Struct(type, Type, fnInfo->parameterTypes[i]);
        fnInfo->ffiParameterTypes[i] = fnInfo->parameterTypes[i]->ffiType;
        fnInfo->nativeParameterTypes[i] = fnInfo->parameterTypes[i]->nativeType;
    }

    fnInfo->rbReturnType = rbffi_Type_Lookup(rbReturnType);
    if (!RTEST(fnInfo->rbReturnType)) {
        VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL);
        rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
    }
    
    if (rb_obj_is_kind_of(fnInfo->rbReturnType, rbffi_StructByValueClass)) {
        fnInfo->hasStruct = true;
    }

    Data_Get_Struct(fnInfo->rbReturnType, Type, fnInfo->returnType);
    fnInfo->ffiReturnType = fnInfo->returnType->ffiType;


#if defined(_WIN32) || defined(__WIN32__)
    fnInfo->abi = (rbConvention != Qnil && strcmp(StringValueCStr(rbConvention), "stdcall") == 0)
            ? FFI_STDCALL : FFI_DEFAULT_ABI;
#else
    fnInfo->abi = FFI_DEFAULT_ABI;
#endif

    status = ffi_prep_cif(&fnInfo->ffi_cif, fnInfo->abi, fnInfo->parameterCount,
            fnInfo->ffiReturnType, fnInfo->ffiParameterTypes);
    switch (status) {
        case FFI_BAD_ABI:
            rb_raise(rb_eArgError, "Invalid ABI specified");
        case FFI_BAD_TYPEDEF:
            rb_raise(rb_eArgError, "Invalid argument type specified");
        case FFI_OK:
            break;
        default:
            rb_raise(rb_eArgError, "Unknown FFI error");
    }

    fnInfo->invoke = rbffi_GetInvoker(fnInfo);

    return self;
}
/*
 * call-seq:
 *  evaluate(search_path, handler = nil)
 *
 * Evaluate the +search_path+ returning an XML::XPath object.
 */
static VALUE evaluate(int argc, VALUE *argv, VALUE self)
{
  VALUE search_path, xpath_handler;
  VALUE thing = Qnil;
  xmlXPathContextPtr ctx;
  xmlXPathObjectPtr xpath;
  xmlChar *query;

  Data_Get_Struct(self, xmlXPathContext, ctx);

  if(rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1)
    xpath_handler = Qnil;

  query = (xmlChar *)StringValuePtr(search_path);

  if(Qnil != xpath_handler) {
    /* FIXME: not sure if this is the correct place to shove private data. */
    ctx->userData = (void *)xpath_handler;
    xmlXPathRegisterFuncLookup(ctx, lookup, (void *)xpath_handler);
  }

  xmlResetLastError();
  xmlSetStructuredErrorFunc(NULL, xpath_exception_handler);

  /* For some reason, xmlXPathEvalExpression will blow up with a generic error */
  /* when there is a non existent function. */
  xmlSetGenericErrorFunc(NULL, xpath_generic_exception_handler);

  xpath = xmlXPathEvalExpression(query, ctx);
  xmlSetStructuredErrorFunc(NULL, NULL);
  xmlSetGenericErrorFunc(NULL, NULL);

  if(xpath == NULL) {
    VALUE xpath = rb_const_get(mNokogiriXml, rb_intern("XPath"));
    VALUE klass = rb_const_get(xpath, rb_intern("SyntaxError"));

    xmlErrorPtr error = xmlGetLastError();
    rb_exc_raise(Nokogiri_wrap_xml_syntax_error(klass, error));
  }

  assert(ctx->doc);
  assert(DOC_RUBY_OBJECT_TEST(ctx->doc));

  switch(xpath->type) {
    case XPATH_STRING:
      thing = NOKOGIRI_STR_NEW2(xpath->stringval);
      xmlFree(xpath->stringval);
      break;
    case XPATH_NODESET:
      if(NULL == xpath->nodesetval) {
        thing = Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL),
          DOC_RUBY_OBJECT(ctx->doc));
      } else {
        thing = Nokogiri_wrap_xml_node_set(xpath->nodesetval,
            DOC_RUBY_OBJECT(ctx->doc));
      }
      break;
    case XPATH_NUMBER:
      thing = rb_float_new(xpath->floatval);
      break;
    case XPATH_BOOLEAN:
      thing = xpath->boolval == 1 ? Qtrue : Qfalse;
      break;
    default:
      thing = Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL),
        DOC_RUBY_OBJECT(ctx->doc));
  }

  xmlXPathFreeNodeSetList(xpath);

  return thing;
}
Beispiel #29
0
static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
  VALUE defaults, opts, block;
  ID db_timezone, app_timezone, dbTz, appTz;
  mysql2_result_wrapper * wrapper;
  unsigned long i;
  int symbolizeKeys = 0, asArray = 0, castBool = 0, cacheRows = 1;

  GetMysql2Result(self, wrapper);

  defaults = rb_iv_get(self, "@query_options");
  if (rb_scan_args(argc, argv, "01&", &opts, &block) == 1) {
    opts = rb_funcall(defaults, intern_merge, 1, opts);
  } else {
    opts = defaults;
  }

  if (rb_hash_aref(opts, sym_symbolize_keys) == Qtrue) {
    symbolizeKeys = 1;
  }

  if (rb_hash_aref(opts, sym_as) == sym_array) {
    asArray = 1;
  }

  if (rb_hash_aref(opts, sym_cast_booleans) == Qtrue) {
    castBool = 1;
  }

  if (rb_hash_aref(opts, sym_cache_rows) == Qfalse) {
    cacheRows = 0;
  }

  dbTz = rb_hash_aref(opts, sym_database_timezone);
  if (dbTz == sym_local) {
    db_timezone = intern_local;
  } else if (dbTz == sym_utc) {
    db_timezone = intern_utc;
  } else {
    if (!NIL_P(dbTz)) {
      rb_warn(":database_timezone option must be :utc or :local - defaulting to :local");
    }
    db_timezone = intern_local;
  }

  appTz = rb_hash_aref(opts, sym_application_timezone);
  if (appTz == sym_local) {
    app_timezone = intern_local;
  } else if (appTz == sym_utc) {
    app_timezone = intern_utc;
  } else {
    app_timezone = Qnil;
  }

  if (wrapper->lastRowProcessed == 0) {
    wrapper->numberOfRows = mysql_num_rows(wrapper->result);
    if (wrapper->numberOfRows == 0) {
      wrapper->rows = rb_ary_new();
      return wrapper->rows;
    }
    wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
  }

  if (cacheRows && wrapper->lastRowProcessed == wrapper->numberOfRows) {
    // we've already read the entire dataset from the C result into our
    // internal array. Lets hand that over to the user since it's ready to go
    for (i = 0; i < wrapper->numberOfRows; i++) {
      rb_yield(rb_ary_entry(wrapper->rows, i));
    }
  } else {
    unsigned long rowsProcessed = 0;
    rowsProcessed = RARRAY_LEN(wrapper->rows);
    for (i = 0; i < wrapper->numberOfRows; i++) {
      VALUE row;
      if (cacheRows && i < rowsProcessed) {
        row = rb_ary_entry(wrapper->rows, i);
      } else {
        row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool);
        if (cacheRows) {
          rb_ary_store(wrapper->rows, i, row);
        }
        wrapper->lastRowProcessed++;
      }

      if (row == Qnil) {
        // we don't need the mysql C dataset around anymore, peace it
        rb_mysql_result_free_result(wrapper);
        return Qnil;
      }

      if (block != Qnil) {
        rb_yield(row);
      }
    }
    if (wrapper->lastRowProcessed == wrapper->numberOfRows) {
      // we don't need the mysql C dataset around anymore, peace it
      rb_mysql_result_free_result(wrapper);
    }
  }

  return wrapper->rows;
}
Beispiel #30
0
static VALUE
range_step(int argc, VALUE *argv, VALUE range)
{
    VALUE b, e, step, tmp;

    RETURN_SIZED_ENUMERATOR(range, argc, argv, range_step_size);

    b = RANGE_BEG(range);
    e = RANGE_END(range);
    if (argc == 0) {
	step = INT2FIX(1);
    }
    else {
	rb_scan_args(argc, argv, "01", &step);
	if (!rb_obj_is_kind_of(step, rb_cNumeric)) {
	    step = rb_to_int(step);
	}
	if (rb_funcall(step, '<', 1, INT2FIX(0))) {
	    rb_raise(rb_eArgError, "step can't be negative");
	}
	else if (!rb_funcall(step, '>', 1, INT2FIX(0))) {
	    rb_raise(rb_eArgError, "step can't be 0");
	}
    }

    if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */
	long end = FIX2LONG(e);
	long i, unit = FIX2LONG(step);

	if (!EXCL(range))
	    end += 1;
	i = FIX2LONG(b);
	while (i < end) {
	    rb_yield(LONG2NUM(i));
	    if (i + unit < i) break;
	    i += unit;
	}

    }
    else if (SYMBOL_P(b) && SYMBOL_P(e)) { /* symbols are special */
	VALUE args[2], iter[2];

	args[0] = rb_sym_to_s(e);
	args[1] = EXCL(range) ? Qtrue : Qfalse;
	iter[0] = INT2FIX(1);
	iter[1] = step;
	rb_block_call(rb_sym_to_s(b), rb_intern("upto"), 2, args, sym_step_i, (VALUE)iter);
    }
    else if (ruby_float_step(b, e, step, EXCL(range))) {
	/* done */
    }
    else if (rb_obj_is_kind_of(b, rb_cNumeric) ||
	     !NIL_P(rb_check_to_integer(b, "to_int")) ||
	     !NIL_P(rb_check_to_integer(e, "to_int"))) {
	ID op = EXCL(range) ? '<' : idLE;
	VALUE v = b;
	int i = 0;

	while (RTEST(rb_funcall(v, op, 1, e))) {
	    rb_yield(v);
	    i++;
	    v = rb_funcall(b, '+', 1, rb_funcall(INT2NUM(i), '*', 1, step));
	}
    }
    else {
	tmp = rb_check_string_type(b);

	if (!NIL_P(tmp)) {
	    VALUE args[2], iter[2];

	    b = tmp;
	    args[0] = e;
	    args[1] = EXCL(range) ? Qtrue : Qfalse;
	    iter[0] = INT2FIX(1);
	    iter[1] = step;
	    rb_block_call(b, rb_intern("upto"), 2, args, step_i, (VALUE)iter);
	}
	else {
	    VALUE args[2];

	    if (!discrete_object_p(b)) {
		rb_raise(rb_eTypeError, "can't iterate from %s",
			 rb_obj_classname(b));
	    }
	    args[0] = INT2FIX(1);
	    args[1] = step;
	    range_each_func(range, step_i, (VALUE)args);
	}
    }
    return range;
}