/* * 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 char * _on_cover_retrieve( xmmsv_t *value, const char *picture_front ) { unsigned int bl; const unsigned char *bc; char *tmp_buf; if( xmmsv_get_bin( value, &bc, &bl ) ) { int fd,ret; char buf[4096]; snprintf(buf, sizeof(buf), "%s/.e-music/cache/%s", getenv("HOME"), picture_front); if ( ecore_file_exists(buf) != 1 ) { fd = open(buf, O_WRONLY|O_CREAT, 0777); ret = write(fd, bc, bl); close(fd); if (ret != -1) { ERR("False to write album cover picture"); return NULL; } } return (char *)eina_stringshare_add( buf ); } return NULL; }
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; }
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 void print_entry_string (xmmsv_t *v, const gchar *key, const gchar *source) { const gchar *value; xmmsv_get_string (v, &value); /* Ok it's a string, if it's the URL property from the * server source we need to decode it since it's * encoded in the server */ if (strcmp (key, "url") == 0 && strcmp (source, "server") == 0) { /* First decode the URL encoding */ xmmsv_t *tmp; gchar *url = NULL; const unsigned char *burl; unsigned int blen; tmp = xmmsv_decode_url (v); if (tmp && xmmsv_get_bin (tmp, &burl, &blen)) { url = g_malloc (blen + 1); memcpy (url, burl, blen); url[blen] = 0; xmmsv_unref (tmp); } /* Let's see if the result is valid utf-8. This must be done * since we don't know the charset of the binary string */ if (url && g_utf8_validate (url, -1, NULL)) { /* If it's valid utf-8 we don't have any problem just * printing it to the screen */ print_info ("[%s] %s = %s", source, key, url); } else if (url) { /* Not valid utf-8 :-( We make a valid guess here that * the string when it was encoded with URL it was in the * same charset as we have on the terminal now. * * THIS MIGHT BE WRONG since different clients can have * different charsets and DIFFERENT computers most likely * have it. */ gchar *tmp2 = g_locale_to_utf8 (url, -1, NULL, NULL, NULL); /* Lets add a disclaimer */ print_info ("[%s] %s = %s (charset guessed)", source, key, tmp2); g_free (tmp2); } else { /* Decoding the URL failed for some reason. That's not good. */ print_info ("[%s] %s = (invalid encoding)", source, key); } g_free (url); } else { /* Normal strings is ALWAYS utf-8 no problem */ print_info ("[%s] %s = %s", source, key, value); } }
int xmms_bin_to_gstring (xmmsv_t *value, GString **gs) { const guchar *str; guint len; if (!xmmsv_get_bin (value, &str, &len)) { return 0; } *gs = g_string_new_len ((const gchar *) str, len); return 1; }
static VALUE bin_get (xmmsv_t *val) { const unsigned char *data = NULL; unsigned int len = 0; if (!xmmsv_get_bin (val, &data, &len)) rb_raise (eValueError, "cannot retrieve value"); return rb_str_new ((char *) data, len); }
gboolean xmms_xform_auxdata_get_bin (xmms_xform_t *xform, const gchar *key, const guchar **data, gsize *datalen) { const xmmsv_t *obj; obj = xmms_xform_auxdata_get_val (xform, key); if (obj && xmmsv_get_type (obj) == XMMSV_TYPE_BIN) { xmmsv_get_bin (obj, data, datalen); return TRUE; } return FALSE; }
/** 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; }
static xmmsv_t * aggregate_average (xmmsv_t *current, gint int_value, const gchar *str_value) { avg_data_t *data; guint length; if (current == NULL) { avg_data_t init = { 0 }; current = xmmsv_new_bin ((guchar *) &init, sizeof (avg_data_t)); } xmmsv_get_bin (current, (const guchar **) &data, &length); if (str_value == NULL) { data->n++; data->sum += int_value; } return current; }
xmmsv_t * xmmsv_deserialize (xmmsv_t *v) { xmmsv_t *bb; xmmsv_t *res; const unsigned char *data; uint32_t len; if (!xmmsv_get_bin (v, &data, &len)) return NULL; bb = xmmsv_bitbuffer_new_ro (data, len); if (!xmmsv_bitbuffer_deserialize_value (bb, &res)) { xmmsv_unref (bb); return NULL; } xmmsv_unref (bb); return res; }
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; }
int xmmsv_bitbuffer_serialize_value (xmmsv_t *bb, xmmsv_t *v) { bool ret; int32_t i; const char *s; xmmsv_coll_t *c; const unsigned char *bc; unsigned int bl; xmmsv_type_t type; type = xmmsv_get_type (v); ret = _internal_put_on_bb_int32 (bb, type); if (!ret) return ret; switch (type) { case XMMSV_TYPE_ERROR: if (!xmmsv_get_error (v, &s)) { return false; } ret = _internal_put_on_bb_error (bb, s); break; case XMMSV_TYPE_INT32: if (!xmmsv_get_int (v, &i)) { return false; } ret = _internal_put_on_bb_int32 (bb, i); break; case XMMSV_TYPE_STRING: if (!xmmsv_get_string (v, &s)) { return false; } ret = _internal_put_on_bb_string (bb, s); break; case XMMSV_TYPE_COLL: if (!xmmsv_get_coll (v, &c)) { return false; } ret = _internal_put_on_bb_collection (bb, c); break; case XMMSV_TYPE_BIN: if (!xmmsv_get_bin (v, &bc, &bl)) { return false; } ret = _internal_put_on_bb_bin (bb, bc, bl); break; case XMMSV_TYPE_LIST: ret = _internal_put_on_bb_value_list (bb, v); break; case XMMSV_TYPE_DICT: ret = _internal_put_on_bb_value_dict (bb, v); break; case XMMSV_TYPE_NONE: break; default: x_internal_error ("Tried to serialize value of unsupported type"); return false; } return ret; }
/* Converts the temporary value returned by result_to_xmmsv into the real value */ static xmmsv_t * aggregate_data (xmmsv_t *value, aggregate_function_t aggr_func) { const random_data_t *random_data; const avg_data_t *avg_data; const set_data_t *set_data; gconstpointer data; xmmsv_t *ret; guint len; ret = NULL; data = NULL; if (value != NULL && xmmsv_is_type (value, XMMSV_TYPE_BIN)) xmmsv_get_bin (value, (const guchar **) &data, &len); switch (aggr_func) { case AGGREGATE_FIRST: case AGGREGATE_MIN: case AGGREGATE_MAX: case AGGREGATE_SUM: if (value != NULL) { ret = xmmsv_ref (value); } else { ret = xmmsv_new_none (); } break; case AGGREGATE_LIST: if (value != NULL) { ret = xmmsv_ref (value); } else { ret = xmmsv_new_list (); } break; case AGGREGATE_RANDOM: random_data = data; if (random_data != NULL) { ret = random_data->data; } else { ret = xmmsv_new_none (); } break; case AGGREGATE_SET: set_data = data; if (set_data != NULL) { g_hash_table_destroy (set_data->ht); ret = set_data->list; } else { ret = xmmsv_new_list (); } break; case AGGREGATE_AVG: avg_data = data; if (avg_data != NULL) { ret = xmmsv_new_float (avg_data->n ? avg_data->sum * 1.0 / avg_data->n : 0); } else { ret = xmmsv_new_none (); } break; default: g_assert_not_reached (); } if (value != NULL) { xmmsv_unref (value); } return ret; }