// params: stream, stringToWrite, afterWriteCallback(status) // LUA_API int wrap_uv_write(lua_State *L) { uv_stream_t *stream; uv_stream_t **stream_p = luaL_checkudata(L, 1, "uv_stream_t_ptr"); stream = *stream_p; size_t slen = 0; char *s = (char *) luaL_checklstring(L, 2, &slen); if (s == NULL || slen <= 0) { lua_pushinteger(L, 0); return 1; } write_req_t *wr = malloc(sizeof(*wr)); if (wr != NULL) { lua_pushvalue(L, 2); wr->ref_buf = ref(L); wr->ref_cb = ref_function(L, 3); if (wr->ref_buf && wr->ref_cb) { wr->buf = uv_buf_init(s, slen); int res = uv_write(&wr->req, stream, &wr->buf, 1, wrap_uv_on_write); lua_pushinteger(L, res); return 1; } unref(wr->ref_buf); unref(wr->ref_cb); free(wr); } luaL_error(L, "wrap_uv_write malloc failed"); return 0; }
/* * <proc> .isencapfunction <bool> * * This routine checks if a given Postscript procedure is an "encapsulated" * function of the type made by .buildfunction. These functions can then * be executed without executing the interpreter. These functions can be * executed directly from within C code inside the graphics library. */ static int zisencapfunction(i_ctx_t *i_ctx_p) { os_ptr op = osp; gs_function_t *pfn; check_proc(*op); pfn = ref_function(op); make_bool(op, pfn != NULL); return 0; }
// params: stream, afterReadCallback(nread, string) // LUA_API int wrap_uv_read_start(lua_State *L) { uv_stream_t *stream; uv_stream_t **stream_p = luaL_checkudata(L, 1, "uv_stream_t_ptr"); stream = *stream_p; stream->data = ref_function(L, 2); int res = uv_read_start(stream, wrap_uv_on_alloc, wrap_uv_on_read); lua_pushinteger(L, res); return 1; }
// params: stream, listenBacklogCount, listenCallback(status) // LUA_API int wrap_uv_listen(lua_State *L) { uv_stream_t *stream; uv_stream_t **stream_p = luaL_checkudata(L, 1, "uv_stream_t_ptr"); stream = *stream_p; int backlog = (int) luaL_checkint(L, 2); if (stream->data != NULL) { unref(stream->data); } stream->data = ref_function(L, 3); int res = uv_listen(stream, backlog, wrap_uv_on_listen); lua_pushinteger(L, res); return 1; }
// The wrapped lua API for uv_queue_work() is simpler than // the C API because lua has closures to handle user data. // // params: loop, callback() // LUA_API int wrap_uv_queue_work(lua_State *L) { uv_loop_t *loop; uv_loop_t **loop_p = luaL_checkudata(L, 1, "uv_loop_t_ptr"); loop = *loop_p; uv_work_t *wr = calloc(1, sizeof(*wr)); if (wr != NULL) { wr->data = ref_function(L, 2); int res = uv_queue_work(loop, wr, on_work, on_work_after); lua_pushinteger(L, res); return 1; } luaL_error(L, "wrap_uv_queue_work malloc failed"); return 0; }
/* <function_proc> <array> .scalefunction <function_proc> */ static int zscalefunction(i_ctx_t *i_ctx_p) { os_ptr op = osp; gs_function_t *pfn; gs_function_t *psfn; gs_range_t *ranges; int code; uint i; check_proc(op[-1]); pfn = ref_function(op - 1); if (pfn == 0 || !r_is_array(op)) return_error(gs_error_typecheck); if (r_size(op) != 2 * pfn->params.n) return_error(gs_error_rangecheck); ranges = (gs_range_t *) gs_alloc_byte_array(imemory, pfn->params.n, sizeof(gs_range_t), "zscalefunction"); if (ranges == 0) return_error(gs_error_VMerror); for (i = 0; i < pfn->params.n; ++i) { ref rval[2]; float val[2]; if ((code = array_get(op, 2 * i, &rval[0])) < 0 || (code = array_get(op, 2 * i + 1, &rval[1])) < 0 || (code = float_params(rval + 1, 2, val)) < 0) return code; ranges[i].rmin = val[0]; ranges[i].rmax = val[1]; } code = gs_function_make_scaled(pfn, &psfn, ranges, imemory); gs_free_object(imemory, ranges, "zscalefunction"); if (code < 0 || (code = make_function_proc(i_ctx_p, op - 1, psfn)) < 0) { gs_function_free(psfn, true, imemory); return code; } pop(1); return 0; }
/* The current color space is the alternate space for the separation space. */ static int zsetseparationspace(i_ctx_t *i_ctx_p) { os_ptr op = osp; const ref *pcsa; gs_color_space *pcs; gs_color_space * pacs; ref_colorspace cspace_old; ref sname, name_none, name_all; gs_function_t *pfn = NULL; separation_type sep_type; int code; const gs_memory_t * mem = imemory; /* Verify that we have an array as our input parameter */ check_read_type(*op, t_array); if (r_size(op) != 4) return_error(e_rangecheck); /* The alternate color space has been selected as the current color space */ pacs = gs_currentcolorspace(igs); if (!pacs->type->can_be_alt_space) return_error(e_rangecheck); /* * pcsa is a pointer to element 1 (2nd element) in the Separation colorspace * description array. Thus pcsa[2] is element #3 (4th element) which is the * tint transform. */ pcsa = op->value.const_refs + 1; sname = *pcsa; switch (r_type(&sname)) { default: return_error(e_typecheck); case t_string: code = name_from_string(mem, &sname, &sname); if (code < 0) return code; /* falls through */ case t_name: break; } if ((code = name_ref(mem, (const byte *)"All", 3, &name_all, 0)) < 0) return code; if ((code = name_ref(mem, (const byte *)"None", 4, &name_none, 0)) < 0) return code; sep_type = ( name_eq(&sname, &name_all) ? SEP_ALL : name_eq(&sname, &name_none) ? SEP_NONE : SEP_OTHER); /* Check tint transform procedure. */ /* See comment above about psca */ check_proc(pcsa[2]); pfn = ref_function(pcsa + 2); if (pfn == NULL) return_error(e_rangecheck); cspace_old = istate->colorspace; /* Now set the current color space as Separation */ code = gs_cspace_new_Separation(&pcs, pacs, imemory); if (code < 0) return code; pcs->params.separation.sep_type = sep_type; pcs->params.separation.sep_name = name_index(mem, &sname); pcs->params.separation.get_colorname_string = gs_get_colorname_string; istate->colorspace.procs.special.separation.layer_name = pcsa[0]; istate->colorspace.procs.special.separation.tint_transform = pcsa[2]; if (code >= 0) code = gs_cspace_set_sepr_function(pcs, pfn); if (code >= 0) code = gs_setcolorspace(igs, pcs); /* release reference from construction */ rc_decrement_only(pcs, "zsetseparationspace"); if (code < 0) { istate->colorspace = cspace_old; return code; } pop(1); return 0; }
/* The current color space is the alternate space for the DeviceN space. */ static int zsetdevicenspace(i_ctx_t *i_ctx_p) { os_ptr op = osp; const ref *pcsa; gs_separation_name *names; gs_device_n_map *pmap; uint num_components; gs_color_space *pcs; gs_color_space *pacs; ref_colorspace cspace_old; gs_function_t *pfn; int code; /* Verify that we have an array as our input parameter */ check_read_type(*op, t_array); if (r_size(op) < 4 || r_size(op) > 5) return_error(e_rangecheck); /* pcsa is a pointer to the color names array (element 1 in input array) */ pcsa = op->value.const_refs + 1; if (!r_is_array(pcsa)) return_error(e_typecheck); num_components = r_size(pcsa); if (num_components == 0) return_error(e_rangecheck); if (num_components > GS_CLIENT_COLOR_MAX_COMPONENTS) return_error(e_limitcheck); /* Check tint transform procedure. Note: Cheap trick to get pointer to it. The tint transform procedure is element 3 in the input array */ check_proc(pcsa[2]); /* The alternate color space has been selected as the current color space */ pacs = gs_currentcolorspace(igs); code = gs_cspace_new_DeviceN(&pcs, num_components, pacs, imemory); if (code < 0) return code; names = pcs->params.device_n.names; pmap = pcs->params.device_n.map; pcs->params.device_n.get_colorname_string = gs_get_colorname_string; /* Pick up the names of the components */ { uint i; ref sname; for (i = 0; i < num_components; ++i) { array_get(imemory, pcsa, (long)i, &sname); switch (r_type(&sname)) { case t_string: code = name_from_string(imemory, &sname, &sname); if (code < 0) { rc_decrement(pcs, ".setdevicenspace"); return code; } /* falls through */ case t_name: names[i] = name_index(imemory, &sname); break; default: rc_decrement(pcs, ".setdevicenspace"); return_error(e_typecheck); } } } /* Now set the current color space as DeviceN */ cspace_old = istate->colorspace; /* * pcsa is a pointer to element 1 (2nd element) in the DeviceN * description array. Thus pcsa[2] is element #3 (4th element) * which is the tint transform. */ istate->colorspace.procs.special.device_n.layer_names = pcsa[0]; istate->colorspace.procs.special.device_n.tint_transform = pcsa[2]; pfn = ref_function(pcsa + 2); /* See comment above */ if (!pfn) code = gs_note_error(e_rangecheck); if (code < 0) { istate->colorspace = cspace_old; rc_decrement_only(pcs, "zsetdevicenspace"); return code; } gs_cspace_set_devn_function(pcs, pfn); code = gs_setcolorspace(igs, pcs); /* release reference from construction */ rc_decrement_only(pcs, "zsetdevicenspace"); if (code < 0) { istate->colorspace = cspace_old; return code; } pop(1); return 0; }