// Bitmaps static mrb_value mrb_sdl_video_load_bmp (mrb_state *mrb, mrb_value self) { const char *file; mrb_get_args(mrb, "|s", &file); return sdl_surface_to_mrb_value(mrb, self, SDL_LoadBMP(file)); }
static mrb_value mrb_attr_get_oradate(mrb_state *mrb, mrb_value self) { mrb_value attr_type; mrb_get_args(mrb, "i", &attr_type); return attr_get_oradate(self, attr_type); }
static mrb_value http_request_method(mrb_state *mrb, mrb_value self) { h2o_mruby_generator_t *generator; struct st_h2o_mruby_http_request_context_t *ctx; const char *arg_url; mrb_int arg_url_len; mrb_value arg_hash; h2o_iovec_t method; h2o_url_t url; /* parse args */ arg_hash = mrb_nil_value(); mrb_get_args(mrb, "s|H", &arg_url, &arg_url_len, &arg_hash); /* precond check */ if ((generator = h2o_mruby_current_generator) == NULL || generator->req == NULL) mrb_exc_raise(mrb, create_downstream_closed_exception(mrb)); /* allocate context and initialize */ ctx = h2o_mem_alloc_shared(&generator->req->pool, sizeof(*ctx), on_dispose); memset(ctx, 0, sizeof(*ctx)); ctx->generator = generator; ctx->receiver = mrb_nil_value(); h2o_buffer_init(&ctx->req.buf, &h2o_socket_buffer_prototype); h2o_buffer_init(&ctx->resp.after_closed, &h2o_socket_buffer_prototype); ctx->refs.request = mrb_nil_value(); ctx->refs.input_stream = mrb_nil_value(); /* uri */ if (h2o_url_parse(arg_url, arg_url_len, &url) != 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "invaild URL"); /* method */ method = h2o_iovec_init(H2O_STRLIT("GET")); if (mrb_hash_p(arg_hash)) { mrb_value t = mrb_hash_get(mrb, arg_hash, mrb_symbol_value(generator->ctx->shared->symbols.sym_method)); if (!mrb_nil_p(t)) { t = mrb_str_to_str(mrb, t); method = h2o_iovec_init(RSTRING_PTR(t), RSTRING_LEN(t)); } } /* start building the request */ h2o_buffer_reserve(&ctx->req.buf, method.len + 1); append_to_buffer(&ctx->req.buf, method.base, method.len); append_to_buffer(&ctx->req.buf, H2O_STRLIT(" ")); h2o_buffer_reserve(&ctx->req.buf, url.path.len + url.authority.len + sizeof(" HTTP/1.1\r\nConnection: close\r\nHost: \r\n") - 1); append_to_buffer(&ctx->req.buf, url.path.base, url.path.len); append_to_buffer(&ctx->req.buf, H2O_STRLIT(" HTTP/1.1\r\nConnection: close\r\nHost: ")); append_to_buffer(&ctx->req.buf, url.authority.base, url.authority.len); append_to_buffer(&ctx->req.buf, H2O_STRLIT("\r\n")); /* headers */ if (mrb_hash_p(arg_hash)) { mrb_value headers = mrb_hash_get(mrb, arg_hash, mrb_symbol_value(generator->ctx->shared->symbols.sym_headers)); if (!mrb_nil_p(headers)) { if (h2o_mruby_iterate_headers(generator->ctx, headers, flatten_request_header, ctx) != 0) { mrb_value exc = mrb_obj_value(mrb->exc); mrb->exc = NULL; mrb_exc_raise(mrb, exc); } } } /* body */ if (mrb_hash_p(arg_hash)) { mrb_value body = mrb_hash_get(mrb, arg_hash, mrb_symbol_value(generator->ctx->shared->symbols.sym_body)); if (!mrb_nil_p(body)) { if (mrb_obj_eq(mrb, body, generator->rack_input)) { /* fast path */ mrb_int pos; mrb_input_stream_get_data(mrb, body, NULL, NULL, &pos, NULL, NULL); ctx->req.body = generator->req->entity; ctx->req.body.base += pos; ctx->req.body.len -= pos; } else { if (!mrb_string_p(body)) { body = mrb_funcall(mrb, body, "read", 0); if (!mrb_string_p(body)) mrb_raise(mrb, E_ARGUMENT_ERROR, "body.read did not return string"); } ctx->req.body = h2o_strdup(&ctx->generator->req->pool, RSTRING_PTR(body), RSTRING_LEN(body)); } if (!ctx->req.has_transfer_encoding) { char buf[64]; size_t l = (size_t)sprintf(buf, "content-length: %zu\r\n", ctx->req.body.len); h2o_buffer_reserve(&ctx->req.buf, l); append_to_buffer(&ctx->req.buf, buf, l); } } } h2o_buffer_reserve(&ctx->req.buf, 2); append_to_buffer(&ctx->req.buf, H2O_STRLIT("\r\n")); /* build request and connect */ h2o_http1client_connect(&ctx->client, ctx, &generator->req->conn->ctx->proxy.client_ctx, url.host, h2o_url_get_port(&url), url.scheme == &H2O_URL_SCHEME_HTTPS, on_connect); ctx->refs.request = h2o_mruby_create_data_instance( mrb, mrb_ary_entry(generator->ctx->shared->constants, H2O_MRUBY_HTTP_REQUEST_CLASS), ctx, &request_type); return ctx->refs.request; }
static mrb_value mrb_ary_clear_m(mrb_state *mrb, mrb_value self) { mrb_get_args(mrb, ""); return mrb_ary_clear(mrb, self); }
// FLTK.width(text) // Get the width of a string. mrb_value mrb_fltk_width_module_method( mrb_state *mrb, mrb_value self ) { char *text; mrb_get_args( mrb, "z", &text ); return mrb_fixnum_value( fl_width( text ) ); }
/******************************************************************************* * GL module * * TODO: * - Figure out SDL_GL_GetProcAddress, SDL_GL_GetAttribute, SDL_GL_SetAttribute ******************************************************************************/ static mrb_value mrb_sdl_gl_load_library (mrb_state *mrb, mrb_value self) { const char *path; mrb_get_args(mrb, "|s", &path); return mrb_fixnum_value(SDL_GL_LoadLibrary(path)); }
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; }
// Init static mrb_value mrb_sdl_init (mrb_state *mrb, mrb_value self) { mrb_int flags = SDL_INIT_EVERYTHING; mrb_get_args(mrb, "|i", &flags); return mrb_fixnum_value(SDL_Init(flags)); }
static mrb_value mrb_sdl_init_sub_system (mrb_state *mrb, mrb_value self) { mrb_int flags; mrb_get_args(mrb, "|i", &flags); return mrb_fixnum_value(SDL_InitSubSystem(flags)); }
// like Nginx rewrite keywords // used like this: // => http code 3xx location in browser // => internal redirection in nginx static mrb_value ngx_mrb_redirect(mrb_state *mrb, mrb_value self) { int argc; u_char *str; ngx_int_t rc; mrb_value uri, code; ngx_str_t ns; ngx_table_elt_t *location; ngx_http_request_t *r = ngx_mrb_get_request(); argc = mrb_get_args(mrb, "o|oo", &uri, &code); // get status code from args if (argc == 2) { rc = mrb_fixnum(code); } else { rc = NGX_HTTP_MOVED_TEMPORARILY; } // get redirect uri from args if (mrb_type(uri) != MRB_TT_STRING) { uri = mrb_funcall(mrb, uri, "to_s", 0, NULL); } // save location uri to ns ns.len = RSTRING_LEN(uri); if (ns.len == 0) { return mrb_nil_value(); } ns.data = ngx_palloc(r->pool, ns.len); ngx_memcpy(ns.data, RSTRING_PTR(uri), ns.len); // if uri start with scheme prefix // return 3xx for redirect // else generate a internal redirection and response to raw request // request.path is not changed if (ngx_strncmp(ns.data, "http://", sizeof("http://") - 1) == 0 || ngx_strncmp(ns.data, "https://", sizeof("https://") - 1) == 0 || ngx_strncmp(ns.data, "$scheme", sizeof("$scheme") - 1) == 0) { str = ngx_pstrdup(r->pool, &ns); if (str == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } str[ns.len] = '\0'; // build redirect location location = ngx_list_push(&r->headers_out.headers); if (location == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } location->hash = 1; ngx_str_set(&location->key, "Location"); location->value = ns; location->lowcase_key = ngx_pnalloc(r->pool, location->value.len); if (location->lowcase_key == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } ngx_strlow(location->lowcase_key, location->value.data, location->value.len); // set location and response code for hreaders r->headers_out.location = location; r->headers_out.status = rc; } else { ngx_http_internal_redirect(r, &ns, &r->args); ngx_http_finalize_request(r, NGX_DONE); } return self; }
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; }
static mrb_value ngx_mrb_echo(mrb_state *mrb, mrb_value self) { mrb_value argv; ngx_buf_t *b; ngx_mrb_rputs_chain_list_t *chain; u_char *str; ngx_str_t ns; ngx_http_request_t *r = ngx_mrb_get_request(); ngx_http_mruby_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_mruby_module); mrb_get_args(mrb, "o", &argv); if (mrb_type(argv) != MRB_TT_STRING) { argv = mrb_funcall(mrb, argv, "to_s", 0, NULL); } ns.data = (u_char *)RSTRING_PTR( mrb_str_plus(mrb, argv, mrb_str_new_lit(mrb, "\n"))); ns.len = RSTRING_LEN(argv) + sizeof("\n") - 1; if (ns.len == 0) { return self; } if (ctx->rputs_chain == NULL) { chain = ngx_pcalloc(r->pool, sizeof(ngx_mrb_rputs_chain_list_t)); if (chain == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } chain->out = ngx_alloc_chain_link(r->pool); if (chain->out == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } chain->last = &chain->out; } else { chain = ctx->rputs_chain; (*chain->last)->next = ngx_alloc_chain_link(r->pool); if ((*chain->last)->next == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } chain->last = &(*chain->last)->next; } b = ngx_calloc_buf(r->pool); if (b == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } (*chain->last)->buf = b; (*chain->last)->next = NULL; str = ngx_pstrdup(r->pool, &ns); if (str == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "failed to allocate memory"); } str[ns.len] = '\0'; (*chain->last)->buf->pos = str; (*chain->last)->buf->last = str + ns.len; (*chain->last)->buf->memory = 1; ctx->rputs_chain = chain; ngx_http_set_ctx(r, ctx, ngx_http_mruby_module); if (r->headers_out.content_length_n == -1) { r->headers_out.content_length_n += ns.len + 1; } else { r->headers_out.content_length_n += ns.len; } return self; }
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; }
static mrb_value cfunc_call(mrb_state *mrb, mrb_value self) { int margc; mrb_value mresult_type, mname, *margs; void **values = NULL; ffi_type **args = NULL; mrb_get_args(mrb, "oo*", &mresult_type, &mname, &margs, &margc); void *fp = NULL; if(mrb_string_p(mname) || mrb_symbol_p(mname)) { void *dlh = dlopen(NULL, RTLD_LAZY); fp = dlsym(dlh, mrb_string_value_ptr(mrb, mname)); dlclose(dlh); if(fp == NULL) { mrb_raisef(mrb, E_NAME_ERROR, "can't find C function %s", mrb_string_value_ptr(mrb, mname)); goto cfunc_call_exit; } } else { fp = cfunc_pointer_ptr(mname); if(fp == NULL) { mrb_raisef(mrb, E_NAME_ERROR, "can't call NULL pointer"); goto cfunc_call_exit; } } args = malloc(sizeof(ffi_type*) * margc); values = malloc(sizeof(void*) * margc); mrb_sym sym_to_ffi_value = mrb_intern(mrb, "to_ffi_value"); mrb_value nil_ary[1]; nil_ary[0] = mrb_nil_value(); int i; for(i = 0; i < margc; ++i) { if(mrb_respond_to(mrb, margs[i], sym_to_ffi_value)) { args[i] = mrb_value_to_mrb_ffi_type(mrb, margs[i])->ffi_type_value; values[i] = cfunc_pointer_ptr(mrb_funcall_argv(mrb, margs[i], sym_to_ffi_value, 1, nil_ary)); } else { cfunc_mrb_raise_without_jump(mrb, E_TYPE_ERROR, "ignore argument type %s", mrb_obj_classname(mrb, margs[i])); goto cfunc_call_exit; } } ffi_type *result_type = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(mresult_type))->ffi_type_value; if (result_type == NULL) { cfunc_mrb_raise_without_jump(mrb, E_ARGUMENT_ERROR, "ignore return type %s", mrb_class_name(mrb, mrb_class_ptr(mresult_type))); goto cfunc_call_exit; } mrb_value mresult = mrb_nil_value(); ffi_cif cif; if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, margc, result_type, args) == FFI_OK) { void *result; if(result_type->size > sizeof(long)) { result = malloc(result_type->size); } else if(result_type->size) { result = malloc(sizeof(long)); } else { result = NULL; } ffi_call(&cif, fp, result, values); if(result) { mrb_value result_ptr = cfunc_pointer_new_with_pointer(mrb, result, true); mresult = mrb_funcall(mrb, mresult_type, "refer", 1, result_ptr); } } else { mrb_raisef(mrb, E_NAME_ERROR, "Can't find C function %s", mname); goto cfunc_call_exit; } cfunc_call_exit: free(values); free(args); return mresult; }
static mrb_value mrb_sdl_video_lock_yuv_overlay (mrb_state *mrb, mrb_value self) { mrb_value overlay = mrb_nil_value(); mrb_get_args(mrb, "|o", &overlay); return mrb_fixnum_value(SDL_LockYUVOverlay(mrb_value_to_sdl_overlay(mrb, overlay))); }
static mrb_value mrb_sdl_quit_sub_system (mrb_state *mrb, mrb_value self) { mrb_int flags; mrb_get_args(mrb, "|i", &flags); SDL_QuitSubSystem(flags); return mrb_nil_value(); }
static mrb_value mrb_sdl_video_free_yuv_overlay (mrb_state *mrb, mrb_value self) { mrb_value overlay = mrb_nil_value(); mrb_get_args(mrb, "|o", &overlay); SDL_FreeYUVOverlay(mrb_value_to_sdl_overlay(mrb, overlay)); return mrb_nil_value(); }
// Checking static mrb_value mrb_sdl_was_init (mrb_state *mrb, mrb_value self) { mrb_int flags; mrb_get_args(mrb, "|i", &flags); return mrb_fixnum_value(SDL_WasInit(flags)); }
static mrb_value ngx_mrb_var_set_func(mrb_state *mrb, mrb_value self) { ngx_http_request_t *r; ngx_http_variable_t *v; ngx_http_variable_value_t *vv; ngx_http_core_main_conf_t *cmcf; ngx_str_t key, val; ngx_uint_t hash; mrb_value k; mrb_value o; u_char *keyp, *valp; mrb_get_args(mrb, "oo", &k, &o); if (mrb_type(k) != MRB_TT_STRING) { k = mrb_funcall(mrb, k, "to_s", 0, NULL); } if (mrb_type(o) != MRB_TT_STRING) { o = mrb_funcall(mrb, o, "to_s", 0, NULL); } r = ngx_mrb_get_request(); key.data = (u_char *)RSTRING_PTR(k); key.len = RSTRING_LEN(k); val.data = (u_char *)RSTRING_PTR(o); val.len = RSTRING_LEN(o); /* RSTRING_PTR(k) is not always null-terminated */ keyp = ngx_palloc(r->pool, key.len + 1); if (keyp == NULL) { ngx_log_error(NGX_LOG_ERR , r->connection->log , 0 , "%s ERROR %s:%d: memory allocate failed" , MODULE_NAME , __func__ , __LINE__ ); goto ARENA_RESTOR_AND_ERROR; } /* RSTRING_PTR(o) is not always null-terminated */ valp = ngx_palloc(r->pool, val.len + 1); if (valp == NULL) { ngx_log_error(NGX_LOG_ERR , r->connection->log , 0 , "%s ERROR %s:%d: memory allocate failed" , MODULE_NAME , __func__ , __LINE__ ); goto ARENA_RESTOR_AND_ERROR; } ngx_cpystrn(keyp, key.data, key.len + 1); ngx_cpystrn(valp, val.data, val.len + 1); hash = ngx_hash_strlow(key.data, key.data, key.len); cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); v = ngx_hash_find(&cmcf->variables_hash, hash, key.data, key.len); if (v) { if (!(v->flags & NGX_HTTP_VAR_CHANGEABLE)) { ngx_log_error(NGX_LOG_ERR , r->connection->log , 0 , "%s ERROR %s:%d: %s not changeable" , MODULE_NAME , __func__ , __LINE__ , keyp ); goto ARENA_RESTOR_AND_ERROR; } else if (v->set_handler) { vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); if (vv == NULL) { ngx_log_error(NGX_LOG_ERR , r->connection->log , 0 , "%s ERROR %s:%d: memory allocate failed" , MODULE_NAME , __func__ , __LINE__ ); goto ARENA_RESTOR_AND_ERROR; } v->set_handler(r, vv, v->data); } else if (v->flags & NGX_HTTP_VAR_INDEXED) { vv = &r->variables[v->index]; } else { ngx_log_error(NGX_LOG_ERR , r->connection->log , 0 , "%s ERROR %s:%d: %s is not assinged" , MODULE_NAME , __func__ , __LINE__ , keyp ); goto ARENA_RESTOR_AND_ERROR; } vv->valid = 1; vv->not_found = 0; vv->no_cacheable = 0; vv->data = val.data; vv->len = val.len; ngx_log_error(NGX_LOG_INFO , r->connection->log , 0 , "%s INFO %s:%d: set variable key:%s val:%s" , MODULE_NAME , __func__ , __LINE__ , keyp , valp ); return mrb_str_new(mrb, (char *)vv->data, vv->len); } ngx_log_error(NGX_LOG_ERR , r->connection->log , 0 , "%s ERROR %s:%d: %s is not found" , MODULE_NAME , __func__ , __LINE__ , keyp ); ARENA_RESTOR_AND_ERROR: return mrb_nil_value(); }
static mrb_value mrb_sdl_error (mrb_state *mrb, mrb_value self) { mrb_int code; mrb_get_args(mrb, "|i", &code); SDL_Error(code); return mrb_nil_value(); }
static mrb_value mrb_grn_expression_append_constant(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *expr; mrb_value mrb_constant; mrb_value mrb_op; grn_operator op; mrb_int n_args; expr = DATA_PTR(self); mrb_get_args(mrb, "ooi", &mrb_constant, &mrb_op, &n_args); op = grn_mrb_value_to_operator(mrb, mrb_op); switch (mrb_type(mrb_constant)) { case MRB_TT_FALSE : if (mrb_nil_p(mrb_constant)) { grn_obj constant; GRN_VOID_INIT(&constant); grn_expr_append_const(ctx, expr, &constant, op, n_args); GRN_OBJ_FIN(ctx, &constant); } else { grn_obj constant; GRN_BOOL_INIT(&constant, 0); GRN_BOOL_SET(ctx, &constant, GRN_FALSE); grn_expr_append_const(ctx, expr, &constant, op, n_args); GRN_OBJ_FIN(ctx, &constant); } break; case MRB_TT_TRUE : { grn_obj constant; GRN_BOOL_INIT(&constant, 0); GRN_BOOL_SET(ctx, &constant, GRN_TRUE); grn_expr_append_const(ctx, expr, &constant, op, n_args); GRN_OBJ_FIN(ctx, &constant); } break; case MRB_TT_FIXNUM : grn_expr_append_const_int(ctx, expr, mrb_fixnum(mrb_constant), op, n_args); break; case MRB_TT_SYMBOL : { const char *value; mrb_int value_length; value = mrb_sym2name_len(mrb, mrb_symbol(mrb_constant), &value_length); grn_expr_append_const_str(ctx, expr, value, value_length, op, n_args); } break; case MRB_TT_FLOAT : { grn_obj constant; GRN_FLOAT_INIT(&constant, 0); GRN_FLOAT_SET(ctx, &constant, mrb_float(mrb_constant)); grn_expr_append_const(ctx, expr, &constant, op, n_args); GRN_OBJ_FIN(ctx, &constant); } break; case MRB_TT_STRING : grn_expr_append_const_str(ctx, expr, RSTRING_PTR(mrb_constant), RSTRING_LEN(mrb_constant), op, n_args); break; default : { struct RClass *klass; klass = mrb_class(mrb, mrb_constant); if (klass == ctx->impl->mrb.builtin.time_class) { grn_obj constant; mrb_value mrb_sec; mrb_value mrb_usec; mrb_sec = mrb_funcall(mrb, mrb_constant, "to_i", 0); mrb_usec = mrb_funcall(mrb, mrb_constant, "usec", 0); GRN_TIME_INIT(&constant, 0); GRN_TIME_SET(ctx, &constant, GRN_TIME_PACK(mrb_fixnum(mrb_sec), mrb_fixnum(mrb_usec))); grn_expr_append_const(ctx, expr, &constant, op, n_args); GRN_OBJ_FIN(ctx, &constant); } else { mrb_raisef(mrb, E_ARGUMENT_ERROR, "unsupported constant to append to expression: %S", mrb_constant); } } break; } grn_mrb_ctx_check(mrb); return mrb_nil_value(); }
static mrb_value mrb_sdl_video_flip (mrb_state *mrb, mrb_value self) { mrb_value surface = mrb_nil_value(); mrb_get_args(mrb, "|o", &surface); return mrb_fixnum_value(SDL_Flip(mrb_value_to_sdl_surface(mrb, surface))); }
static mrb_value mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass) { struct addrinfo hints, *res0, *res; mrb_value ai, ary, family, lastai, nodename, protocol, sa, service, socktype; mrb_int flags; int arena_idx, error; const char *hostname = NULL, *servname = NULL; ary = mrb_ary_new(mrb); arena_idx = mrb_gc_arena_save(mrb); /* ary must be on arena! */ family = socktype = protocol = mrb_nil_value(); flags = 0; mrb_get_args(mrb, "oo|oooi", &nodename, &service, &family, &socktype, &protocol, &flags); if (mrb_string_p(nodename)) { hostname = mrb_str_to_cstr(mrb, nodename); } else if (mrb_nil_p(nodename)) { hostname = NULL; } else { mrb_raise(mrb, E_TYPE_ERROR, "nodename must be String or nil"); } if (mrb_string_p(service)) { servname = mrb_str_to_cstr(mrb, service); } else if (mrb_fixnum_p(service)) { servname = mrb_str_to_cstr(mrb, mrb_funcall(mrb, service, "to_s", 0)); } else if (mrb_nil_p(service)) { servname = NULL; } else { mrb_raise(mrb, E_TYPE_ERROR, "service must be String, Fixnum, or nil"); } memset(&hints, 0, sizeof(hints)); hints.ai_flags = flags; if (mrb_fixnum_p(family)) { hints.ai_family = mrb_fixnum(family); } if (mrb_fixnum_p(socktype)) { hints.ai_socktype = mrb_fixnum(socktype); } lastai = mrb_cv_get(mrb, klass, mrb_intern_lit(mrb, "_lastai")); if (mrb_cptr_p(lastai)) { freeaddrinfo(mrb_cptr(lastai)); mrb_cv_set(mrb, klass, mrb_intern_lit(mrb, "_lastai"), mrb_nil_value()); } error = getaddrinfo(hostname, servname, &hints, &res0); if (error) { mrb_raisef(mrb, E_SOCKET_ERROR, "getaddrinfo: %S", mrb_str_new_cstr(mrb, gai_strerror(error))); } mrb_cv_set(mrb, klass, mrb_intern_lit(mrb, "_lastai"), mrb_cptr_value(mrb, res0)); for (res = res0; res != NULL; res = res->ai_next) { sa = mrb_str_new(mrb, (void *)res->ai_addr, res->ai_addrlen); ai = mrb_funcall(mrb, klass, "new", 4, sa, mrb_fixnum_value(res->ai_family), mrb_fixnum_value(res->ai_socktype), mrb_fixnum_value(res->ai_protocol)); mrb_ary_push(mrb, ary, ai); mrb_gc_arena_restore(mrb, arena_idx); } freeaddrinfo(res0); mrb_cv_set(mrb, klass, mrb_intern_lit(mrb, "_lastai"), mrb_nil_value()); return ary; }
static mrb_value mrb_sdl_video_unlock_surface (mrb_state *mrb, mrb_value self) { mrb_value surface = mrb_nil_value(); mrb_get_args(mrb, "|o", &surface); SDL_UnlockSurface(mrb_value_to_sdl_surface(mrb, surface)); return mrb_nil_value(); }
// like Nginx rewrite keywords // used like this: // => http code 3xx location in browser // => internal redirection in nginx static mrb_value ngx_http_mruby_redirect(mrb_state *mrb, mrb_value self) { int argc; u_char *str; ngx_int_t rc; mrb_value uri, code; ngx_str_t ns; ngx_http_request_t *r; ngx_http_mruby_ctx_t *ctx; r = ngx_http_mruby_get_request(); ctx = ngx_http_get_module_ctx(r, ngx_http_mruby_module); argc = mrb_get_args(mrb, "o|oo", &uri, &code); if (argc == 2) { rc = mrb_fixnum(code); } else { rc = NGX_HTTP_MOVED_TEMPORARILY; } uri = mrb_obj_as_string(mrb, uri); // save location uri to ns ns.data = (u_char *)RSTRING_PTR(uri); ns.len = RSTRING_LEN(uri); if (ns.len == 0) { return mrb_nil_value(); } // if uri start with scheme prefix // return 3xx for redirect // else generate a internal redirection and response to raw request // request.path is not changed if (ngx_strncmp(ns.data, "http://", sizeof("http://") - 1) == 0 || ngx_strncmp(ns.data, "https://", sizeof("https://") - 1) == 0 || ngx_strncmp(ns.data, "$scheme", sizeof("$scheme") - 1) == 0) { if ((str = ngx_pnalloc(r->pool, ns.len + 1)) == NULL) { return self; } ngx_memcpy(str, ns.data, ns.len); str[ns.len] = '\0'; // build redirect location r->headers_out.location = ngx_list_push(&r->headers_out.headers); if (r->headers_out.location == NULL) { return self; } r->headers_out.location->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(ngx_hash(ngx_hash( ngx_hash('l', 'o'), 'c'), 'a'), 't'), 'i'), 'o'), 'n'); r->headers_out.location->value.data = ns.data; r->headers_out.location->value.len = ns.len; ngx_str_set(&r->headers_out.location->key, "Location"); r->headers_out.status = rc; ctx->exited = 1; ctx->exit_code = rc; } else { ctx->exited = 1; ctx->exit_code = ngx_http_internal_redirect(r, &ns, &r->args); } return self; }
static mrb_value mrb_sdl_video_display_format_alpha (mrb_state *mrb, mrb_value self) { mrb_value arg_surface = mrb_nil_value(); mrb_get_args(mrb, "|o", &arg_surface); SDL_Surface* surface = mrb_value_to_sdl_surface(mrb, arg_surface); return sdl_surface_to_mrb_value(mrb, self, SDL_DisplayFormatAlpha(surface)); }
static mrb_value mrb_attr_set_ub4(mrb_state *mrb, mrb_value self) { mrb_value attr_type, attr_value; mrb_get_args(mrb, "ii", &attr_type, &attr_value); return attr_set_ub4(self, attr_type, attr_value); }
// like Nginx rewrite keywords // used like this: // => http code 3xx location in browser // => internal redirection in nginx static mrb_value ngx_mrb_redirect(mrb_state *mrb, mrb_value self) { int argc; u_char *str; ngx_buf_t *b; ngx_int_t rc; mrb_value uri, code; ngx_str_t ns; ngx_http_mruby_ctx_t *ctx; ngx_table_elt_t *location; ngx_mrb_rputs_chain_list_t *chain; ngx_http_request_t *r = ngx_mrb_get_request(); argc = mrb_get_args(mrb, "o|oo", &uri, &code); // get status code from args if (argc == 2) { rc = mrb_fixnum(code); } else { rc = NGX_HTTP_MOVED_TEMPORARILY; } // get redirect uri from args if (mrb_type(uri) != MRB_TT_STRING) { uri = mrb_funcall(mrb, uri, "to_s", 0, NULL); } // save location uri to ns ns.data = (u_char *)RSTRING_PTR(uri); ns.len = ngx_strlen(ns.data); if (ns.len == 0) { return mrb_nil_value(); } // if uri start with scheme prefix // return 3xx for redirect // else generate a internal redirection and response to raw request // request.path is not changed if (ngx_strncmp(ns.data, "http://", sizeof("http://") - 1) == 0 || ngx_strncmp(ns.data, "https://", sizeof("https://") - 1) == 0 || ngx_strncmp(ns.data, "$scheme", sizeof("$scheme") - 1) == 0) { ctx = ngx_http_get_module_ctx(r, ngx_http_mruby_module); if (ctx == NULL) { ngx_log_error(NGX_LOG_ERR , r->connection->log , 0 , "get mruby context failed." ); } if (ctx->rputs_chain == NULL) { chain = ngx_pcalloc(r->pool, sizeof(ngx_mrb_rputs_chain_list_t)); chain->out = ngx_alloc_chain_link(r->pool); chain->last = &chain->out; } else { chain = ctx->rputs_chain; (*chain->last)->next = ngx_alloc_chain_link(r->pool); chain->last = &(*chain->last)->next; } // allocate space for body b = ngx_calloc_buf(r->pool); (*chain->last)->buf = b; (*chain->last)->next = NULL; str = ngx_pstrdup(r->pool, &ns); str[ns.len] = '\0'; (*chain->last)->buf->pos = str; (*chain->last)->buf->last = str+ns.len; (*chain->last)->buf->memory = 1; ctx->rputs_chain = chain; ngx_http_set_ctx(r, ctx, ngx_http_mruby_module); if (r->headers_out.content_length_n == -1) { r->headers_out.content_length_n += ns.len + 1; } else { r->headers_out.content_length_n += ns.len; } // build redirect location location = ngx_list_push(&r->headers_out.headers); location->hash = 1; ngx_str_set(&location->key, "Location"); location->value = ns; location->lowcase_key = ngx_pnalloc(r->pool, location->value.len); ngx_strlow(location->lowcase_key, location->value.data, location->value.len); // set location and response code for hreaders r->headers_out.location = location; r->headers_out.status = rc; ngx_http_send_header(r); ngx_http_output_filter(r, chain->out); } else { ngx_http_internal_redirect(r, &ns, &r->args); } return self; }