Line data Source code
1 : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 : /*
3 : * lt-variant.c
4 : * Copyright (C) 2011-2012 Akira TAGOH
5 : *
6 : * Authors:
7 : * Akira TAGOH <akira@tagoh.org>
8 : *
9 : * You may distribute under the terms of either the GNU
10 : * Lesser General Public License or the Mozilla Public
11 : * License, as specified in the README file.
12 : */
13 : #ifdef HAVE_CONFIG_H
14 : #include "config.h"
15 : #endif
16 :
17 : #include <stdlib.h>
18 : #include <string.h>
19 : #include "lt-mem.h"
20 : #include "lt-messages.h"
21 : #include "lt-string.h"
22 : #include "lt-utils.h"
23 : #include "lt-variant.h"
24 : #include "lt-variant-private.h"
25 :
26 :
27 : /**
28 : * SECTION: lt-variant
29 : * @Short_Description: A container class for Variant subtag
30 : * @Title: Container - Variant
31 : *
32 : * This container class provides a data access to Variant subtag entry.
33 : */
34 : struct _lt_variant_t {
35 : lt_mem_t parent;
36 : char *tag;
37 : char *description;
38 : char *preferred_tag;
39 : lt_list_t *prefix;
40 : };
41 :
42 : /*< private >*/
43 :
44 : /*< protected >*/
45 : lt_variant_t *
46 252 : lt_variant_create(void)
47 : {
48 : lt_variant_t *retval;
49 :
50 252 : retval = lt_mem_alloc_object(sizeof (lt_variant_t));
51 :
52 252 : return retval;
53 : }
54 :
55 : void
56 252 : lt_variant_set_tag(lt_variant_t *variant,
57 : const char *subtag)
58 : {
59 252 : lt_return_if_fail (variant != NULL);
60 252 : lt_return_if_fail (subtag != NULL);
61 :
62 252 : if (variant->tag)
63 0 : lt_mem_delete_ref(&variant->parent, variant->tag);
64 252 : variant->tag = strdup(subtag);
65 252 : lt_mem_add_ref(&variant->parent, variant->tag, free);
66 : }
67 :
68 : void
69 4 : lt_variant_set_preferred_tag(lt_variant_t *variant,
70 : const char *subtag)
71 : {
72 4 : lt_return_if_fail (variant != NULL);
73 4 : lt_return_if_fail (subtag != NULL);
74 :
75 4 : if (variant->preferred_tag)
76 0 : lt_mem_delete_ref(&variant->parent, variant->preferred_tag);
77 4 : variant->preferred_tag = strdup(subtag);
78 4 : lt_mem_add_ref(&variant->parent, variant->preferred_tag, free);
79 : }
80 :
81 : void
82 252 : lt_variant_set_name(lt_variant_t *variant,
83 : const char *description)
84 : {
85 252 : lt_return_if_fail (variant != NULL);
86 252 : lt_return_if_fail (description != NULL);
87 :
88 252 : if (variant->description)
89 0 : lt_mem_delete_ref(&variant->parent, variant->description);
90 252 : variant->description = strdup(description);
91 252 : lt_mem_add_ref(&variant->parent, variant->description, free);
92 : }
93 :
94 : void
95 284 : lt_variant_add_prefix(lt_variant_t *variant,
96 : const char *prefix)
97 : {
98 : lt_bool_t no_prefixes;
99 :
100 284 : lt_return_if_fail (variant != NULL);
101 284 : lt_return_if_fail (prefix != NULL);
102 :
103 284 : no_prefixes = variant->prefix == NULL;
104 284 : variant->prefix = lt_list_append(variant->prefix, strdup(prefix), free);
105 284 : if (no_prefixes)
106 228 : lt_mem_add_ref(&variant->parent, variant->prefix, lt_list_free);
107 : }
108 :
109 : /*< public >*/
110 : /**
111 : * lt_variant_ref:
112 : * @variant: a #lt_variant_t.
113 : *
114 : * Increases the reference count of @variant.
115 : *
116 : * Returns: (transfer none): the same @variant object.
117 : */
118 : lt_variant_t *
119 244 : lt_variant_ref(lt_variant_t *variant)
120 : {
121 244 : lt_return_val_if_fail (variant != NULL, NULL);
122 :
123 244 : return lt_mem_ref(&variant->parent);
124 : }
125 :
126 : /**
127 : * lt_variant_unref:
128 : * @variant: a #lt_variant_t.
129 : *
130 : * Decreases the reference count of @variant. when its reference count
131 : * drops to 0, the object is finalized (i.e. its memory is freed).
132 : */
133 : void
134 496 : lt_variant_unref(lt_variant_t *variant)
135 : {
136 496 : if (variant)
137 496 : lt_mem_unref(&variant->parent);
138 496 : }
139 :
140 : /**
141 : * lt_variant_get_better_tag:
142 : * @variant: a #lt_variant_t.
143 : *
144 : * Obtains the better tag for use. this is a convenient function to get
145 : * the preferred-value if available.
146 : *
147 : * Returns: a tag string.
148 : */
149 : const char *
150 0 : lt_variant_get_better_tag(const lt_variant_t *variant)
151 : {
152 0 : const char *retval = lt_variant_get_preferred_tag(variant);
153 :
154 0 : if (!retval)
155 0 : retval = lt_variant_get_tag(variant);
156 :
157 0 : return retval;
158 : }
159 :
160 : /**
161 : * lt_variant_get_tag:
162 : * @variant: a #lt_variant_t.
163 : *
164 : * Obtains the tag name.
165 : *
166 : * Returns: a tag string.
167 : */
168 : const char *
169 252 : lt_variant_get_tag(const lt_variant_t *variant)
170 : {
171 252 : lt_return_val_if_fail (variant != NULL, NULL);
172 :
173 252 : return variant->tag;
174 : }
175 :
176 : /**
177 : * lt_variant_get_preferred_tag:
178 : * @variant: a #lt_variant_t.
179 : *
180 : * Obtains the preferred-value. this is available only when the tag is
181 : * marked as deprecated.
182 : *
183 : * Returns: a preferred-value for the tag or %NULL.
184 : */
185 : const char *
186 0 : lt_variant_get_preferred_tag(const lt_variant_t *variant)
187 : {
188 0 : lt_return_val_if_fail (variant != NULL, NULL);
189 :
190 0 : return variant->preferred_tag;
191 : }
192 :
193 : /**
194 : * lt_variant_get_name:
195 : * @variant: a #lt_variant_t.
196 : *
197 : * Obtains the description of the subtag.
198 : *
199 : * Returns: a description string.
200 : */
201 : const char *
202 0 : lt_variant_get_name(const lt_variant_t *variant)
203 : {
204 0 : lt_return_val_if_fail (variant != NULL, NULL);
205 :
206 0 : return variant->description;
207 : }
208 :
209 : /**
210 : * lt_variant_get_prefix:
211 : * @variant: a #lt_variant_t.
212 : *
213 : * Obtains the prefix being assigned to the subtag.
214 : * This is available only when the subtag has any suitable sequence of
215 : * subtags for forming (with other subtags, as appropriate) a language
216 : * tag when using the variant.
217 : *
218 : * Returns: (transfer none): a #lt_list_t contains prefix strings or %NULL.
219 : */
220 : const lt_list_t *
221 0 : lt_variant_get_prefix(const lt_variant_t *variant)
222 : {
223 0 : lt_return_val_if_fail (variant != NULL, NULL);
224 :
225 0 : return variant->prefix;
226 : }
227 :
228 : /**
229 : * lt_variant_dump:
230 : * @variant: a #lt_variant_t.
231 : *
232 : * Dumps the container information to the standard output.
233 : */
234 : void
235 0 : lt_variant_dump(const lt_variant_t *variant)
236 : {
237 0 : lt_string_t *string = lt_string_new(NULL);
238 : const lt_list_t *list, *l;
239 0 : const char *preferred = lt_variant_get_preferred_tag(variant);
240 :
241 0 : list = lt_variant_get_prefix(variant);
242 0 : for (l = list; l != NULL; l = lt_list_next(l)) {
243 0 : if (lt_string_length(string) == 0)
244 0 : lt_string_append(string, " (prefix = [");
245 : else
246 0 : lt_string_append(string, ", ");
247 0 : lt_string_append(string, (const char *)lt_list_value(l));
248 : }
249 0 : if (lt_string_length(string) > 0)
250 0 : lt_string_append(string, "]");
251 0 : if (preferred) {
252 0 : if (lt_string_length(string) == 0)
253 0 : lt_string_append(string, " (");
254 : else
255 0 : lt_string_append(string, ", ");
256 0 : lt_string_append_printf(string, "preferred-value: %s",
257 : preferred);
258 : }
259 0 : if (lt_string_length(string) > 0)
260 0 : lt_string_append(string, ")");
261 :
262 0 : lt_info("Variant: %s [%s]%s",
263 : lt_variant_get_tag(variant),
264 : lt_variant_get_name(variant),
265 : lt_string_value(string));
266 :
267 0 : lt_string_unref(string);
268 0 : }
269 :
270 : /**
271 : * lt_variant_compare:
272 : * @v1: a #lt_variant_t.
273 : * @v2: a #lt_variant_t.
274 : *
275 : * Compare if @v1 and @v2 is the same object or not.
276 : *
277 : * Returns: %TRUE if it's the same, otherwise %FALSE.
278 : */
279 : lt_bool_t
280 0 : lt_variant_compare(const lt_variant_t *v1,
281 : const lt_variant_t *v2)
282 : {
283 : const char *s1, *s2;
284 :
285 0 : if (v1 == v2)
286 0 : return TRUE;
287 :
288 0 : s1 = v1 ? lt_variant_get_tag(v1) : NULL;
289 0 : s2 = v2 ? lt_variant_get_tag(v2) : NULL;
290 :
291 0 : if (lt_strcmp0(s1, "*") == 0 ||
292 0 : lt_strcmp0(s2, "*") == 0)
293 0 : return TRUE;
294 :
295 0 : return lt_strcmp0(s1, s2) == 0;
296 : }
|