1 /* gdict-context.c - Abstract class for dictionary contexts
2  *
3  * Copyright (C) 2005  Emmanuele Bassi <ebassi@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this library. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /**
20  * SECTION:gdict-context
21  * @short_description: Interface for dictionary transports
22  *
23  * #GdictContext is an interface used to uniformly access dictionary
24  * transport objects. Each implementation of #GdictContext must provide
25  * functions for accessing the list of databases available on a dictionary
26  * source and the available matching strategies; a function for retrieving
27  * all words matching a given string, inside one (or more) of those databases
28  * and using one of those strategies; a function for querying one (or more)
29  * of those databases for a definition of a word.
30  *
31  * Implementations of the #GdictContext interface should query their
32  * dictionary sources asynchronously; methods of the #GdictContext interface
33  * should return immediately, and each time a new database, strategy, match
34  * or definition has been found, a signal should be fired by those
35  * implementations.
36  */
37 
38 #include "config.h"
39 
40 #include <glib/gi18n-lib.h>
41 
42 #include "gdict-context.h"
43 #include "gdict-enum-types.h"
44 #include "gdict-utils.h"
45 #include "gdict-marshal.h"
46 #include "gdict-context-private.h"
47 #include "gdict-private.h"
48 
49 
50 static void gdict_context_class_init (gpointer g_iface);
51 
52 
53 GType
gdict_context_get_type(void)54 gdict_context_get_type (void)
55 {
56   static GType context_type = 0;
57 
58   if (G_UNLIKELY (context_type == 0))
59     {
60       static GTypeInfo context_info =
61       {
62         sizeof (GdictContextIface),
63         NULL,                       /* base_init */
64         NULL,                       /* base_finalize */
65         (GClassInitFunc) gdict_context_class_init,
66       };
67 
68       context_type = g_type_register_static (G_TYPE_INTERFACE,
69       					     "GdictContext",
70       					     &context_info, 0);
71       g_type_interface_add_prerequisite (context_type, G_TYPE_OBJECT);
72     }
73 
74   return context_type;
75 }
76 
77 
78 static void
gdict_context_class_init(gpointer g_iface)79 gdict_context_class_init (gpointer g_iface)
80 {
81   GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
82 
83   /**
84    * GdictContext::lookup-start
85    * @context: the object which received the signal
86    *
87    * This signal is emitted when a look up operation has been issued using
88    * a #GdictContext.  Since every operation using a context is
89    * asynchronous, you can use this signal to know if the request has been
90    * issued or not.
91    *
92    * Since: 1.0
93    */
94   g_signal_new ("lookup-start",
95                 iface_type,
96                 G_SIGNAL_RUN_LAST,
97                 G_STRUCT_OFFSET (GdictContextIface, lookup_start),
98                 NULL, NULL,
99                 gdict_marshal_VOID__VOID,
100                 G_TYPE_NONE, 0);
101   /**
102    * GdictContext::lookup-end
103    * @context: the object which received the signal
104    *
105    * This signal is emitted when a look up operation that has been issued
106    * using a #GdictContext has been completed.  Since every operation using a
107    * context is asynchronous, you can use this signal to know if the request
108    * has been completed or not.
109    *
110    * Since: 1.0
111    */
112   g_signal_new ("lookup-end",
113                 iface_type,
114                 G_SIGNAL_RUN_LAST,
115                 G_STRUCT_OFFSET (GdictContextIface, lookup_end),
116                 NULL, NULL,
117                 gdict_marshal_VOID__VOID,
118                 G_TYPE_NONE, 0);
119  /**
120    * GdictContext::error
121    * @context: the object which received the signal
122    * @error: a #GError
123    *
124    * This signal is emitted when an error happened during an asynchronous
125    * request.
126    *
127    * Since: 1.0
128    */
129   g_signal_new ("error",
130                 iface_type,
131                 G_SIGNAL_RUN_LAST,
132                 G_STRUCT_OFFSET (GdictContextIface, error),
133                 NULL, NULL,
134                 gdict_marshal_VOID__POINTER,
135                 G_TYPE_NONE, 1,
136                 G_TYPE_POINTER);
137   /**
138    * GdictContext::database-lookup-start
139    * @context: the object which received the signal
140    *
141    * This signal is emitted when a database look up operation has been issued
142    * using a #GdictContext.  Since every operation using a context is
143    * asynchronous, you can use this signal to know if the request has been
144    * issued or not.
145    *
146    * Since: 1.0
147    */
148   g_signal_new ("database-lookup-start",
149                 iface_type,
150                 G_SIGNAL_RUN_LAST,
151                 G_STRUCT_OFFSET (GdictContextIface, database_lookup_start),
152                 NULL, NULL,
153                 gdict_marshal_VOID__VOID,
154                 G_TYPE_NONE, 0);
155   /**
156    * GdictContext::database-lookup-end
157    * @context: the object which received the signal
158    *
159    * This signal is emitted when a database look up operation that has been
160    * issued using a #GdictContext has been completed.  Since every operation
161    * using a context is asynchronous, you can use this signal to know if the
162    * request has been completed or not.
163    *
164    * Since: 1.0
165    */
166   g_signal_new ("database-lookup-end",
167                 iface_type,
168                 G_SIGNAL_RUN_LAST,
169                 G_STRUCT_OFFSET (GdictContextIface, database_lookup_end),
170                 NULL, NULL,
171                 gdict_marshal_VOID__VOID,
172                 G_TYPE_NONE, 0);
173   /**
174    * GdictContext::database-found
175    * @context: the object which received the signal
176    * @database: a #GdictDatabase
177    *
178    * This signal is emitted when a database request has found a database.
179    *
180    * Since: 1.0
181    */
182   g_signal_new ("database-found",
183                 iface_type,
184                 G_SIGNAL_RUN_LAST,
185                 G_STRUCT_OFFSET (GdictContextIface, database_found),
186                 NULL, NULL,
187                 gdict_marshal_VOID__BOXED,
188                 G_TYPE_NONE, 1,
189                 GDICT_TYPE_DATABASE);
190   /**
191    * GdictContext::strategy-found
192    * @context: the object which received the signal
193    * @strategy: a #GdictStrategy
194    *
195    * This signal is emitted when a strategy request has found a strategy.
196    *
197    * Since: 1.0
198    */
199   g_signal_new ("strategy-found",
200                 iface_type,
201                 G_SIGNAL_RUN_LAST,
202                 G_STRUCT_OFFSET (GdictContextIface, strategy_found),
203                 NULL, NULL,
204                 gdict_marshal_VOID__BOXED,
205                 G_TYPE_NONE, 1,
206                 GDICT_TYPE_STRATEGY);
207   /**
208    * GdictContext::match-found
209    * @context: the object which received the signal
210    * @match: a #GdictMatch
211    *
212    * This signal is emitted when a match request has found a match.
213    *
214    * Since: 1.0
215    */
216   g_signal_new ("match-found",
217                 iface_type,
218                 G_SIGNAL_RUN_LAST,
219                 G_STRUCT_OFFSET (GdictContextIface, match_found),
220                 NULL, NULL,
221                 gdict_marshal_VOID__BOXED,
222                 G_TYPE_NONE, 1,
223                 GDICT_TYPE_MATCH);
224   /**
225    * GdictContext::definition-lookup-start
226    * @context: the object which received the signal
227    *
228    * This signal is emitted when a definition look up operation has been
229    * issued using a #GdictContext.  Since every operation using a context
230    * is asynchronous, you can use this signal to know if the request has
231    * been issued or not.
232    *
233    * Since: 1.0
234    */
235   g_signal_new ("definition-lookup-start",
236                 iface_type,
237                 G_SIGNAL_RUN_LAST,
238                 G_STRUCT_OFFSET (GdictContextIface, definition_lookup_start),
239                 NULL, NULL,
240                 gdict_marshal_VOID__VOID,
241                 G_TYPE_NONE, 0);
242   /**
243    * GdictContext::definition-lookup-end
244    * @context: the object which received the signal
245    *
246    * This signal is emitted when a definition look up operation that has been
247    * issued using a #GdictContext has been completed.  Since every operation
248    * using a context is asynchronous, you can use this signal to know if the
249    * request has been completed or not.
250    *
251    * Since: 1.0
252    */
253   g_signal_new ("definition-lookup-end",
254                 iface_type,
255                 G_SIGNAL_RUN_LAST,
256                 G_STRUCT_OFFSET (GdictContextIface, definition_lookup_end),
257                 NULL, NULL,
258                 gdict_marshal_VOID__VOID,
259                 G_TYPE_NONE, 0);
260   /**
261    * GdictContext::definition-found
262    * @context: the object which received the signal
263    * @definition: a #GdictDefinition
264    *
265    * This signal is emitted when a definition request has found a definition.
266    *
267    * Since: 1.0
268    */
269   g_signal_new ("definition-found",
270                 iface_type,
271                 G_SIGNAL_RUN_LAST,
272                 G_STRUCT_OFFSET (GdictContextIface, definition_found),
273                 NULL, NULL,
274                 gdict_marshal_VOID__BOXED,
275                 G_TYPE_NONE, 1,
276                 GDICT_TYPE_DEFINITION);
277 
278   /**
279    * GdictContext:local-only
280    *
281    * Whether the context uses only local dictionaries or not.
282    *
283    * Since: 1.0
284    */
285   g_object_interface_install_property (g_iface,
286   				       g_param_spec_boolean ("local-only",
287                                                              "Local Only",
288                                                              "Whether the context uses only local dictionaries or not",
289   				       			     FALSE,
290   				       			     (G_PARAM_READABLE | G_PARAM_WRITABLE)));
291 }
292 
293 GQuark
gdict_context_error_quark(void)294 gdict_context_error_quark (void)
295 {
296   return g_quark_from_static_string ("gdict-context-error-quark");
297 }
298 
299 /**
300  * gdict_context_set_local_only:
301  * @context: a #GdictContext
302  * @local_only: %TRUE if only local resources will be used
303  *
304  * Sets whether only local resources will be used when querying for databases,
305  * strategies, matches or definitions.
306  *
307  * Since: 1.0
308  */
309 void
gdict_context_set_local_only(GdictContext * context,gboolean local_only)310 gdict_context_set_local_only (GdictContext *context,
311 			      gboolean      local_only)
312 {
313   g_return_if_fail (GDICT_IS_CONTEXT (context));
314 
315   g_object_set (context, "local-only", &local_only, NULL);
316 }
317 
318 /**
319  * gdict_context_get_local_only:
320  * @context: a #GdictContext
321  *
322  * Gets whether only local resources will be used when querying.
323  *
324  * Return value: %TRUE if only local resources will be used.
325  *
326  * Since: 1.0
327  */
328 gboolean
gdict_context_get_local_only(GdictContext * context)329 gdict_context_get_local_only (GdictContext *context)
330 {
331   gboolean local_only;
332 
333   g_return_val_if_fail (GDICT_IS_CONTEXT (context), FALSE);
334 
335   g_object_get (context, "local-only", &local_only, NULL);
336 
337   return local_only;
338 }
339 
340 /**
341  * gdict_context_lookup_databases:
342  * @context: a #GdictContext
343  * @error: return location for a #GError, or %NULL
344  *
345  * Query @context for the list of databases available.  Each time a
346  * database is found, the "database-found" signal is fired.
347  *
348  * Return value: %TRUE if the query was successfully started.
349  *
350  * Since: 1.0
351  */
352 gboolean
gdict_context_lookup_databases(GdictContext * context,GError ** error)353 gdict_context_lookup_databases (GdictContext  *context,
354 				GError       **error)
355 {
356   g_return_val_if_fail (GDICT_IS_CONTEXT (context), FALSE);
357 
358   if (!GDICT_CONTEXT_GET_IFACE (context)->get_databases)
359     {
360       g_warning ("Object `%s' does not implement the get_databases "
361                  "virtual function.",
362                  g_type_name (G_OBJECT_TYPE (context)));
363 
364       return FALSE;
365     }
366 
367   return GDICT_CONTEXT_GET_IFACE (context)->get_databases (context, error);
368 }
369 
370 /**
371  * gdict_context_lookup_strategies:
372  * @context: a #GdictContext
373  * @error: return location for a #GError, or %NULL
374  *
375  * Query @context for the list of matching strategies available.  Each
376  * time a new strategy is found, the "strategy-found" signal is fired.
377  *
378  * Return value: %TRUE if the query was successfully started.
379  *
380  * Since: 1.0
381  */
382 gboolean
gdict_context_lookup_strategies(GdictContext * context,GError ** error)383 gdict_context_lookup_strategies (GdictContext  *context,
384 				 GError       **error)
385 {
386   g_return_val_if_fail (GDICT_IS_CONTEXT (context), FALSE);
387 
388   if (!GDICT_CONTEXT_GET_IFACE (context)->get_strategies)
389     {
390       g_warning ("Object `%s' does not implement the get_strategies "
391                  "virtual function.",
392                  g_type_name (G_OBJECT_TYPE (context)));
393 
394       return FALSE;
395     }
396 
397   return GDICT_CONTEXT_GET_IFACE (context)->get_strategies (context, error);
398 }
399 
400 /**
401  * gdict_context_match_word:
402  * @context: a #GdictContext
403  * @database: (nullable): a database name to search into, or %NULL for the
404  *    default database
405  * @strategy: (nullable): a strategy name to use for matching, or %NULL for
406  *    the default strategy
407  * @word: the word to match
408  * @error: return location for a #GError, or %NULL
409  *
410  * Query @context for a list of word matching @word inside @database,
411  * using @strategy as a matching strategy.  Each time a matching word
412  * is found, the "match-found" signal is fired.
413  *
414  * Return value: %TRUE if the query was successfully started.
415  *
416  * Since: 1.0
417  */
418 gboolean
gdict_context_match_word(GdictContext * context,const gchar * database,const gchar * strategy,const gchar * word,GError ** error)419 gdict_context_match_word (GdictContext  *context,
420 			  const gchar   *database,
421 			  const gchar   *strategy,
422 			  const gchar   *word,
423 			  GError       **error)
424 {
425   g_return_val_if_fail (GDICT_IS_CONTEXT (context), FALSE);
426   g_return_val_if_fail (word != NULL, FALSE);
427 
428   if (!GDICT_CONTEXT_GET_IFACE (context)->match_word)
429     {
430       g_warning ("Object `%s' does not implement the match_word "
431                  "virtual function.",
432                  g_type_name (G_OBJECT_TYPE (context)));
433 
434       return FALSE;
435     }
436 
437   return GDICT_CONTEXT_GET_IFACE (context)->match_word (context,
438   							database,
439   							strategy,
440   							word,
441   							error);
442 }
443 
444 /**
445  * gdict_context_define_word:
446  * @context: a #GdictContext
447  * @database: (nullable): a database name to search into, or %NULL for the
448  *    default database
449  * @word: the word to search
450  * @error: return location for a #GError, or %NULL
451  *
452  * Query @context for a list of definitions of @word inside @database.  Each
453  * time a new definition is found, the "definition-found" signal is fired.
454  *
455  * Return value: %TRUE if the query was successfully sent.
456  *
457  * Since: 1.0
458  */
459 gboolean
gdict_context_define_word(GdictContext * context,const gchar * database,const gchar * word,GError ** error)460 gdict_context_define_word (GdictContext  *context,
461 			   const gchar   *database,
462 			   const gchar   *word,
463 			   GError       **error)
464 {
465   g_return_val_if_fail (GDICT_IS_CONTEXT (context), FALSE);
466   g_return_val_if_fail (word != NULL, FALSE);
467 
468   if (!GDICT_CONTEXT_GET_IFACE (context)->define_word)
469     {
470       g_warning ("Object `%s' does not implement the define_word "
471                  "virtual function.",
472                  g_type_name (G_OBJECT_TYPE (context)));
473 
474       return FALSE;
475     }
476 
477   return GDICT_CONTEXT_GET_IFACE (context)->define_word (context,
478   							 database,
479   							 word,
480   							 error);
481 }
482 
483 
484 
485 /*****************
486  * GdictDatabase *
487  *****************/
488 
489 GDICT_DEFINE_BOXED_TYPE (GdictDatabase, gdict_database);
490 
491 GdictDatabase *
_gdict_database_new(const gchar * name)492 _gdict_database_new (const gchar *name)
493 {
494   GdictDatabase *retval;
495 
496   g_return_val_if_fail (name != NULL, NULL);
497 
498   retval = g_slice_new (GdictDatabase);
499   retval->name = g_strdup (name);
500   retval->full_name = NULL;
501   retval->ref_count = 1;
502 
503   return retval;
504 }
505 
506 /**
507  * gdict_database_ref:
508  * @db: a #GdictDatabase
509  *
510  * Increases the reference count of @db by one.
511  *
512  * Return value: @db with its reference count increased
513  *
514  * Since: 1.0
515  */
516 GdictDatabase *
gdict_database_ref(GdictDatabase * db)517 gdict_database_ref (GdictDatabase *db)
518 {
519   g_return_val_if_fail (db != NULL, NULL);
520 
521   g_assert (db->ref_count != 0);
522 
523   db->ref_count += 1;
524 
525   return db;
526 }
527 
528 /**
529  * gdict_database_unref:
530  * @db: a #GdictDatabase
531  *
532  * Decreases the reference count of @db by one.  If the reference count reaches
533  * zero, @db is destroyed.
534  *
535  * Since: 1.0
536  */
537 void
gdict_database_unref(GdictDatabase * db)538 gdict_database_unref (GdictDatabase *db)
539 {
540   g_return_if_fail (db != NULL);
541 
542   g_assert (db->ref_count != 0);
543 
544   db->ref_count -= 1;
545   if (db->ref_count == 0)
546     {
547       g_free (db->name);
548       g_free (db->full_name);
549 
550       g_slice_free (GdictDatabase, db);
551     }
552 }
553 
554 /**
555  * gdict_database_get_name:
556  * @db: a #GdictDatabase
557  *
558  * Gets the short name of the database, to be used with functions like
559  * gdict_context_match_word() or gdict_context_define_word().
560  *
561  * Return value: the short name of the database.  The string is owned by
562  *   the #GdictDatabase object, and should never be modified or freed.
563  *
564  * Since: 1.0
565  */
566 const gchar *
gdict_database_get_name(GdictDatabase * db)567 gdict_database_get_name (GdictDatabase *db)
568 {
569   g_return_val_if_fail (db != NULL, NULL);
570 
571   return db->name;
572 }
573 
574 /**
575  * gdict_database_get_full_name:
576  * @db: a #GdictDatabase
577  *
578  * Gets the full name of the database, suitable for display.
579  *
580  * Return value: the full name of the database.  The string is owned by
581  *   the #GdictDatabase object, and should never be modified or freed.
582  *
583  * Since: 1.0
584  */
585 const gchar *
gdict_database_get_full_name(GdictDatabase * db)586 gdict_database_get_full_name (GdictDatabase *db)
587 {
588   g_return_val_if_fail (db != NULL, NULL);
589 
590   return db->full_name;
591 }
592 
593 
594 
595 /*****************
596  * GdictStrategy *
597  *****************/
598 
599 GDICT_DEFINE_BOXED_TYPE (GdictStrategy, gdict_strategy);
600 
601 GdictStrategy *
_gdict_strategy_new(const gchar * name)602 _gdict_strategy_new (const gchar *name)
603 {
604   GdictStrategy *strat;
605 
606   g_return_val_if_fail (name != NULL, NULL);
607 
608   strat = g_slice_new (GdictStrategy);
609   strat->name = g_strdup (name);
610   strat->description = NULL;
611   strat->ref_count = 1;
612 
613   return strat;
614 }
615 
616 /**
617  * gdict_strategy_ref:
618  * @strat: a #GdictStrategy
619  *
620  * Increases the reference count of @strat by one.
621  *
622  * Return value: the #GdictStrategy object  with its reference count
623  *   increased
624  *
625  * Since: 1.0
626  */
627 GdictStrategy *
gdict_strategy_ref(GdictStrategy * strat)628 gdict_strategy_ref (GdictStrategy   *strat)
629 {
630   g_return_val_if_fail (strat != NULL, NULL);
631 
632   g_assert (strat->ref_count != 0);
633 
634   strat->ref_count += 1;
635 
636   return strat;
637 }
638 
639 /**
640  * gdict_strategy_unref:
641  * @strat: a #GdictStrategy
642  *
643  * Decreases the reference count of @strat by one.  If the reference count
644  * reaches zero, the #GdictStrategy object is freed.
645  *
646  * Since: 1.0
647  */
648 void
gdict_strategy_unref(GdictStrategy * strat)649 gdict_strategy_unref (GdictStrategy *strat)
650 {
651   g_return_if_fail (strat != NULL);
652 
653   g_assert (strat->ref_count != 0);
654 
655   strat->ref_count -= 1;
656   if (strat->ref_count == 0)
657     {
658       g_free (strat->name);
659       g_free (strat->description);
660 
661       g_slice_free (GdictStrategy, strat);
662     }
663 }
664 
665 /**
666  * gdict_strategy_get_name:
667  * @strat: a #GdictStrategy
668  *
669  * FIXME
670  *
671  * Return value: FIXME
672  *
673  * Since: 1.0
674  */
675 const gchar *
gdict_strategy_get_name(GdictStrategy * strat)676 gdict_strategy_get_name (GdictStrategy *strat)
677 {
678   g_return_val_if_fail (strat != NULL, NULL);
679 
680   return strat->name;
681 }
682 
683 /**
684  * gdict_strategy_get_description:
685  * @strat: a #GdictStrategy
686  *
687  * FIXME
688  *
689  * Return value: FIXME
690  *
691  * Since: 1.0
692  */
693 const gchar *
gdict_strategy_get_description(GdictStrategy * strat)694 gdict_strategy_get_description (GdictStrategy *strat)
695 {
696   g_return_val_if_fail (strat != NULL, NULL);
697 
698   return strat->description;
699 }
700 
701 
702 
703 /**************
704  * GdictMatch *
705  **************/
706 
707 GDICT_DEFINE_BOXED_TYPE (GdictMatch, gdict_match);
708 
709 GdictMatch *
_gdict_match_new(const gchar * word)710 _gdict_match_new (const gchar *word)
711 {
712   GdictMatch *match;
713 
714   g_return_val_if_fail (word != NULL, NULL);
715 
716   match = g_slice_new (GdictMatch);
717   match->word = g_strdup (word);
718   match->database = NULL;
719   match->ref_count = 1;
720 
721   return match;
722 }
723 
724 /**
725  * gdict_match_ref:
726  * @match: a #GdictMatch
727  *
728  * FIXME
729  *
730  * Return value: FIXME
731  *
732  * Since: 1.0
733  */
734 GdictMatch *
gdict_match_ref(GdictMatch * match)735 gdict_match_ref (GdictMatch *match)
736 {
737   g_return_val_if_fail (match != NULL, NULL);
738 
739   g_assert (match->ref_count != 0);
740 
741   match->ref_count += 1;
742 
743   return match;
744 }
745 
746 /**
747  * gdict_match_unref:
748  * @match: a #GdictMatch
749  *
750  * FIXME
751  *
752  * Since: 1.0
753  */
754 void
gdict_match_unref(GdictMatch * match)755 gdict_match_unref (GdictMatch *match)
756 {
757   g_return_if_fail (match != NULL);
758 
759   g_assert (match->ref_count != 0);
760 
761   match->ref_count -= 1;
762 
763   if (match->ref_count == 0)
764     {
765       g_free (match->word);
766       g_free (match->database);
767 
768       g_slice_free (GdictMatch, match);
769     }
770 }
771 
772 /**
773  * gdict_match_get_word:
774  * @match: a #GdictMatch
775  *
776  * FIXME
777  *
778  * Return value: FIXME
779  *
780  * Since: 1.0
781  */
782 const gchar *
gdict_match_get_word(GdictMatch * match)783 gdict_match_get_word (GdictMatch *match)
784 {
785   g_return_val_if_fail (match != NULL, NULL);
786 
787   return match->word;
788 }
789 
790 /**
791  * gdict_match_get_database:
792  * @match: a #GdictMatch
793  *
794  * FIXME
795  *
796  * Return value: FIXME
797  *
798  * Since: 1.0
799  */
800 const gchar *
gdict_match_get_database(GdictMatch * match)801 gdict_match_get_database (GdictMatch *match)
802 {
803   g_return_val_if_fail (match != NULL, NULL);
804 
805   return match->database;
806 }
807 
808 
809 
810 /*******************
811  * GdictDefinition *
812  *******************/
813 
814 GDICT_DEFINE_BOXED_TYPE (GdictDefinition, gdict_definition);
815 
816 /* GdictDefinition constructor */
817 GdictDefinition *
_gdict_definition_new(gint total)818 _gdict_definition_new (gint total)
819 {
820   GdictDefinition *def;
821 
822   def = g_slice_new (GdictDefinition);
823 
824   def->total = total;
825   def->word = NULL;
826   def->database_name = NULL;
827   def->database_full = NULL;
828   def->ref_count = 1;
829 
830   return def;
831 }
832 
833 /**
834  * gdict_definition_ref:
835  * @def: a #GdictDefinition
836  *
837  * Increases the reference count of @def by one.
838  *
839  * Return value: the #GdictDefinition object with its reference count
840  *   increased.
841  *
842  * Since: 1.0
843  */
844 GdictDefinition *
gdict_definition_ref(GdictDefinition * def)845 gdict_definition_ref (GdictDefinition *def)
846 {
847   g_return_val_if_fail (def != NULL, NULL);
848 
849   g_assert (def->ref_count != 0);
850 
851   def->ref_count += 1;
852 
853   return def;
854 }
855 
856 /**
857  * gdict_definition_unref:
858  * @def: a #GdictDefinition
859  *
860  * Decreases the reference count of @def by one.  If the reference count
861  * reaches zero, the #GdictDefinition object is freed.
862  *
863  * Since: 1.0
864  */
865 void
gdict_definition_unref(GdictDefinition * def)866 gdict_definition_unref (GdictDefinition *def)
867 {
868   g_return_if_fail (def != NULL);
869 
870   g_assert (def->ref_count != 0);
871 
872   def->ref_count -= 1;
873   if (def->ref_count == 0)
874     {
875       g_free (def->word);
876       g_free (def->database_name);
877       g_free (def->database_full);
878 
879       g_slice_free (GdictDefinition, def);
880     }
881 }
882 
883 /**
884  * gdict_definition_get_total:
885  * @def: a #GdictDefinition
886  *
887  * Retrieves the total number of definitions that were found on a
888  * dictionary.
889  *
890  * Return value: the number of definitions.
891  *
892  * Since: 1.0
893  */
894 gint
gdict_definition_get_total(GdictDefinition * def)895 gdict_definition_get_total (GdictDefinition *def)
896 {
897   g_return_val_if_fail (def != NULL, -1);
898 
899   return def->total;
900 }
901 
902 /**
903  * gdict_definition_get_word:
904  * @def: a #GdictDefinition
905  *
906  * Retrieves the word used by the dictionary database to store
907  * the definition.
908  *
909  * Return value: a word.  The returned string is owned by the
910  *   #GdictDefinition object and should not be modified or freed.
911  *
912  * Since: 1.0
913  */
914 const gchar *
gdict_definition_get_word(GdictDefinition * def)915 gdict_definition_get_word (GdictDefinition *def)
916 {
917   g_return_val_if_fail (def != NULL, NULL);
918 
919   return def->word;
920 }
921 
922 /**
923  * gdict_definition_get_database:
924  * @def: a #GdictDefinition
925  *
926  * Retrieves the full name of the dictionary database where the
927  * definition is stored.
928  *
929  * Return value: the full name of a database.  The returned string
930  *   is owned by the #GdictDefinition object and should not be
931  *   modified or freed.
932  *
933  * Since: 1.0
934  */
935 const gchar *
gdict_definition_get_database(GdictDefinition * def)936 gdict_definition_get_database (GdictDefinition *def)
937 {
938   g_return_val_if_fail (def != NULL, NULL);
939 
940   return def->database_full;
941 }
942 
943 /**
944  * gdict_definition_get_text:
945  * @def: a #GdictDefinition
946  *
947  * Retrieves the text of the definition.
948  *
949  * Return value: the text of the definition.  The returned string
950  *   is owned by the #GdictDefinition object, and should not be
951  *   modified or freed.
952  *
953  * Since: 1.0
954  */
955 const gchar *
gdict_definition_get_text(GdictDefinition * def)956 gdict_definition_get_text (GdictDefinition *def)
957 {
958   g_return_val_if_fail (def != NULL, NULL);
959 
960   return def->definition;
961 }
962