1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 /* vim:set et sts=4: */
3 /* IBus - The Input Bus
4  * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
5  * Copyright (C) 2008-2013 Red Hat, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
20  * USA
21  */
22 #include "ibusattrlist.h"
23 
24 /* functions prototype */
25 static void         ibus_attr_list_destroy      (IBusAttrList           *attr_list);
26 static gboolean     ibus_attr_list_serialize    (IBusAttrList           *attr_list,
27                                                  GVariantBuilder        *builder);
28 static gint         ibus_attr_list_deserialize  (IBusAttrList           *attr_list,
29                                                  GVariant               *variant);
30 static gboolean     ibus_attr_list_copy         (IBusAttrList           *dest,
31                                                  const IBusAttrList     *src);
32 
G_DEFINE_TYPE(IBusAttrList,ibus_attr_list,IBUS_TYPE_SERIALIZABLE)33 G_DEFINE_TYPE (IBusAttrList, ibus_attr_list, IBUS_TYPE_SERIALIZABLE)
34 
35 static void
36 ibus_attr_list_class_init (IBusAttrListClass *class)
37 {
38     IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
39     IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (class);
40 
41     object_class->destroy = (IBusObjectDestroyFunc) ibus_attr_list_destroy;
42 
43     serializable_class->serialize   = (IBusSerializableSerializeFunc) ibus_attr_list_serialize;
44     serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_attr_list_deserialize;
45     serializable_class->copy        = (IBusSerializableCopyFunc) ibus_attr_list_copy;
46 }
47 
48 static void
ibus_attr_list_init(IBusAttrList * attr_list)49 ibus_attr_list_init (IBusAttrList *attr_list)
50 {
51     attr_list->attributes = g_array_new (TRUE, TRUE, sizeof (IBusAttribute *));
52 }
53 
54 static void
ibus_attr_list_destroy(IBusAttrList * attr_list)55 ibus_attr_list_destroy (IBusAttrList *attr_list)
56 {
57     g_assert (IBUS_IS_ATTR_LIST (attr_list));
58 
59     gint i;
60     for (i = 0;; i++) {
61         IBusAttribute *attr;
62 
63         attr = ibus_attr_list_get (attr_list, i);
64         if (attr == NULL)
65             break;
66 
67         g_object_unref (attr);
68     }
69 
70     g_array_free (attr_list->attributes, TRUE);
71 
72     IBUS_OBJECT_CLASS (ibus_attr_list_parent_class)->destroy ((IBusObject *)attr_list);
73 }
74 
75 static gboolean
ibus_attr_list_serialize(IBusAttrList * attr_list,GVariantBuilder * builder)76 ibus_attr_list_serialize (IBusAttrList    *attr_list,
77                           GVariantBuilder *builder)
78 {
79     gboolean retval;
80     guint i;
81 
82     retval = IBUS_SERIALIZABLE_CLASS (ibus_attr_list_parent_class)->serialize ((IBusSerializable *)attr_list, builder);
83     g_return_val_if_fail (retval, FALSE);
84 
85     g_return_val_if_fail (IBUS_IS_ATTR_LIST (attr_list), FALSE);
86 
87     GVariantBuilder array;
88     g_variant_builder_init (&array, G_VARIANT_TYPE ("av"));
89 
90     for (i = 0;; i++) {
91         IBusAttribute *attr;
92         attr = ibus_attr_list_get (attr_list, i);
93         if (attr == NULL)
94             break;
95         g_variant_builder_add (&array, "v", ibus_serializable_serialize ((IBusSerializable *)attr));
96     }
97     g_variant_builder_add (builder, "av", &array);
98 
99     return TRUE;
100 }
101 
102 static gint
ibus_attr_list_deserialize(IBusAttrList * attr_list,GVariant * variant)103 ibus_attr_list_deserialize (IBusAttrList    *attr_list,
104                             GVariant        *variant)
105 {
106     gint retval = IBUS_SERIALIZABLE_CLASS (ibus_attr_list_parent_class)->deserialize ((IBusSerializable *)attr_list, variant);
107     g_return_val_if_fail (retval, 0);
108 
109     GVariantIter *iter = NULL;
110     g_variant_get_child (variant, retval++, "av", &iter);
111     GVariant *var;
112     while (g_variant_iter_loop (iter, "v", &var)) {
113         IBusAttribute *attr = IBUS_ATTRIBUTE (ibus_serializable_deserialize (var));
114         ibus_attr_list_append (attr_list, attr);
115     }
116     g_variant_iter_free (iter);
117 
118     return retval;
119 }
120 
121 
122 
123 static gboolean
ibus_attr_list_copy(IBusAttrList * dest,const IBusAttrList * src)124 ibus_attr_list_copy (IBusAttrList       *dest,
125                      const IBusAttrList *src)
126 {
127     gboolean retval;
128 
129     retval = IBUS_SERIALIZABLE_CLASS (ibus_attr_list_parent_class)->copy ((IBusSerializable *)dest,
130                                  (IBusSerializable *)src);
131     g_return_val_if_fail (retval, FALSE);
132 
133     g_return_val_if_fail (IBUS_IS_ATTR_LIST (dest), FALSE);
134     g_return_val_if_fail (IBUS_IS_ATTR_LIST (src), FALSE);
135 
136     gint i;
137     for (i = 0; ; i++) {
138         IBusAttribute *attr = ibus_attr_list_get ((IBusAttrList *)src, i);
139         if (attr == NULL) {
140             break;
141         }
142 
143         attr = (IBusAttribute *) ibus_serializable_copy ((IBusSerializable *) attr);
144         if (attr == NULL) {
145             g_warning ("can not copy attribute");
146             continue;
147         }
148 
149         ibus_attr_list_append (dest, attr);
150     }
151     return TRUE;
152 }
153 
154 IBusAttrList *
ibus_attr_list_new()155 ibus_attr_list_new ()
156 {
157     IBusAttrList *attr_list;
158     attr_list = g_object_new (IBUS_TYPE_ATTR_LIST, NULL);
159     return attr_list;
160 }
161 
162 void
ibus_attr_list_append(IBusAttrList * attr_list,IBusAttribute * attr)163 ibus_attr_list_append (IBusAttrList  *attr_list,
164                        IBusAttribute *attr)
165 {
166     g_assert (IBUS_IS_ATTR_LIST (attr_list));
167     g_assert (IBUS_IS_ATTRIBUTE (attr));
168 
169     g_object_ref_sink (attr);
170     g_array_append_val (attr_list->attributes, attr);
171 }
172 
173 IBusAttribute *
ibus_attr_list_get(IBusAttrList * attr_list,guint index)174 ibus_attr_list_get (IBusAttrList *attr_list,
175                     guint         index)
176 {
177     g_assert (IBUS_IS_ATTR_LIST (attr_list));
178     IBusAttribute *attr = NULL;
179 
180     if (index < attr_list->attributes->len) {
181         attr = g_array_index (attr_list->attributes, IBusAttribute *, index);
182     }
183 
184     return attr;
185 }
186 
187 
188