2 * go-data-cache-field.h : A field (named vector) within a cache of data
3 * containing the unique values (unodered). The cache contains the
4 * ordering, and allows replication.
6 * Copyright (C) 2008 Jody Goldberg (jody@gnome.org)
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) version 3.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
24 #include <gnumeric-config.h>
25 #include <go-data-cache-field-impl.h>
26 #include <go-data-cache-impl.h>
27 #include <go-data-cache.h>
31 #include <gsf/gsf-impl-utils.h>
32 #include <glib/gi18n-lib.h>
35 #define GO_DATA_CACHE_FIELD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GO_DATA_CACHE_FIELD_TYPE, GODataCacheFieldClass))
36 #define IS_GO_DATA_CACHE_FIELD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GO_DATA_CACHE_FIELD_TYPE))
37 #define GO_DATA_CACHE_FIELD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GO_DATA_CACHE_FIELD_TYPE, GODataCacheFieldClass))
41 PROP_CACHE
, /* GODataCache * */
42 PROP_NAME
, /* GOString */
44 PROP_BUCKETER
, /* GOValBucketer * */
45 PROP_GROUP_PARENT
/* int */
49 go_data_cache_field_init (GODataCacheField
*field
)
54 field
->group_parent
= -1;
55 field
->indexed
= NULL
;
56 field
->grouped
= NULL
;
57 go_val_bucketer_init (&field
->bucketer
);
60 static GObjectClass
*parent_klass
;
63 go_data_cache_field_finalize (GObject
*obj
)
65 GODataCacheField
*field
= (GODataCacheField
*)obj
;
67 field
->cache
= NULL
; /* we do not hold a ref */
69 go_string_unref (field
->name
); field
->name
= NULL
;
71 go_val_array_free (field
->indexed
);
72 field
->indexed
= NULL
;
73 go_val_array_free (field
->grouped
);
74 field
->grouped
= NULL
;
76 (parent_klass
->finalize
) (obj
);
80 go_data_cache_field_set_property (GObject
*obj
, guint property_id
,
81 GValue
const *value
, GParamSpec
*pspec
)
83 GODataCacheField
*field
= (GODataCacheField
*)obj
;
85 switch (property_id
) {
86 /* we do not hold a ref */
87 case PROP_CACHE
: field
->cache
= g_value_get_object (value
); break;
88 case PROP_NAME
: go_string_unref (field
->name
); field
->name
= g_value_dup_boxed (value
); break;
89 case PROP_BUCKETER
: field
->bucketer
= *((GOValBucketer
*)g_value_get_pointer (value
)); break;
90 case PROP_GROUP_PARENT
: field
->group_parent
= g_value_get_int (value
); break;
92 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj
, property_id
, pspec
);
97 go_data_cache_field_get_property (GObject
*obj
, guint property_id
,
98 GValue
*value
, GParamSpec
*pspec
)
100 GODataCacheField
const *field
= (GODataCacheField
const *)obj
;
101 switch (property_id
) {
102 case PROP_CACHE
: g_value_set_object (value
, field
->cache
); break;
103 case PROP_NAME
: g_value_set_boxed (value
, field
->name
); break;
104 case PROP_INDEX
: g_value_set_int (value
, field
->indx
); break;
105 case PROP_BUCKETER
: g_value_set_pointer (value
, (gpointer
) &field
->bucketer
); break;
106 case PROP_GROUP_PARENT
: g_value_set_int (value
, field
->group_parent
); break;
108 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj
, property_id
, pspec
);
113 go_data_cache_field_class_init (GODataCacheFieldClass
*klass
)
115 GObjectClass
*gobject_class
= (GObjectClass
*)klass
;
116 gobject_class
->set_property
= go_data_cache_field_set_property
;
117 gobject_class
->get_property
= go_data_cache_field_get_property
;
118 gobject_class
->finalize
= go_data_cache_field_finalize
;
120 g_object_class_install_property (gobject_class
, PROP_CACHE
,
121 g_param_spec_object ("cache", NULL
, NULL
,
122 GO_DATA_CACHE_TYPE
, GSF_PARAM_STATIC
| G_PARAM_READWRITE
));
123 g_object_class_install_property (gobject_class
, PROP_NAME
,
124 g_param_spec_boxed ("name", NULL
, NULL
, go_string_get_type (),
125 GSF_PARAM_STATIC
| G_PARAM_READWRITE
));
126 g_object_class_install_property (gobject_class
, PROP_INDEX
,
127 g_param_spec_int ("index", NULL
,
128 "Index to identify field if the header changes in the source",
130 GSF_PARAM_STATIC
| G_PARAM_READABLE
));
131 g_object_class_install_property (gobject_class
, PROP_BUCKETER
,
132 g_param_spec_pointer ("bucketer", NULL
,
133 "How to group values",
134 GSF_PARAM_STATIC
| G_PARAM_READWRITE
));
136 g_object_class_install_property (gobject_class
, PROP_GROUP_PARENT
,
137 g_param_spec_int ("group-base", NULL
,
138 "Index to CacheField of the source of the group",
140 GSF_PARAM_STATIC
| G_PARAM_READWRITE
));
142 /* Unclear how to select what is parent and what is child when dealing with groups */
143 g_object_class_install_property (gobject_class
, PROP_GROUP_PARENT
,
144 g_param_spec_int ("group-parent", NULL
,
145 "Index to CacheField with higher precedence in the group ?",
147 GSF_PARAM_STATIC
| G_PARAM_READWRITE
));
149 parent_klass
= g_type_class_peek_parent (klass
);
152 GSF_CLASS (GODataCacheField
, go_data_cache_field
,
153 go_data_cache_field_class_init
, go_data_cache_field_init
,
157 go_data_cache_field_get_cache (GODataCacheField
const *field
)
159 g_return_val_if_fail (IS_GO_DATA_CACHE_FIELD (field
), NULL
);
164 go_data_cache_field_get_name (GODataCacheField
const *field
)
166 g_return_val_if_fail (IS_GO_DATA_CACHE_FIELD (field
), go_string_ERROR ());
171 go_data_cache_field_get_vals (GODataCacheField
const *field
, gboolean group_val
)
173 g_return_val_if_fail (IS_GO_DATA_CACHE_FIELD (field
), NULL
);
174 return group_val
? field
->grouped
: field
->indexed
;
178 go_data_cache_field_set_vals (GODataCacheField
*field
, gboolean group_val
,
181 g_return_if_fail (IS_GO_DATA_CACHE_FIELD (field
));
183 go_val_array_free (group_val
? field
->grouped
: field
->indexed
);
185 field
->grouped
= vals
;
187 field
->indexed
= vals
;
191 go_data_cache_field_is_base (GODataCacheField
const *field
)
193 g_return_val_if_fail (IS_GO_DATA_CACHE_FIELD (field
), FALSE
);
194 g_print ("[%d] %s : parent = %d\n", field
->indx
, field
->name
->str
,
195 field
->group_parent
);
196 return field
->group_parent
< 0 || field
->group_parent
== field
->indx
;
200 go_data_cache_field_ref_type (GODataCacheField
const *field
)
202 g_return_val_if_fail (IS_GO_DATA_CACHE_FIELD (field
), GO_DATA_CACHE_FIELD_TYPE_NONE
);
203 return field
->ref_type
;
207 go_data_cache_field_get_val (GODataCacheField
const *field
, unsigned int record_num
)
212 g_return_val_if_fail (IS_GO_DATA_CACHE_FIELD (field
), NULL
);
214 p
= go_data_cache_records_index (field
->cache
, record_num
) + field
->offset
;
215 switch (field
->ref_type
) {
216 case GO_DATA_CACHE_FIELD_TYPE_NONE
:
218 case GO_DATA_CACHE_FIELD_TYPE_INLINE
:
219 return *((GOVal
**)p
);
220 case GO_DATA_CACHE_FIELD_TYPE_INDEXED_I8
:
223 case GO_DATA_CACHE_FIELD_TYPE_INDEXED_I16
:
226 case GO_DATA_CACHE_FIELD_TYPE_INDEXED_I32
:
230 g_warning ("unknown field type %d", field
->ref_type
);
234 return (idx
-- > 0) ? g_ptr_array_index (field
->indexed
, idx
) : NULL
;