/* * call-seq: * Xmms.decode_url(url) -> String * * Decodes a url-encoded string _url_ and returns it in UNKNOWN ENCODING. * Use with caution. */ static VALUE m_decode_url (VALUE self, VALUE str) { const unsigned char *burl; unsigned int blen; xmmsv_t *strv, *decoded; VALUE url = Qnil; strv = xmmsv_new_string (StringValuePtr (str)); decoded = xmmsv_decode_url (strv); if (!decoded) goto out; if (!xmmsv_get_bin (decoded, &burl, &blen)) goto out; url = rb_str_new ((char *) burl, blen); out: if (decoded) xmmsv_unref (decoded); xmmsv_unref (strv); return url; }
static void xmms_playlist_client_load (xmms_playlist_t *playlist, const gchar *name, xmms_error_t *err) { xmmsv_coll_t *plcoll, *active_coll; if (strcmp (name, XMMS_ACTIVE_PLAYLIST) == 0) { xmms_error_set (err, XMMS_ERROR_INVAL, "invalid playlist to load"); return; } active_coll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, err); if (active_coll == NULL) { xmms_error_set (err, XMMS_ERROR_GENERIC, "no active playlist"); return; } plcoll = xmms_playlist_get_coll (playlist, name, err); if (plcoll == NULL) { xmms_error_set (err, XMMS_ERROR_NOENT, "no such playlist"); return; } if (active_coll == plcoll) { XMMS_DBG ("Not loading %s playlist, already active!", name); return; } XMMS_DBG ("Loading new playlist! %s", name); xmms_collection_update_pointer (playlist->colldag, XMMS_ACTIVE_PLAYLIST, XMMS_COLLECTION_NSID_PLAYLISTS, plcoll); xmms_object_emit (XMMS_OBJECT (playlist), XMMS_IPC_SIGNAL_PLAYLIST_LOADED, xmmsv_new_string (name)); }
static xmms_xspf_track_attr_t * xmms_xspf_track_attr_from_node (const xmms_xspf_track_prop_t *prop, xmlNodePtr node) { xmmsv_t *value; xmms_xspf_track_attr_t *attr; switch (prop->attr_type) { case XMMS_XSPF_TRACK_ATTR_TYPE_STRING: value = xmmsv_new_string ((char *)node->children->content); break; case XMMS_XSPF_TRACK_ATTR_TYPE_INT32: { /* TODO: check for errors */ gint32 val = strtol ((char *)node->children->content, (char **)NULL, 10); value = xmmsv_new_int (val); break; } } if (!value) { return NULL; } attr = g_new0 (xmms_xspf_track_attr_t, 1); attr->key = prop->name; attr->value = value; return attr; }
static xmmsv_t * aggregate_random (xmmsv_t *current, gint int_value, const gchar *str_value) { random_data_t *data; guint length; if (current == NULL) { random_data_t init = { 0 }; current = xmmsv_new_bin ((guchar *) &init, sizeof (random_data_t)); } xmmsv_get_bin (current, (const guchar **) &data, &length); data->n++; if (g_random_int_range (0, data->n) == 0) { if (data->data != NULL) { xmmsv_unref (data->data); } if (str_value != NULL) { data->data = xmmsv_new_string (str_value); } else { data->data = xmmsv_new_int (int_value); } } return current; }
static xmmsv_t * aggregate_set (xmmsv_t *current, gint int_value, const gchar *str_value) { set_data_t *data; xmmsv_t *value; gpointer key; guint length; if (current == NULL) { set_data_t init = { .ht = g_hash_table_new (NULL, NULL), .list = xmmsv_new_list () }; current = xmmsv_new_bin ((guchar *) &init, sizeof (set_data_t)); } xmmsv_get_bin (current, (const guchar **) &data, &length); if (str_value != NULL) { value = xmmsv_new_string (str_value); key = (gpointer) str_value; } else { value = xmmsv_new_int (int_value); key = GINT_TO_POINTER (int_value); } if (g_hash_table_lookup (data->ht, key) == NULL) { g_hash_table_insert (data->ht, key, value); xmmsv_list_append (data->list, value); } xmmsv_unref (value); return current; }
void xmms_xform_browse_add_entry_property_str (xmms_xform_t *xform, const gchar *key, const gchar *value) { xmmsv_t *val = xmmsv_new_string (value); xmms_xform_browse_add_entry_property (xform, key, val); xmmsv_unref (val); }
xmmsv_t * xmms_convert_and_kill_string (gchar *str) { xmmsv_t *v = NULL; if (str) { v = xmmsv_new_string (str); g_free (str); } return v; }
/** * 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 * xmms_medialib_entry_to_tree (xmms_medialib_session_t *session, xmms_medialib_entry_t entry) { s4_resultset_t *set; s4_val_t *song_id; xmmsv_t *ret, *id; gint i; song_id = s4_val_new_int (entry); set = xmms_medialib_filter (session, "song_id", song_id, S4_COND_PARENT, NULL, NULL, S4_FETCH_PARENT | S4_FETCH_DATA); s4_val_free (song_id); ret = xmmsv_new_dict (); for (i = 0; i < s4_resultset_get_rowcount (set); i++) { const s4_result_t *res; res = s4_resultset_get_result (set, 0, 0); while (res != NULL) { xmmsv_t *v_entry = NULL; const s4_val_t *val; const char *s; gint32 i; val = s4_result_get_val (res); if (s4_val_get_str (val, &s)) { v_entry = xmmsv_new_string (s); } else if (s4_val_get_int (val, &i)) { v_entry = xmmsv_new_int (i); } xmms_medialib_tree_add_tuple (ret, s4_result_get_key (res), s4_result_get_src (res), v_entry); xmmsv_unref (v_entry); res = s4_result_next (res); } } s4_resultset_free (set); id = xmmsv_new_int (entry); xmms_medialib_tree_add_tuple (ret, "id", "server", id); xmmsv_unref (id); return ret; }
static xmmsv_t * aggregate_first (xmmsv_t *current, gint int_value, const gchar *str_value) { if (current != NULL) { return current; } if (str_value != NULL) { current = xmmsv_new_string (str_value); } else { current = xmmsv_new_int (int_value); } return current; }
void xmms_xform_auxdata_set_str (xmms_xform_t *xform, const gchar *key, const gchar *strval) { xmmsv_t *val; const char *old; if (xmms_xform_auxdata_get_str (xform, key, &old)) { if (strcmp (old, strval) == 0) { return; } } val = xmmsv_new_string (strval); xmms_xform_auxdata_set_val (xform, g_strdup (key), val); }
/** * Helper function to build a list #xmmsv_t containing the * strings from the input array. * * @param array An array of C strings. Must be NULL-terminated if num * is -1. * @param num The optional number of elements to read from the array. Set to * -1 if the array is NULL-terminated. * @return An #xmmsv_t containing the list of strings. Must be * unreffed manually when done. */ xmmsv_t * xmmsv_make_stringlist (char *array[], int num) { xmmsv_t *list, *elem; int i; list = xmmsv_new_list (); if (array) { for (i = 0; (num >= 0 && i < num) || array[i]; i++) { elem = xmmsv_new_string (array[i]); xmmsv_list_append (list, elem); xmmsv_unref (elem); } } return list; }
/** * This returns the main stats for the server */ static GTree * xmms_main_client_stats (xmms_object_t *object, xmms_error_t *error) { GTree *ret; gint starttime; ret = g_tree_new_full ((GCompareDataFunc) strcmp, NULL, NULL, (GDestroyNotify) xmmsv_unref); starttime = ((xmms_main_t*)object)->starttime; g_tree_insert (ret, (gpointer) "version", xmmsv_new_string (XMMS_VERSION)); g_tree_insert (ret, (gpointer) "uptime", xmmsv_new_int (time (NULL) - starttime)); return ret; }
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."); } }
/** Decode an URL-encoded string. * * Some strings (currently only the url of media) have no known * encoding, and must be encoded in an UTF-8 clean way. This is done * similarly to the url encoding web browsers do. This functions decodes * a string encoded in that way. OBSERVE that the decoded string HAS * NO KNOWN ENCODING and you cannot display it on screen in a 100% * guaranteed correct way (a good heuristic is to try to validate the * decoded string as UTF-8, and if it validates assume that it is an * UTF-8 encoded string, and otherwise fall back to some other * encoding). * * Do not use this function if you don't understand the * implications. The best thing is not to try to display the url at * all. * * Note that the fact that the string has NO KNOWN ENCODING and CAN * NOT BE DISPLAYED does not stop you from open the file if it is a * local file (if it starts with "file://"). * * @param encoded_url the url-encoded string * @return the decoded string in an unknown encoding * */ std::string decodeUrl( const std::string& encoded_url ) { xmmsv_t *encoded, *decoded; const unsigned char *url; unsigned int len; std::string dec_str; encoded = xmmsv_new_string( encoded_url.c_str() ); decoded = xmmsv_decode_url( encoded ); if( !xmmsv_get_bin( decoded, &url, &len ) ) { throw invalid_url( "The given URL cannot be decoded." ); } dec_str = std::string( reinterpret_cast< const char* >( url ), len ); xmmsv_unref( encoded ); xmmsv_unref( decoded ); return dec_str; }
void xmms_xform_metadata_set_str (xmms_xform_t *xform, const char *key, const char *val) { const char *old; if (!g_utf8_validate (val, -1, NULL)) { xmms_log_error ("xform '%s' tried to set property '%s' to a NON UTF-8 string!", xmms_xform_shortname (xform), key); return; } if (xmms_xform_metadata_get_str (xform, key, &old)) { if (strcmp (old, val) == 0) { return; } } g_hash_table_insert (xform->metadata, g_strdup (key), xmmsv_new_string (val)); xform->metadata_changed = TRUE; }
static xmmsv_t * args_to_dict (gchar **argv, gint argc) { xmmsv_t *dict; gint i; dict = xmmsv_new_dict (); if (!dict) { return NULL; } for (i = 0; i < argc; i++) { gchar **tuple; xmmsv_t *val; /* Split the string into arg and value. */ tuple = g_strsplit (argv[i], "=", 2); if (tuple[0] && tuple[1]) { val = xmmsv_new_string (tuple[1]); } else if (tuple[0]) { val = xmmsv_new_none (); } else { g_strfreev (tuple); continue; /* Empty tuple, means empty string. */ } if (!val) { xmmsv_unref (dict); return NULL; } xmmsv_dict_set (dict, tuple[0], val); g_strfreev (tuple); xmmsv_unref (val); } return dict; }
char *decode_url(const char *url) { xmmsv_t *url_str; xmmsv_t *decoded_url; char *new_url = NULL; const unsigned char *url_tmp; unsigned int url_len; url_str = xmmsv_new_string(url); if (url_str) { decoded_url = xmmsv_decode_url(url_str); if (decoded_url) { if (xmmsv_get_bin(decoded_url, &url_tmp, &url_len)) { new_url = (char*) malloc( sizeof(char)*(url_len+1) ); snprintf(new_url, url_len+1, "%s", url_tmp); } } xmmsv_unref(decoded_url); } xmmsv_unref(url_str); return new_url; }
xmmsv_t * xmms_medialib_entry_property_get_value (xmms_medialib_session_t *session, xmms_medialib_entry_t id_num, const gchar *property) { xmmsv_t *ret = NULL; s4_val_t *prop; const gchar *s; gint32 i; prop = xmms_medialib_entry_property_get (session, id_num, property); if (prop == NULL) return NULL; if (s4_val_get_str (prop, &s)) { ret = xmmsv_new_string (s); } else if (s4_val_get_int (prop, &i)) { ret = xmmsv_new_int (i); } s4_val_free (prop); return ret; }
/** * Decodes a cluster fetch specification from a dictionary. * The 'cluster-by' must be one of 'id', 'position' or 'value'. If set * to 'value', then an additional 'cluster-field' will be used to specify * which meta data attribute to cluster on. */ static xmms_fetch_spec_t * xmms_fetch_spec_new_cluster (xmmsv_t *fetch, xmms_fetch_info_t *info, s4_sourcepref_t *prefs, xmms_error_t *err) { xmmsv_t *cluster_by, *cluster_field, *cluster_data; xmms_fetch_spec_t *data, *spec = NULL; s4_sourcepref_t *sp; const gchar *value = NULL; const gchar *field = NULL; const gchar *fallback = NULL; gint cluster_type; if (!xmmsv_dict_get (fetch, "cluster-by", &cluster_by)) { cluster_by = xmmsv_new_string ("value"); xmmsv_dict_set (fetch, "cluster-by", cluster_by); xmmsv_unref (cluster_by); } if (!xmmsv_dict_entry_get_string (fetch, "cluster-by", &value)) { const gchar *message = "'cluster-by' must be a string."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } xmmsv_get_string (cluster_by, &value); if (!cluster_by_from_string (value, &cluster_type)) { const gchar *message = "'cluster-by' must be 'id', 'position', or 'value'."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } if (cluster_type == CLUSTER_BY_VALUE) { if (!xmmsv_dict_entry_get_string (fetch, "cluster-field", &field)) { const gchar *message = "'cluster-field' must if 'cluster-by' is 'value'."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } } if (!xmmsv_dict_get (fetch, "data", &cluster_data)) { const gchar *message = "Required field 'data' not set in cluster."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } if (xmmsv_dict_entry_get_type (fetch, "cluster-fallback") == XMMSV_TYPE_NONE) { fallback = NULL; } else if (!xmmsv_dict_entry_get_string (fetch, "cluster-fallback", &fallback)) { const gchar *message = "Optional field 'default' must be a string."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } sp = normalize_source_preferences (fetch, prefs, err); if (xmms_error_iserror (err)) { return NULL; } data = xmms_fetch_spec_new (cluster_data, info, sp, err); if (xmms_error_iserror (err)) { s4_sourcepref_unref (sp); return NULL; } spec = g_new0 (xmms_fetch_spec_t, 1); spec->data.cluster.data = data; spec->data.cluster.type = cluster_type; spec->data.cluster.fallback = fallback; switch (spec->data.cluster.type) { case CLUSTER_BY_ID: spec->data.cluster.column = xmms_fetch_info_add_song_id(info, cluster_field); break; case CLUSTER_BY_VALUE: xmmsv_dict_get (fetch, "cluster-field", &cluster_field); spec->data.cluster.column = xmms_fetch_info_add_key (info, cluster_field, field, sp); break; case CLUSTER_BY_POSITION: /* do nothing */ break; default: g_assert_not_reached (); } s4_sourcepref_unref (sp); return spec; }
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; }