/** * Return a new value object which is a deep copy of the input value * * @param val #xmmsv_t to copy. * @return 1 the address to the new copy of the value. */ xmmsv_t * xmmsv_copy (xmmsv_t *val) { xmmsv_t *cur_val = NULL; xmmsv_type_t type; int64_t i; const char *s; float f; x_return_val_if_fail (val, 0); type = xmmsv_get_type (val); switch (type) { case XMMSV_TYPE_DICT: cur_val = duplicate_dict_value (val); break; case XMMSV_TYPE_LIST: cur_val = duplicate_list_value (val); break; case XMMSV_TYPE_INT64: xmmsv_get_int (val, &i); cur_val = xmmsv_new_int (i); break; case XMMSV_TYPE_FLOAT: xmmsv_get_float (val, &f); cur_val = xmmsv_new_float (f); break; case XMMSV_TYPE_STRING: xmmsv_get_string (val, &s); cur_val = xmmsv_new_string (s); break; case XMMSV_TYPE_ERROR: xmmsv_get_error (val, &s); cur_val = xmmsv_new_error (s); break; case XMMSV_TYPE_COLL: cur_val = duplicate_coll_value (val); break; case XMMSV_TYPE_BIN: cur_val = xmmsv_new_bin (val->value.bin.data, val->value.bin.len); break; case XMMSV_TYPE_BITBUFFER: cur_val = xmmsv_new_bitbuffer (); xmmsv_bitbuffer_put_data (cur_val, val->value.bit.buf, val->value.bit.len / 8); xmmsv_bitbuffer_goto (cur_val, xmmsv_bitbuffer_pos (val)); break; default: cur_val = xmmsv_new_none (); break; } assert (cur_val); return cur_val; }
static xmmsv_t * create_data (int type, const char *data, uint32_t len) { switch (type) { case JSON_STRING: return xmmsv_new_string (data); case JSON_INT: return xmmsv_new_int (atoi(data)); case JSON_FLOAT: return xmmsv_new_float (strtof (data, NULL)); case JSON_NULL: return xmmsv_new_none (); case JSON_TRUE: return xmmsv_new_int (1); case JSON_FALSE: return xmmsv_new_int (0); default: return xmmsv_new_error ("Unknown data type."); } }
static bool _internal_get_from_bb_value_of_type_alloc (xmmsv_t *bb, xmmsv_type_t type, xmmsv_t **val) { int32_t i; uint32_t len; char *s; xmmsv_coll_t *c; unsigned char *d; switch (type) { case XMMSV_TYPE_ERROR: if (!_internal_get_from_bb_error_alloc (bb, &s, &len)) { return false; } *val = xmmsv_new_error (s); free (s); break; case XMMSV_TYPE_INT32: if (!_internal_get_from_bb_int32 (bb, &i)) { return false; } *val = xmmsv_new_int (i); break; case XMMSV_TYPE_STRING: if (!_internal_get_from_bb_string_alloc (bb, &s, &len)) { return false; } *val = xmmsv_new_string (s); free (s); break; case XMMSV_TYPE_DICT: if (!xmmsc_deserialize_dict (bb, val)) { return false; } break; case XMMSV_TYPE_LIST : if (!xmmsc_deserialize_list (bb, val)) { return false; } break; case XMMSV_TYPE_COLL: if (!_internal_get_from_bb_collection_alloc (bb, &c)) { return false; } *val = xmmsv_new_coll (c); xmmsv_coll_unref (c); break; case XMMSV_TYPE_BIN: if (!_internal_get_from_bb_bin_alloc (bb, &d, &len)) { return false; } *val = xmmsv_new_bin (d, len); free (d); break; case XMMSV_TYPE_NONE: *val = xmmsv_new_none (); break; default: x_internal_error ("Got message of unknown type!"); return false; } return true; }
static void process_msg (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg) { xmms_object_t *object; xmms_object_cmd_arg_t arg; xmms_ipc_msg_t *retmsg; xmmsv_t *error, *arguments; uint32_t objid, cmdid; g_return_if_fail (msg); objid = xmms_ipc_msg_get_object (msg); cmdid = xmms_ipc_msg_get_cmd (msg); if (!xmms_ipc_msg_get_value (msg, &arguments)) { xmms_log_error ("Cannot read command arguments. " "Ignoring command."); return; } if (objid == XMMS_IPC_OBJECT_SIGNAL) { if (cmdid == XMMS_IPC_CMD_SIGNAL) { xmms_ipc_register_signal (client, msg, arguments); } else if (cmdid == XMMS_IPC_CMD_BROADCAST) { xmms_ipc_register_broadcast (client, msg, arguments); } else { xmms_log_error ("Bad command id (%d) for signal object", cmdid); } goto out; } if (objid >= XMMS_IPC_OBJECT_END) { xmms_log_error ("Bad object id (%d)", objid); goto out; } g_mutex_lock (ipc_object_pool_lock); object = ipc_object_pool->objects[objid]; g_mutex_unlock (ipc_object_pool_lock); if (!object) { xmms_log_error ("Object %d was not found!", objid); goto out; } if (!g_tree_lookup (object->cmds, GUINT_TO_POINTER (cmdid))) { xmms_log_error ("No such cmd %d on object %d", cmdid, objid); goto out; } xmms_object_cmd_arg_init (&arg); arg.args = arguments; xmms_object_cmd_call (object, cmdid, &arg); if (xmms_error_isok (&arg.error)) { retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); } else { /* FIXME: or we could omit setting the command to _CMD_ERROR * and let the client check whether the value it got is an * error xmmsv_t. If so, don't forget to * update the client-side of IPC too. */ retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR); error = xmmsv_new_error (xmms_error_message_get (&arg.error)); xmms_ipc_msg_put_value (retmsg, error); xmmsv_unref (error); /* retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); */ } if (arg.retval) xmmsv_unref (arg.retval); err: xmms_ipc_msg_set_cookie (retmsg, xmms_ipc_msg_get_cookie (msg)); g_mutex_lock (client->lock); xmms_ipc_client_msg_write (client, retmsg); g_mutex_unlock (client->lock); out: if (arguments) { xmmsv_unref (arguments); } }
static void process_msg (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg) { xmms_object_t *object; xmms_object_cmd_desc_t *cmd = NULL; xmms_object_cmd_arg_t arg; xmms_ipc_msg_t *retmsg; xmmsv_t *error, *arguments; uint32_t objid, cmdid; gint i; g_return_if_fail (msg); objid = xmms_ipc_msg_get_object (msg); cmdid = xmms_ipc_msg_get_cmd (msg); if (!xmms_ipc_msg_get_value (msg, &arguments)) { xmms_log_error ("Cannot read command arguments. " "Ignoring command."); return; } if (objid == XMMS_IPC_OBJECT_SIGNAL) { if (cmdid == XMMS_IPC_CMD_SIGNAL) { xmms_ipc_register_signal (client, msg, arguments); } else if (cmdid == XMMS_IPC_CMD_BROADCAST) { xmms_ipc_register_broadcast (client, msg, arguments); } else { xmms_log_error ("Bad command id (%d) for signal object", cmdid); } goto out; } if (objid >= XMMS_IPC_OBJECT_END) { xmms_log_error ("Bad object id (%d)", objid); goto out; } g_mutex_lock (ipc_object_pool_lock); object = ipc_object_pool->objects[objid]; g_mutex_unlock (ipc_object_pool_lock); if (!object) { xmms_log_error ("Object %d was not found!", objid); goto out; } if (object->cmds) cmd = g_tree_lookup (object->cmds, GUINT_TO_POINTER (cmdid)); if (!cmd) { xmms_log_error ("No such cmd %d on object %d", cmdid, objid); goto out; } xmms_object_cmd_arg_init (&arg); for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) { if (!type_and_msg_to_arg (cmd->args[i], arguments, &arg, i)) { xmms_log_error ("Error parsing args"); if (objid == XMMS_IPC_OBJECT_MAIN && cmdid == XMMS_IPC_CMD_HELLO) { xmms_log_error ("Couldn't parse hello message. " "Maybe the client or libxmmsclient " "needs to be updated."); } retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR); error = xmmsv_new_error ("Corrupt msg"); xmms_ipc_msg_put_value (retmsg, error); xmmsv_unref (error); goto err; } } xmms_object_cmd_call (object, cmdid, &arg); if (xmms_error_isok (&arg.error)) { retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); } else { /* FIXME: or we could omit setting the command to _CMD_ERROR * and let the client check whether the value it got is an * error xmmsv_t. If so, don't forget to * update the client-side of IPC too. */ retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR); error = xmmsv_new_error (xmms_error_message_get (&arg.error)); xmms_ipc_msg_put_value (retmsg, error); xmmsv_unref (error); /* retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); */ } if (arg.retval) xmmsv_unref (arg.retval); err: for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) { if (arg.values[i]) xmmsv_unref (arg.values[i]); } xmms_ipc_msg_set_cookie (retmsg, xmms_ipc_msg_get_cookie (msg)); g_mutex_lock (client->lock); xmms_ipc_client_msg_write (client, retmsg); g_mutex_unlock (client->lock); out: if (arguments) { xmmsv_unref (arguments); } }