Esempio n. 1
0
static mrb_value
ctx_class_instance(mrb_state *mrb, mrb_value klass)
{
  grn_ctx *ctx = (grn_ctx *)mrb->ud;
  mrb_value mrb_ctx;
  mrb_sym iv_name;

  iv_name = mrb_intern_lit(mrb, "@instance");
  mrb_ctx = mrb_iv_get(mrb, klass, iv_name);
  if (mrb_nil_p(mrb_ctx)) {
    struct RBasic *raw_mrb_ctx;
    raw_mrb_ctx = mrb_obj_alloc(mrb, MRB_TT_DATA, mrb_class_ptr(klass));
    mrb_ctx = mrb_obj_value(raw_mrb_ctx);
    DATA_PTR(mrb_ctx) = ctx;
    mrb_iv_set(mrb, klass, iv_name, mrb_ctx);
  }

  return mrb_ctx;
}
Esempio n. 2
0
/*******************************************************************************
 * Palette class
 ******************************************************************************/
static mrb_value mrb_sdl_palette_init (mrb_state *mrb, mrb_value self) {
  SDL_Palette palette;
  mrb_value arg_colors = mrb_nil_value();

  mrb_get_args(mrb, "|i", &palette.ncolors);
  mrb_get_args(mrb, "|o", &arg_colors);

  palette.colors = mrb_value_to_sdl_color(mrb, arg_colors);

  mrb_sdl_context* context = sdl_context_alloc(mrb);
  context->any.palette = &palette;

  context->instance = mrb_nil_value();
  mrb_iv_set(mrb, self, mrb_intern(mrb, "context"), mrb_obj_value(
    Data_Wrap_Struct(mrb, mrb->object_class, &sdl_context_type, (void*) context)
  ));

  return self;
}
Esempio n. 3
0
static mrb_value
map(mrb_state *mrb, mrb_value self)
{
  mrb_value map;
  uint32_t len;
  char *ptr;

  map = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "map"));
  if (!mrb_nil_p(map)) {
    return map;
  }

  PPB(VarArrayBuffer)->ByteLength(MRB_PP_VAR(self), &len);
  ptr = PPB(VarArrayBuffer)->Map(MRB_PP_VAR(self));
  map = mrb_pp_pointer_new(mrb, ptr, len, 0);

  mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "map"), map);
  return map;
}
Esempio n. 4
0
static mrb_value
mrb_ipvs_dest_init(mrb_state *mrb, mrb_value self){
  int parse;
  mrb_value arg_opt = mrb_nil_value(),
            addr = mrb_nil_value(),
            obj = mrb_nil_value();
  mrb_int port,
          weight;
  struct mrb_ipvs_entry *ie;

  ie = (struct mrb_ipvs_entry*)mrb_malloc(mrb, sizeof(*ie));
  memset(ie, 0, sizeof(struct mrb_ipvs_entry));

  mrb_get_args(mrb, "H", &arg_opt);
  if (mrb_nil_p(arg_opt)) mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
  addr = mrb_hash_get(mrb, arg_opt, mrb_str_new_cstr(mrb, "addr"));
  if (mrb_nil_p(addr)) mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
  obj = mrb_hash_get(mrb, arg_opt, mrb_str_new_cstr(mrb, "port"));
  port = mrb_nil_p(obj) ? 0 : mrb_fixnum(obj);
  if (port < 0 || port > 65535) mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid port value specified"); 
  weight = mrb_fixnum(mrb_hash_get(mrb, arg_opt, mrb_str_new_cstr(mrb, "weight")));
  obj = mrb_hash_get(mrb, arg_opt, mrb_str_new_cstr(mrb, "weight"));
  weight = mrb_nil_p(obj) ? DEF_WEIGHT : mrb_fixnum(obj);
  if (weight < 0 || weight > INT_MAX) mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid weight value specified"); 

  if (strrchr((char *) RSTRING_PTR(addr), ':') == NULL) ie->svc.port = htons(port);
  parse = parse_service((char *) RSTRING_PTR(addr), &ie->svc);
  if (!(parse & SERVICE_ADDR))
    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");

  mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@service"), mrb_nil_value());

  ie->dest.af = ie->svc.af;
  ie->dest.addr = ie->svc.addr;
  ie->dest.port = ie->svc.port;
  ie->dest.weight = weight;

  DATA_TYPE(self) = &mrb_ipvs_dest_type;
  DATA_PTR(self) = ie;

  return self;
}
Esempio n. 5
0
static mrb_value
mrb_uv_once_init(mrb_state *mrb, mrb_value self)
{
  uv_once_t *once;
  mrb_value b;
  static uv_once_t const initial_once = UV_ONCE_INIT;

  mrb_get_args(mrb, "&", &b);

  if (mrb_nil_p(b)) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "block not passed to UV::Once initialization");
  }

  once = (uv_once_t*)mrb_malloc(mrb, sizeof(uv_once_t));
  *once = initial_once;
  DATA_PTR(self) = once;
  DATA_TYPE(self) = &mrb_uv_once_type;
  mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "once_cb"), b);
  return self;
}
Esempio n. 6
0
static mrb_value mrb_rand(mrb_state* mrb, mrb_value self)
{
  int i;
  mrb_value max;
  mrb_value seed;

  max = get_opt(mrb);
  if (mrb_nil_p(self)) {
    seed = mrb_gv_get(mrb, mrb_intern_lit(mrb, GLOBAL_RAND_SEED_KEY));
    i = NEXT_SEED(seed);
    mrb_gv_set(mrb, mrb_intern_lit(mrb, GLOBAL_RAND_SEED_KEY), mrb_fixnum_value(i));
  } else {
    seed = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, INSTANCE_RAND_SEED_KEY));
    i = NEXT_SEED(seed);
    mrb_iv_set(mrb, self, mrb_intern_lit(mrb, INSTANCE_RAND_SEED_KEY), mrb_fixnum_value(i));
  }
  if (mrb_nil_p(max) || mrb_fixnum(max) == 0) {
    return mrb_float_value(mrb, NEXT_RAND(i) / 32767.0);
  }
  return mrb_float_value(mrb, NEXT_RAND(i) % mrb_fixnum(max));
}
Esempio n. 7
0
static mrb_value
mrb_http_parser_parse(mrb_state *mrb, mrb_value self)
{
    mrb_value arg_data;
    mrb_value value_context;
    mrb_http_parser_context* context;
    struct RProc *b = NULL;

    value_context = mrb_iv_get(mrb, self, mrb_intern(mrb, "parser_context"));
    Data_Get_Struct(mrb, value_context, &http_parser_context_type, context);
    if (!context) {
        mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
    }

    mrb_get_args(mrb, "bo", &b, &arg_data);
    if (mrb_nil_p(arg_data)) {
        mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
    }
    mrb_iv_set(mrb, self, mrb_intern(mrb, "complete_cb"), b ? mrb_obj_value(b) : mrb_nil_value());

    context->parser.data = context;
    context->was_header_value = TRUE;
    CTXV_SET(context, "headers", mrb_hash_new(mrb, 32));

    http_parser_init(&context->parser, HTTP_REQUEST);

    context->settings.on_url = parser_settings_on_url;
    context->settings.on_header_field = parser_settings_on_header_field;
    context->settings.on_header_value = parser_settings_on_header_value;
    context->settings.on_headers_complete = parser_settings_on_headers_complete;
    if (b) {
        context->settings.on_message_complete = parser_settings_on_message_complete;
    }

    if (RSTRING_LEN(arg_data) > 0) {
        http_parser_execute(&context->parser, &context->settings, (char*) RSTRING_PTR(arg_data), RSTRING_CAPA(arg_data));
    }

    return mrb_nil_value();
}
Esempio n. 8
0
// FLTK::Widget#callback
// Gets or sets the current callback function for the widget.
mrb_value mrb_fltk_widget_callback_instance_method( mrb_state *mrb, mrb_value self ) {
  GET_DATA( fl_widget, Fl_Widget, self );

  mrb_value block = mrb_nil_value();

  mrb_get_args( mrb, "&", &block );

  if( !mrb_nil_p( block ) ) {
    // TODO: Free the existing context struct if it already exists?
    mrb_iv_set( mrb, self, mrb_intern_cstr( mrb, "callback" ), block );

    mrb_fltk_widget_callback_context *context = (mrb_fltk_widget_callback_context *)malloc( sizeof( mrb_fltk_widget_callback_context ) );
    context->mrb = mrb;
    context->self = self;

    fl_widget->callback( mrb_fltk_widget_callback_function, context );
  } else {
    block = mrb_iv_get( mrb, self, mrb_intern_cstr( mrb, "callback" ) );
  }

  return block;
}
Esempio n. 9
0
static mrb_value
mrb_hash_dup(mrb_state *mrb, mrb_value hash)
{
  struct RHash* ret;
  khash_t(ht) *h, *ret_h;
  khiter_t k, ret_k;
  mrb_value ifnone, vret;

  h = RHASH_TBL(hash);
  ret = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
  ret->ht = kh_init(ht, mrb);

  if (h && kh_size(h) > 0) {
    ret_h = ret->ht;

    for (k = kh_begin(h); k != kh_end(h); k++) {
      if (kh_exist(h, k)) {
        int ai = mrb_gc_arena_save(mrb);
        ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h, k)));
        mrb_gc_arena_restore(mrb, ai);
        kh_val(ret_h, ret_k).v = kh_val(h, k).v;
        kh_val(ret_h, ret_k).n = kh_size(ret_h)-1;
      }
    }
  }

  if (MRB_RHASH_DEFAULT_P(hash)) {
    ret->flags |= MRB_HASH_DEFAULT;
  }
  if (MRB_RHASH_PROCDEFAULT_P(hash)) {
    ret->flags |= MRB_HASH_PROC_DEFAULT;
  }
  vret = mrb_obj_value(ret);
  ifnone = RHASH_IFNONE(hash);
  if (!mrb_nil_p(ifnone)) {
      mrb_iv_set(mrb, vret, mrb_intern_lit(mrb, "ifnone"), ifnone);
  }
  return vret;
}
Esempio n. 10
0
mrb_value mrb_redis_connect(mrb_state *mrb, mrb_value self)
{
    mrb_value host, port;

    mrb_get_args(mrb, "oo", &host, &port);

    redisContext *rc = redisConnect(RSTRING_PTR(host), mrb_fixnum(port));
    if (rc->err)
        mrb_raise(mrb, E_RUNTIME_ERROR, "redis connection faild.");

    mrb_iv_set(mrb
        , self
        , mrb_intern(mrb, "redis_c")
        , mrb_obj_value(Data_Wrap_Struct(mrb
            , mrb->object_class
            , &redisContext_type
            , (void*) rc)
        )
    );

    return self;
}
Esempio n. 11
0
File: error.c Progetto: deweerdt/h2o
static mrb_value
exc_get_backtrace(mrb_state *mrb, mrb_value exc)
{
  mrb_sym attr_name;
  mrb_value backtrace;

  attr_name = mrb_intern_lit(mrb, "backtrace");
  backtrace = mrb_iv_get(mrb, exc, attr_name);
  if (mrb_nil_p(backtrace)) {
    if (mrb_obj_ptr(exc) == mrb->backtrace.exc && mrb->backtrace.n > 0) {
      backtrace = mrb_restore_backtrace(mrb);
      mrb->backtrace.n = 0;
      mrb->backtrace.exc = 0;
    }
    else {
      backtrace = mrb_exc_backtrace(mrb, exc);
    }
    mrb_iv_set(mrb, exc, attr_name, backtrace);
  }

  return backtrace;
}
Esempio n. 12
0
static mrb_value
mrb_hash_init(mrb_state *mrb, mrb_value hash)
{
  mrb_value block, ifnone;
  mrb_bool ifnone_p;

  ifnone = mrb_nil_value();
  mrb_get_args(mrb, "&|o?", &block, &ifnone, &ifnone_p);
  mrb_hash_modify(mrb, hash);
  if (!mrb_nil_p(block)) {
    if (ifnone_p) {
      mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
    }
    RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
    ifnone = block;
  }
  if (!mrb_nil_p(ifnone)) {
    RHASH(hash)->flags |= MRB_HASH_DEFAULT;
    mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
  }
  return hash;
}
Esempio n. 13
0
mrb_value
qgame_shader_asset_load_from_file(mrb_state* mrb, mrb_value self)
{
  mrb_value path;  
  mrb_sym shader_type_sym;
  mrb_get_args(mrb, "nS", &shader_type_sym, &path);

  GLenum shader_type = shader_type_sym_to_enum(mrb, shader_type_sym);

  GLuint shader = glCreateShader(shader_type);
  if(shader == 0) {
    mrb_raisef(mrb, E_RUNTIME_ERROR, "Failed creating shader with type: %i", mrb_fixnum_value(shader_type));
    return self;
  }

  char* shader_source = read_file(mrb_string_value_ptr(mrb, path));
  glShaderSource(shader, 1, (const GLchar**)&shader_source, NULL);
  glCompileShader(shader);
  free(shader_source);

  GLint status;
  glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
  if (status == GL_FALSE) {
      
      GLint infoLogLength;
      glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
      char strInfoLog[infoLogLength + 1];
      glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);

      glDeleteShader(shader); shader = NULL;
      mrb_raisef(mrb, E_RUNTIME_ERROR, "Failed compiling shader '%S': %S", path, mrb_str_new_cstr(mrb, &strInfoLog));
      return self;
  }

  mrb_value shader_id = mrb_fixnum_value(shader);
  mrb_iv_set(mrb, self, mrb_intern(mrb, "shader_id"), shader_id);

  return self;
}
Esempio n. 14
0
File: io.c Progetto: asfluido/mruby
mrb_value
mrb_io_initialize(mrb_state *mrb, mrb_value io)
{
  struct mrb_io *fptr;
  mrb_int fd;
  mrb_value mode, opt;
  int flags;

  mode = opt = mrb_nil_value();

  mrb_get_args(mrb, "i|So", &fd, &mode, &opt);
  if (mrb_nil_p(mode)) {
    mode = mrb_str_new_cstr(mrb, "r");
  }
  if (mrb_nil_p(opt)) {
    opt = mrb_hash_new(mrb);
  }

  flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode));

  mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, ""));

  fptr = (struct mrb_io *)DATA_PTR(io);
  if (fptr != NULL) {
    fptr_finalize(mrb, fptr, TRUE);
    mrb_free(mrb, fptr);
  }
  fptr = mrb_io_alloc(mrb);

  DATA_TYPE(io) = &mrb_io_type;
  DATA_PTR(io) = fptr;

  fptr->fd = (int)fd;
  fptr->readable = ((flags & FMODE_READABLE) != 0);
  fptr->writable = ((flags & FMODE_WRITABLE) != 0);
  fptr->sync = 0;
  return io;
}
Esempio n. 15
0
static mrb_value mrb_cgroup_attach(mrb_state *mrb, mrb_value self)
{
    mrb_cgroup_context *mrb_cg_cxt = mrb_cgroup_get_context(mrb, self, "mrb_cgroup_context");
    mrb_value pid = mrb_nil_value();
    mrb_get_args(mrb, "|i", &pid);

    if (mrb_nil_p(pid)) {
        cgroup_attach_task(mrb_cg_cxt->cg);
    } else {
        cgroup_attach_task_pid(mrb_cg_cxt->cg, mrb_fixnum(pid));
    }
    mrb_iv_set(mrb
        , self
        , mrb_intern_cstr(mrb, "mrb_cgroup_context")
        , mrb_obj_value(Data_Wrap_Struct(mrb
            , mrb->object_class
            , &mrb_cgroup_context_type
            , (void *)mrb_cg_cxt)
        )
    );

    return self;
}
Esempio n. 16
0
mrb_value mrb_discount_init(mrb_state *mrb, mrb_value self)
{
    mrb_md_context *md_ctx = (mrb_md_context *)mrb_malloc(mrb, sizeof(mrb_md_context));
    mrb_value css_path;
    mrb_value title;

    mrb_get_args(mrb, "oo", &css_path, &title);

    md_ctx->css     = RSTRING_PTR(css_path);
    md_ctx->title   = RSTRING_PTR(title);

    mrb_iv_set(mrb
        , self
        , mrb_intern_cstr(mrb, "mrb_md_context")
        , mrb_obj_value(Data_Wrap_Struct(mrb
            , mrb->object_class
            , &mrb_md_context_type
            , (void *)md_ctx)
        )
    );

    return self;
}
Esempio n. 17
0
static mrb_value mrb_ctrdrbg_initialize(mrb_state *mrb, mrb_value self) {
  ctr_drbg_context *ctr_drbg;
  entropy_context *entropy_p;
  mrb_value entp, pers;
  int ret;

  ctr_drbg = (ctr_drbg_context *)DATA_PTR(self);
  if (ctr_drbg) {
    mrb_free(mrb, ctr_drbg);
  }
  DATA_TYPE(self) = &mrb_ctr_drbg_type;
  DATA_PTR(self) = NULL;

  mrb_get_args(mrb, "o|S", &entp, &pers);

  if (mrb_type(entp) != MRB_TT_DATA) {
    mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
  }
  entropy_p = DATA_CHECK_GET_PTR(mrb, entp, &mrb_entropy_type, entropy_context);

  ctr_drbg = (ctr_drbg_context *)mrb_malloc(mrb, sizeof(ctr_drbg_context));
  DATA_PTR(self) = ctr_drbg;

  if (mrb_string_p(pers)) {
    mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@pers"), pers);
    ret = ctr_drbg_init(ctr_drbg, entropy_func, entropy_p, RSTRING_PTR(pers), RSTRING_LEN(pers));
  } else {
    ret = ctr_drbg_init(ctr_drbg, entropy_func, entropy_p, NULL, 0 );
  }

  if (ret == POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED ) {
    mrb_raise(mrb, E_RUNTIME_ERROR, "Could not initialize entropy source");	
  }

  return self;
}
Esempio n. 18
0
static int
parser_settings_on_message_complete(http_parser* parser)
{
  mrb_value c;
  mrb_http_parser_context *context = (mrb_http_parser_context*) parser->data;
  mrb_http_parser_context *new_context;
  mrb_state* mrb = context->mrb;
  mrb_value args[1];

  c = mrb_class_new_instance(mrb, 0, NULL, _class_http_request);
  new_context = (mrb_http_parser_context*) malloc(sizeof(mrb_http_parser_context));
  memcpy(new_context, context, sizeof(mrb_http_parser_context));
  mrb_iv_set(mrb, c, mrb_intern(mrb, "context"), mrb_obj_value(
    Data_Wrap_Struct(mrb, mrb->object_class,
    &http_parser_context_type, (void*) new_context)));
  args[0] = c;
  mrb_yield_argv(context->mrb, context->proc, 1, args);
  PARSER_SET(context, "headers", mrb_nil_value());
  PARSER_SET(context, "last_header_field", mrb_nil_value());
  PARSER_SET(context, "last_header_value", mrb_nil_value());
  PARSER_SET(context, "buf", mrb_nil_value());

  return 0;
}
Esempio n. 19
0
File: io.c Progetto: asfluido/mruby
mrb_value
mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
{
  mrb_value cmd, io;
  mrb_value mode = mrb_str_new_cstr(mrb, "r");
  mrb_value opt  = mrb_hash_new(mrb);

  struct mrb_io *fptr;
  const char *pname;
  int pid = 0, flags;
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  SECURITY_ATTRIBUTES saAttr;

  HANDLE ifd[2];
  HANDLE ofd[2];

  int doexec;
  int opt_in, opt_out, opt_err;

  ifd[0] = INVALID_HANDLE_VALUE;
  ifd[1] = INVALID_HANDLE_VALUE;
  ofd[0] = INVALID_HANDLE_VALUE;
  ofd[1] = INVALID_HANDLE_VALUE;

  mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt);
  io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));

  pname = mrb_string_value_cstr(mrb, &cmd);
  flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode));

  doexec = (strcmp("-", pname) != 0);
  opt_in = option_to_fd(mrb, opt, "in");
  opt_out = option_to_fd(mrb, opt, "out");
  opt_err = option_to_fd(mrb, opt, "err");

  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
  saAttr.bInheritHandle = TRUE;
  saAttr.lpSecurityDescriptor = NULL;

  if (flags & FMODE_READABLE) {
    if (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0)
        || !SetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0)) {
      mrb_sys_fail(mrb, "pipe");
    }
  }

  if (flags & FMODE_WRITABLE) {
    if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0)
        || !SetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)) {
      mrb_sys_fail(mrb, "pipe");
    }
  }

  if (doexec) {
    ZeroMemory(&pi, sizeof(pi));
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags |= STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    si.dwFlags |= STARTF_USESTDHANDLES;
    if (flags & FMODE_READABLE) {
      si.hStdOutput = ofd[1];
      si.hStdError = ofd[1];
    }
    if (flags & FMODE_WRITABLE) {
      si.hStdInput = ifd[0];
    }
    if (!CreateProcess(
        NULL, (char*)pname, NULL, NULL,
        TRUE, CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi)) {
      CloseHandle(ifd[0]);
      CloseHandle(ifd[1]);
      CloseHandle(ofd[0]);
      CloseHandle(ofd[1]);
      mrb_raisef(mrb, E_IO_ERROR, "command not found: %S", cmd);
    }
    CloseHandle(pi.hThread);
    CloseHandle(ifd[0]);
    CloseHandle(ofd[1]);
    pid = pi.dwProcessId;
  }

  mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, ""));

  fptr = mrb_io_alloc(mrb);
  fptr->fd = _open_osfhandle((intptr_t)ofd[0], 0);
  fptr->fd2 = _open_osfhandle((intptr_t)ifd[1], 0);
  fptr->pid = pid;
  fptr->readable = ((flags & FMODE_READABLE) != 0);
  fptr->writable = ((flags & FMODE_WRITABLE) != 0);
  fptr->sync = 0;

  DATA_TYPE(io) = &mrb_io_type;
  DATA_PTR(io)  = fptr;
  return io;
}
Esempio n. 20
0
void
mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v)
{
    mod_const_check(mrb, mod);
    mrb_iv_set(mrb, mod, sym, v);
}
Esempio n. 21
0
void
mrb_vm_iv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
{
    /* get self */
    mrb_iv_set(mrb, mrb->stack[0], sym, v);
}
Esempio n. 22
0
mrb_value
mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
{
  mrb_value cmd, io, result;
  mrb_value mode = mrb_str_new_cstr(mrb, "r");
  mrb_value opt  = mrb_hash_new(mrb);

  struct mrb_io *fptr;
  const char *pname;
  int pid, flags, fd, write_fd = -1;
  int pr[2] = { -1, -1 };
  int pw[2] = { -1, -1 };
  int doexec;
  int saved_errno;

  mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt);
  io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));

  pname = mrb_string_value_cstr(mrb, &cmd);
  flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode));

  doexec = (strcmp("-", pname) != 0);

  if ((flags & FMODE_READABLE) && pipe(pr) == -1) {
    mrb_sys_fail(mrb, "pipe");
  }
  if ((flags & FMODE_WRITABLE) && pipe(pw) == -1) {
    if (pr[0] != -1) close(pr[0]);
    if (pr[1] != -1) close(pr[1]);
    mrb_sys_fail(mrb, "pipe");
  }

  if (!doexec) {
    // XXX
    fflush(stdin);
    fflush(stdout);
    fflush(stderr);
  }

  result = mrb_nil_value();
  switch (pid = fork()) {
    case 0: /* child */
      if (flags & FMODE_READABLE) {
        close(pr[0]);
        if (pr[1] != 1) {
          dup2(pr[1], 1);
          close(pr[1]);
        }
      }
      if (flags & FMODE_WRITABLE) {
        close(pw[1]);
        if (pw[0] != 0) {
          dup2(pw[0], 0);
          close(pw[0]);
        }
      }
      if (doexec) {
        for (fd = 3; fd < NOFILE; fd++) {
          close(fd);
        }
        mrb_proc_exec(pname);
        mrb_raisef(mrb, E_IO_ERROR, "command not found: %S", cmd);
        _exit(127);
      }
      result = mrb_nil_value();
      break;

    default: /* parent */
      if ((flags & FMODE_READABLE) && (flags & FMODE_WRITABLE)) {
        close(pr[1]);
        fd = pr[0];
        close(pw[0]);
        write_fd = pw[1];
      } else if (flags & FMODE_READABLE) {
        close(pr[1]);
        fd = pr[0];
      } else {
        close(pw[0]);
        fd = pw[1];
      }

      mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, ""));
      mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@pos"), mrb_fixnum_value(0));

      fptr = mrb_io_alloc(mrb);
      fptr->fd = fd;
      fptr->fd2 = write_fd;
      fptr->pid = pid;
      fptr->writable = ((flags & FMODE_WRITABLE) != 0);
      fptr->sync = 0;

      DATA_TYPE(io) = &mrb_io_type;
      DATA_PTR(io)  = fptr;
      result = io;
      break;

    case -1: /* error */
      saved_errno = errno;
      if (flags & FMODE_READABLE) {
        close(pr[0]);
        close(pr[1]);
      }
      if (flags & FMODE_WRITABLE) {
        close(pw[0]);
        close(pw[1]);
      }
      errno = saved_errno;
      mrb_sys_fail(mrb, "pipe_open failed.");
      break;
  }
  return result;
}
Esempio n. 23
0
void
mrb_define_const(mrb_state *mrb, struct RClass *mod, const char *name, mrb_value v)
{
  mrb_iv_set(mrb, mrb_obj_value(mod), mrb_intern(mrb, name), v);
}
Esempio n. 24
0
static mrb_value
mrb_sqlite3_database_execute(mrb_state *mrb, mrb_value self) {
  int argc = 0;
  mrb_value* argv = NULL;
  mrb_value b = mrb_nil_value();
  mrb_value value_context;
  mrb_sqlite3_database* db = NULL;
  mrb_value fields;
  int i, r, count;
  sqlite3_stmt* stmt = NULL;
  mrb_value args[2];
  mrb_value query;

  mrb_get_args(mrb, "&S*", &b, &query, &argv, &argc);

  value_context = mrb_iv_get(mrb, self, mrb_intern(mrb, "context"));
  db = NULL;
  Data_Get_Struct(mrb, value_context, &mrb_sqlite3_database_type, db);
  if (!db) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
  }

  r = sqlite3_prepare_v2(db->db, RSTRING_PTR(query), RSTRING_LEN(query),
    &stmt, NULL);
  if (r != SQLITE_OK) {
    if (stmt) {
      sqlite3_finalize(stmt);
      sqlite3_reset(stmt);
    }
    mrb_raise(mrb, E_RUNTIME_ERROR, sqlite3_errmsg(db->db));
  }
  if (!stmt) {
    return mrb_nil_value();
  }

  if (argc > 0) {
    const char* error = bind_values(mrb, db->db, stmt, argc, argv);
    if (error) {
      mrb_raise(mrb, E_ARGUMENT_ERROR, error);
    }
  }

  fields = mrb_ary_new(mrb);
  count = sqlite3_column_count(stmt);
  for (i = 0; i < count; i++) {
    const char* name = sqlite3_column_name(stmt, i);
    mrb_ary_push(mrb, fields, mrb_str_new_cstr(mrb, name));
  }

  if (mrb_nil_p(b)) {
    struct RClass* _class_sqlite3;
    struct RClass* _class_sqlite3_resultset;
    mrb_value c;
    mrb_sqlite3_resultset* rs = (mrb_sqlite3_resultset*)
      malloc(sizeof(mrb_sqlite3_resultset));
    if (!rs) {
      mrb_raise(mrb, E_RUNTIME_ERROR, "can't memory alloc");
    }
    memset(rs, 0, sizeof(mrb_sqlite3_resultset));
    rs->mrb = mrb;
    rs->stmt = stmt;
    _class_sqlite3 = mrb_class_get(mrb, "SQLite3");
    _class_sqlite3_resultset = mrb_class_ptr(mrb_const_get(mrb, mrb_obj_value(_class_sqlite3), mrb_intern(mrb, "ResultSet")));
    c = mrb_class_new_instance(mrb, 0, NULL, _class_sqlite3_resultset);
    mrb_iv_set(mrb, c, mrb_intern(mrb, "context"), mrb_obj_value(
      Data_Wrap_Struct(mrb, mrb->object_class,
      &mrb_sqlite3_resultset_type, (void*) rs)));
    mrb_iv_set(mrb, c, mrb_intern(mrb, "fields"), fields);
    mrb_iv_set(mrb, c, mrb_intern(mrb, "db"), self);
    mrb_iv_set(mrb, c, mrb_intern(mrb, "eof"), mrb_false_value());
    return c;
  }
  while ((r = sqlite3_step(stmt)) == SQLITE_ROW) {
    int ai = mrb_gc_arena_save(mrb);
    args[0] = row_to_value(mrb, stmt);
    args[1] = fields;
    mrb_yield_argv(mrb, b, 2, args);
    mrb_gc_arena_restore(mrb, ai);
  }
  sqlite3_finalize(stmt);
  if (r != SQLITE_OK && r != SQLITE_DONE) {
    mrb_raise(mrb, E_RUNTIME_ERROR, sqlite3_errmsg(db->db));
  }
  return mrb_nil_value();
}
Esempio n. 25
0
static mrb_value
mrb_sce_errno(mrb_state *mrb, mrb_value self)
{
  struct RClass *c;
  mrb_sym sym;

  c = mrb_class(mrb, self);
  sym = mrb_intern_lit(mrb, "Errno");
#if MRUBY_RELEASE_NO < 10000
  if (mrb_const_defined_at(mrb, c, sym)) {
#else
  if (mrb_const_defined_at(mrb, mrb_obj_value(c), sym)) {
#endif
    return mrb_const_get(mrb, mrb_obj_value(c), sym);
  } else {
    sym = mrb_intern_lit(mrb, "errno");
    return mrb_attr_get(mrb, self, sym);
  }
}

static mrb_value
mrb_sce_to_s(mrb_state *mrb, mrb_value self)
{
  return mrb_attr_get(mrb, self, mrb_intern_lit(mrb, "mesg"));
}

static mrb_value
mrb_sce_sys_fail(mrb_state *mrb, mrb_value cls)
{
  struct RClass *cl, *sce;
  mrb_value e, msg;
  mrb_int no;
  int argc;
  char name[8];

  sce = mrb_class_get(mrb, "SystemCallError");
  argc = mrb_get_args(mrb, "i|S", &no, &msg);
  if (argc == 1) {
    e = mrb_funcall(mrb, mrb_obj_value(sce), "new", 1, mrb_fixnum_value(no));
  } else {
    e = mrb_funcall(mrb, mrb_obj_value(sce), "new", 2, msg, mrb_fixnum_value(no));
  }
  if (mrb_obj_class(mrb, e) == sce) {
    snprintf(name, sizeof(name), "E%03ld", (long)no);
    cl = mrb_define_class_under(mrb, mrb_module_get(mrb, "Errno"), name, sce);
    mrb_define_const(mrb, cl, "Errno", mrb_fixnum_value(no));
    mrb_basic_ptr(e)->c = cl;
  }
  mrb_exc_raise(mrb, e);
  return mrb_nil_value();  /* NOTREACHED */
}

static mrb_value
mrb_exxx_init(mrb_state *mrb, mrb_value self)
{
  mrb_value m, no, str;

  no = mrb_const_get(mrb, mrb_obj_value(mrb_class(mrb, self)), mrb_intern_lit(mrb, "Errno"));
  str = mrb_str_new_cstr(mrb, strerror(mrb_fixnum(no)));

  m = mrb_nil_value();
  mrb_get_args(mrb, "|S", &m);
  if (!mrb_nil_p(m)) {
    mrb_str_cat2(mrb, str, " - ");
    mrb_str_append(mrb, str, m);
  }
  mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "mesg"), str);
  return self;
}
Esempio n. 26
0
static mrb_value
mrb_future_init(mrb_state *oldmrb, mrb_value self)
{
  static const struct mrb_context mrb_context_zero = { 0 };
  mrb_state *mrb = mrb_open();
  mrb_future_context *context = (mrb_future_context *) malloc(sizeof(mrb_future_context));
  struct mrb_context *c;
  struct RProc *p;
  mrb_callinfo *ci;
  mrb_value blk;
  size_t slen;
  int argc;
  mrb_value* argv;

  *mrb = *oldmrb;
  mrb_get_args(mrb, "*&", &argv, &argc, &blk);

  p = mrb_proc_ptr(blk);

  c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
  *c = mrb_context_zero;
  mrb->c = c;
  context->mrb = mrb;
  context->oldmrb = oldmrb;
  context->proc = mrb_proc_ptr(blk);
  context->argc = argc;
  context->argv = argv;
  context->self = self;

  /* initialize VM stack */
  slen = FIBER_STACK_INIT_SIZE;
  if (!MRB_PROC_CFUNC_P(p) && p->body.irep->nregs > slen) {
    slen += p->body.irep->nregs;
  }
  c->stbase = (mrb_value *)mrb_malloc(mrb, slen*sizeof(mrb_value));
  c->stend = c->stbase + slen;
  c->stack = c->stbase;

#ifdef MRB_NAN_BOXING
  {
    mrb_value *p = c->stbase;
    mrb_value *pend = c->stend;
    
    while (p < pend) {
      SET_NIL_VALUE(*p);
      p++;
    }
  }
#else
  memset(c->stbase, 0, slen * sizeof(mrb_value));
#endif

  /* copy future object(self) from a block */
  c->stack[0] = self;

  /* initialize callinfo stack */
  c->cibase = (mrb_callinfo *)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo));
  c->ciend = c->cibase + FIBER_CI_INIT_SIZE;
  c->ci = c->cibase;
  c->ci->stackent = c->stack;

  /* adjust return callinfo */
  ci = c->ci;
  ci->target_class = p->target_class;
  ci->proc = p;
  if (!MRB_PROC_CFUNC_P(p)) {
    ci->pc = p->body.irep->iseq;
    ci->nregs = p->body.irep->nregs;
  }
  ci[1] = ci[0];
  c->ci++;                      /* push dummy callinfo */

  mrb_iv_set(oldmrb, self, mrb_intern_cstr(oldmrb, "_context"), mrb_cptr_value(oldmrb, context));
  mrb_iv_set(oldmrb, self, mrb_intern_cstr(oldmrb, "_state"), mrb_fixnum_value(FUTURE_RUNNING));

  pthread_create(&context->thread, NULL, &mrb_future_func, (void *)context);

  return self;
}
mrb_value
regexp_pcre_match(mrb_state *mrb, mrb_value self)
{
  struct mrb_matchdata *mrb_md;
  int rc;
  int ccount, matchlen;
  int *match;
  struct RClass *c;
  mrb_value md, str;
  mrb_int i, pos;
  pcre_extra extra;
  struct mrb_regexp_pcre *reg;

  reg = (struct mrb_regexp_pcre *)mrb_get_datatype(mrb, self, &mrb_regexp_type);
  if (!reg)
    return mrb_nil_value();

  pos = 0;
  mrb_get_args(mrb, "S|i", &str, &pos);

  // XXX: RSTRING_LEN(str) >= pos ...

  rc = pcre_fullinfo(reg->re, NULL, PCRE_INFO_CAPTURECOUNT, &ccount);
  if (rc < 0) {
    /* fullinfo error */
    return mrb_nil_value();
  }
  matchlen = ccount + 1;
  match = mrb_malloc(mrb, sizeof(int) * matchlen * 3);

  extra.flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION;
  extra.match_limit_recursion = 1000;
  rc = pcre_exec(reg->re, &extra, RSTRING_PTR(str), RSTRING_LEN(str), pos, 0, match, matchlen * 3);
  if (rc < 0) {
    mrb_free(mrb, match);
    return mrb_nil_value();
  }

  /* XXX: need current scope */
  mrb_obj_iv_set(mrb, (struct RObject *)mrb_class_real(RDATA(self)->c), mrb_intern_lit(mrb, "@last_match"), mrb_nil_value());

  c = mrb_class_get(mrb, "MatchData");
  md = mrb_funcall(mrb, mrb_obj_value(c), "new", 0);

  mrb_md = (struct mrb_matchdata *)mrb_get_datatype(mrb, md, &mrb_matchdata_type);
  mrb_md->ovector = match;
  mrb_md->length = matchlen;

  mrb_iv_set(mrb, md, mrb_intern_lit(mrb, "@regexp"), self);
  mrb_iv_set(mrb, md, mrb_intern_lit(mrb, "@string"), mrb_str_dup(mrb, str));
  /* XXX: need current scope */
  mrb_obj_iv_set(mrb, (struct RObject *)mrb_class_real(RDATA(self)->c), mrb_intern_lit(mrb, "@last_match"), md);

  mrb_gv_set(mrb, mrb_intern_lit(mrb, "$~"), md);
  mrb_gv_set(mrb, mrb_intern_lit(mrb, "$&"), mrb_funcall(mrb, md, "to_s", 0));
  mrb_gv_set(mrb, mrb_intern_lit(mrb, "$`"), mrb_funcall(mrb, md, "pre_match", 0));
  mrb_gv_set(mrb, mrb_intern_lit(mrb, "$'"), mrb_funcall(mrb, md, "post_match", 0));

  for (i = 1; i < 10; i++) {
    char sym[8];
    snprintf(sym, sizeof(sym), "$%d", i);
    mrb_gv_set(mrb, mrb_intern_cstr(mrb, sym), mrb_funcall(mrb, md, "[]", 1, mrb_fixnum_value(i)));
  }

  return md;
}
Esempio n. 28
0
static mrb_value
mrb_grn_table_cursor_class_open_raw(mrb_state *mrb, mrb_value klass)
{
  grn_ctx *ctx = (grn_ctx *)mrb->ud;
  mrb_value mrb_table;
  mrb_value mrb_options = mrb_nil_value();
  grn_table_cursor *table_cursor;
  grn_obj *table;
  void *min = NULL;
  unsigned int min_size = 0;
  grn_mrb_value_to_raw_data_buffer min_buffer;
  void *max = NULL;
  unsigned int max_size = 0;
  grn_mrb_value_to_raw_data_buffer max_buffer;
  int offset = 0;
  int limit = -1;
  int flags = 0;

  mrb_get_args(mrb, "o|H", &mrb_table, &mrb_options);

  table = DATA_PTR(mrb_table);
  grn_mrb_value_to_raw_data_buffer_init(mrb, &min_buffer);
  grn_mrb_value_to_raw_data_buffer_init(mrb, &max_buffer);
  if (!mrb_nil_p(mrb_options)) {
    grn_id key_domain_id;
    mrb_value mrb_min;
    mrb_value mrb_max;
    mrb_value mrb_flags;

    if (table->header.type == GRN_DB) {
      key_domain_id = GRN_DB_SHORT_TEXT;
    } else {
      key_domain_id = table->header.domain;
    }

    mrb_min = grn_mrb_options_get_lit(mrb, mrb_options, "min");
    grn_mrb_value_to_raw_data(mrb, "min", mrb_min,
                              key_domain_id, &min_buffer, &min, &min_size);

    mrb_max = grn_mrb_options_get_lit(mrb, mrb_options, "max");
    grn_mrb_value_to_raw_data(mrb, "max", mrb_max,
                              key_domain_id, &max_buffer, &max, &max_size);

    mrb_flags = grn_mrb_options_get_lit(mrb, mrb_options, "flags");
    if (!mrb_nil_p(mrb_flags)) {
      flags = mrb_fixnum(mrb_flags);
    }
  }
  table_cursor = grn_table_cursor_open(ctx, table,
                                       min, min_size,
                                       max, max_size,
                                       offset, limit, flags);
  grn_mrb_value_to_raw_data_buffer_fin(mrb, &min_buffer);
  grn_mrb_value_to_raw_data_buffer_fin(mrb, &max_buffer);
  grn_mrb_ctx_check(mrb);

  {
    mrb_value mrb_table_cursor;
    mrb_table_cursor = mrb_funcall(mrb, klass,
                                   "new", 1, mrb_cptr_value(mrb, table_cursor));
    mrb_iv_set(mrb, mrb_table_cursor, mrb_intern_lit(mrb, "@table"), mrb_table);
    return mrb_table_cursor;
  }
}
Esempio n. 29
0
mrb_value
qgame_texture_asset_load_from_file(mrb_state* mrb, mrb_value self)
{
  GLuint texture;     // This is a handle to our texture object
  SDL_Surface *surface; // This surface will tell us the details of the image
  GLenum texture_format;

  mrb_value path;
  mrb_get_args(mrb, "S", &path);
  char* file = mrb_string_value_ptr(mrb, path);

  if ( (surface = IMG_Load(file)) ) { 
    // Check that the image's width is a power of 2
    if ( (surface->w & (surface->w - 1)) != 0 ) {
      printf("warning: %s's width is not a power of 2\n", file);
    }
   
    // Also check if the height is a power of 2
    if ( (surface->h & (surface->h - 1)) != 0 ) {
      printf("warning: %s's height is not a power of 2\n", file);
    }

    // get the number of channels in the SDL surface
    GLint  nOfColors = surface->format->BytesPerPixel;
    if (nOfColors == 4)     // contains an alpha channel
    {
      if (surface->format->Rmask == 0x000000ff)
        texture_format = GL_RGBA;
      else
        texture_format = GL_BGRA;
    } else if (nOfColors == 3)     // no alpha channel
    {
      if (surface->format->Rmask == 0x000000ff)
        texture_format = GL_RGB;
      else
        texture_format = GL_BGRA;
    } else {
      printf("warning: the image is not truecolor..  this will probably break\n");
    }

    // Have OpenGL generate a texture object handle for us
    glGenTextures( 1, &texture );
   
    // Bind the texture object
    glBindTexture( GL_TEXTURE_2D, texture );
   
    // Set the texture's stretching properties
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    // Edit the texture object's image data using the information SDL_Surface gives us
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
                        texture_format, GL_UNSIGNED_BYTE, surface->pixels );
    
    GLenum err = glGetError();
    if (err != GL_NO_ERROR) {
      printf("Error loading image into GL: %i\n", err);
    }
    
    mrb_value texture_id = mrb_fixnum_value(texture);
    mrb_iv_set(mrb, self, mrb_intern(mrb, "texture_id"), texture_id);
    
    mrb_value mrb_width = mrb_fixnum_value(surface->w);
    mrb_iv_set(mrb, self, mrb_intern(mrb, "@width"), mrb_width);
  
    mrb_value mrb_height = mrb_fixnum_value(surface->h);
    mrb_iv_set(mrb, self, mrb_intern(mrb, "@height"), mrb_height);
  }
  else {
    printf("SDL could not load image.bmp: %s\n", SDL_GetError());
  }    

  // Free the SDL_Surface only if it was successfully created
  if ( surface ) { 
    SDL_FreeSurface( surface );
  }

  return self;
}
Esempio n. 30
0
static mrb_value
mrb_jpeg_decompress_common(mrb_state *mrb, mrb_value self, enum decompress_type dtype)
{
  struct jpeg_decompress_struct dinfo;
  struct jpeg_error_mgr jpeg_error;
  long scanline_size;
  void *jpeg_data;
  int row = 0;
  struct RClass* module_jpeg;
  struct RClass* class_jpeg_image;
  mrb_value ivar;

  mrb_value arg_config_hash = mrb_nil_value();
  mrb_value arg_data = mrb_nil_value();

  int argc = mrb_get_args(mrb, "S|H", &arg_data, &arg_config_hash);
  if (mrb_nil_p(arg_data) || mrb_type(arg_data) != MRB_TT_STRING) 
  {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "Invalid argument");
  }
  if(argc > 1 && mrb_type(arg_config_hash) != MRB_TT_HASH)
  {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "Invalid argument");
  }
  
  dinfo.client_data = mrb;

  dinfo.err = jpeg_std_error(&jpeg_error);
  dinfo.err->error_exit = jpeg_error_func;

  jpeg_create_decompress(&dinfo);

  if(dtype == FILE_SRC)
  {
    FILE *fp = fopen(RSTRING_PTR(arg_data), "r");
    if(fp == NULL)
    {
      jpeg_destroy_decompress(&dinfo);
      mrb_raise(mrb, E_RUNTIME_ERROR, "Could not open input file.");
    }
    jpeg_stdio_src(&dinfo, fp);
  }
  else
  {
    jpeg_memory_src(&dinfo, (const JOCTET *)RSTRING_PTR(arg_data), RSTRING_LEN(arg_data));
  }

  jpeg_read_header(&dinfo, 1); 

  if(!mrb_obj_equal(mrb, arg_config_hash, mrb_nil_value()) && HASH_TRUE(mrb, arg_config_hash, "force_grayscale"))
  {
    dinfo.output_components = 1;
  }
  else
  {
    if (dinfo.out_color_space == JCS_GRAYSCALE) 
    {
      dinfo.output_components = 1;
    }
    else 
    {
      dinfo.output_components = 3;
      dinfo.out_color_space = JCS_RGB;
    }
  }

  jpeg_start_decompress(&dinfo);

  scanline_size = dinfo.image_width * dinfo.output_components;
  jpeg_data = malloc(scanline_size * dinfo.image_height);

  for(row = 0; row < dinfo.image_height; row++)
  {
    JSAMPROW jpeg_row = (JSAMPROW)(jpeg_data + (scanline_size * row));
    jpeg_read_scanlines(&dinfo, &jpeg_row, 1);
  }

  module_jpeg = mrb_module_get(mrb, "JPEG");
  class_jpeg_image = mrb_class_ptr(mrb_const_get(mrb, mrb_obj_value(module_jpeg), mrb_intern_lit(mrb, "JPEGImage")));
  ivar = mrb_class_new_instance(mrb, 0, NULL, class_jpeg_image);
  mrb_iv_set(mrb, ivar, mrb_intern_lit(mrb, "data"), mrb_str_new(mrb, jpeg_data, scanline_size * dinfo.image_height));
  mrb_iv_set(mrb, ivar, mrb_intern_lit(mrb, "width"), mrb_fixnum_value(dinfo.image_width));
  mrb_iv_set(mrb, ivar, mrb_intern_lit(mrb, "height"), mrb_fixnum_value(dinfo.image_height));

  jpeg_finish_decompress(&dinfo);
  jpeg_destroy_decompress(&dinfo);

  return ivar;
}