4
* Copyright (C) 2004-2011 Eina
6
* This program is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
20
#include "lomo-stream.h"
23
#include <glib/gi18n.h>
27
G_DEFINE_TYPE (LomoStream, lomo_stream, G_TYPE_OBJECT)
35
static struct TagFmt tag_fmt_table [] = {
36
{ 'a', LOMO_TAG_ARTIST , "%s" },
37
{ 'b', LOMO_TAG_ALBUM , "%s" },
38
{ 't', LOMO_TAG_TITLE , "%s" },
39
{ 'g', LOMO_TAG_GENRE , "%s" },
40
{ 'n', LOMO_TAG_TRACK_NUMBER , "%02d"},
41
{ 'd', LOMO_TAG_DATE , "%s" },
42
{ 0, LOMO_TAG_INVALID , "%p" }
45
struct _LomoStreamPrivate {
46
gboolean all_tags, failed;
56
SIGNAL_EXTENDED_METADATA_UPDATED,
59
guint lomo_stream_signals[LAST_SIGNAL] = { 0 };
62
stream_set_uri(LomoStream *self, const gchar *uri);
65
destroy_gvalue(GValue *value);
68
lomo_stream_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
70
LomoStream *self = LOMO_STREAM(object);
74
g_value_set_static_string(value, lomo_stream_get_tag(self, LOMO_TAG_URI));
77
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
82
lomo_stream_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
84
LomoStream *self = LOMO_STREAM(object);
88
stream_set_uri(self, g_value_get_string(value));
91
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
96
lomo_stream_dispose (GObject *object)
98
struct _LomoStreamPrivate *priv = LOMO_STREAM(object)->priv;
102
g_list_foreach(priv->tags, (GFunc) g_free, NULL);
103
g_list_free(priv->tags);
107
if (G_OBJECT_CLASS (lomo_stream_parent_class)->dispose)
108
G_OBJECT_CLASS (lomo_stream_parent_class)->dispose (object);
112
lomo_stream_class_init (LomoStreamClass *klass)
114
GObjectClass *object_class = G_OBJECT_CLASS (klass);
116
g_type_class_add_private (klass, sizeof (LomoStreamPrivate));
118
object_class->get_property = lomo_stream_get_property;
119
object_class->set_property = lomo_stream_set_property;
120
object_class->dispose = lomo_stream_dispose;
125
* URI corresponding to the stream
127
g_object_class_install_property(object_class, PROP_URI,
128
g_param_spec_string("uri", "uri", "uri",
129
NULL, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY|G_PARAM_STATIC_STRINGS));
132
* LomoStream::extended-metadata-updated:
133
* @stream: the object that recieved the signal
134
* @key: Name of the updated metadata key
136
* Emitted when extended metadata (cover, lyrics, etc...) is updated
139
lomo_stream_signals[SIGNAL_EXTENDED_METADATA_UPDATED] =
140
g_signal_new ("extended-metadata-updated",
141
G_OBJECT_CLASS_TYPE (object_class),
143
G_STRUCT_OFFSET (LomoStreamClass, extended_metadata_updated),
145
g_cclosure_marshal_VOID__STRING,
152
lomo_stream_init (LomoStream *self)
154
LomoStreamPrivate *priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), LOMO_TYPE_STREAM, LomoStreamPrivate);
156
priv->all_tags = FALSE;
162
* @uri: An uri to create a #LomoStream from.
164
* Create a new #LomoStream from an uri
166
* Returns: A new #LomoStream
169
lomo_stream_new (const gchar *uri)
171
return g_object_new (LOMO_TYPE_STREAM, "uri", uri, NULL);
175
stream_set_uri(LomoStream *self, const gchar *uri)
177
g_return_if_fail(LOMO_IS_STREAM(self));
178
g_return_if_fail(uri != NULL);
180
// Check valid URI, more strict methods than this: g_uri_parse_scheme
181
for (guint i = 0; uri[i] != '\0'; i++)
182
if ((uri[i] < 20) || (uri[i] > 126))
183
g_warning(_("'%s' is not a valid URI"), uri);
185
if (!uri && (strstr(uri, "://") == NULL))
186
g_warning(_("'%s' is not a valid URI"), uri);
188
g_object_set_data_full(G_OBJECT(self), LOMO_TAG_URI, g_strdup(uri), g_free);
192
lomo_stream_string_parser_cb(gchar tag_key, LomoStream *self)
195
gchar *tag_str = lomo_stream_get_tag_by_id(self, tag_key);
200
if ((tag_key == 't') && (ret == NULL))
202
const gchar *tmp = lomo_stream_get_tag(self, LOMO_TAG_URI);
203
gchar *tmp2 = g_uri_unescape_string(tmp, NULL);
204
ret = g_path_get_basename(tmp2);
211
* lomo_stream_get_tag:
212
* @self: a #LomoStream
215
* Gets a tag from #LomoStream. The returned value is owned by @stream, and
216
* should not be modified (Internally it uses g_object_get_data).
218
* Returns: A pointer to the tag value
221
lomo_stream_get_tag(LomoStream *self, const gchar *tag)
223
g_return_val_if_fail(LOMO_IS_STREAM(self), NULL);
224
g_return_val_if_fail(tag, NULL);
226
const gchar *ret = g_object_get_data((GObject *) self, tag);
231
* lomo_stream_set_tag:
232
* @self: a #LomoStream
233
* @tag: (in) (type gchar*) (transfer none): a #const gchar *to set
234
* @value: (in) (type gchar*) (transfer none): value for tag, must not be modified. It becomes owned by #LomoStream
236
* Sets a tag in a #LomoStream
239
lomo_stream_set_tag(LomoStream *self, const gchar *tag, gpointer value)
241
LomoStreamPrivate *priv = self->priv;
242
GList *link = g_list_find_custom(priv->tags, tag, (GCompareFunc) strcmp);
249
link->data = g_strdup(tag);
252
priv->tags = g_list_prepend(priv->tags, g_strdup(tag));
256
priv->tags = g_list_remove_link(priv->tags, link);
260
g_object_set_data_full(G_OBJECT(self), tag, value, g_free);
264
* lomo_stream_get_tags:
265
* @self: a #LomoStream
267
* Gets the list of #const gchar *for a #LomoStream
269
* Return value: (element-type utf8) (transfer full): a #GList, it must be freed when no longer needed, data too
272
lomo_stream_get_tags(LomoStream *self)
275
GList *iter = self->priv->tags;
278
ret = g_list_prepend(ret, g_strdup((gchar *) iter->data));
285
* lomo_stream_set_all_tags_flag:
286
* @self: a #LomoStream
287
* @value: (in): value for flag
289
* Sets the all_tags flag to value
292
lomo_stream_set_all_tags_flag(LomoStream *self, gboolean value)
294
self->priv->all_tags = value;
298
* lomo_stream_get_all_tags_flag:
299
* @self: a #LomoStream
301
* Gets value of all_tags flag
303
* Returns: the value of all_tags flag
306
lomo_stream_get_all_tags_flag(LomoStream *self)
308
return self->priv->all_tags;
312
* lomo_stream_set_failed_flag:
313
* @self: a #LomoStream
314
* @value: (in): value for flag
316
* Sets the failed flag to value
319
lomo_stream_set_failed_flag(LomoStream *self, gboolean value)
321
self->priv->failed = value;
325
* lomo_stream_get_failed_flag:
326
* @self: a #LomoStream
328
* Gets value of failed flag
330
* Returns: the value of failed flag
333
lomo_stream_get_failed_flag(LomoStream *self)
335
return self->priv->failed;
339
* lomo_stream_set_extended_metadata:
340
* @self: A #LomoStream
341
* @key: (transfer none): Key
342
* @value: (transfer full): Value to store
344
* Adds (or replaces) the value for the extended metadata for key
347
lomo_stream_set_extended_metadata(LomoStream *self, const gchar *key, GValue *value)
349
g_return_if_fail(LOMO_IS_STREAM(self));
350
g_return_if_fail(key != NULL);
351
g_return_if_fail(G_IS_VALUE(value));
353
gchar *k = g_strconcat("x-lomo-extended-metadata-", key, NULL);
354
g_object_set_data_full(G_OBJECT(self), k, value, (GDestroyNotify) destroy_gvalue);
357
g_signal_emit(self, lomo_stream_signals[SIGNAL_EXTENDED_METADATA_UPDATED], 0, key);
360
* lomo_stream_set_extended_metadata:
361
* @self: A #LomoStream
362
* @key: (transfer none): Key
363
* @value: (transfer none): Value to store
365
* Adds (or replaces) the value for the extended metadata for key
368
lomo_stream_set_extended_metadata_as_string(LomoStream *self, const gchar *key, const gchar *value)
370
g_return_if_fail(LOMO_IS_STREAM(self));
371
g_return_if_fail(key);
372
g_return_if_fail(value);
374
GValue *v = g_new0(GValue, 1);
375
g_value_set_string(g_value_init(v, G_TYPE_STRING), value);
376
lomo_stream_set_extended_metadata(self, key, v);
380
* lomo_stream_get_extended_metadata:
381
* @self: A #LomoStream
384
* See g_object_get_data()
386
* Returns: (transfer none): The value associated with the key
389
lomo_stream_get_extended_metadata(LomoStream *self, const gchar *key)
391
g_return_val_if_fail(LOMO_IS_STREAM(self), NULL);
393
gchar *k = g_strconcat("x-lomo-extended-metadata-", key, NULL);
394
GValue *ret = g_object_get_data(G_OBJECT(self), k);
401
* lomo_stream_get_extended_metadata_as_string
402
* @self: A #LomoStream
405
* See lomo_stream_get_extended_metadata()
407
* Returns: (transfer none): The value associated with the key as a string or
408
* %NULL if not found or key is not a string
411
lomo_stream_get_extended_metadata_as_string(LomoStream *self, const gchar *key)
413
GValue *v = lomo_stream_get_extended_metadata(self, key);
414
return (v && G_VALUE_HOLDS_STRING(v) ? g_value_get_string(v) : NULL);
418
* lomo_stream_get_tag_by_id:
419
* @self: a #LomoStream
420
* @id: (in): identifier for tag (t = title, b = album, etc...)
422
* Gets the tag value as string for the matching id
424
* Retuns: the tag value as string
427
lomo_stream_get_tag_by_id(LomoStream *self, gchar id)
432
for (i = 0; tag_fmt_table[i].key != 0; i++)
434
if (tag_fmt_table[i].key == id)
436
const gchar *tag_str = lomo_stream_get_tag(self, tag_fmt_table[i].tag);
439
ret = g_strdup_printf(tag_fmt_table[i].fmt, tag_str);
447
* lomo_tag_get_gtype:
448
* @tag: (in) (transfer none): a #LomoTag
450
* Queries for the #GType corresponding for the tag
452
* Returns: the #GType for tag
455
lomo_tag_get_gtype(const gchar *tag)
457
if (g_str_equal(tag, "uri"))
458
return G_TYPE_STRING;
459
return gst_tag_get_type(tag);
463
destroy_gvalue(GValue *value)
467
g_return_if_fail(G_IS_VALUE(value));
468
g_value_unset(value);