nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 * Copyright © 2011 William Hua
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the licence, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author: William Hua <william@attente.ca>
18 */
19  
20 #include "config.h"
21  
22 #include "gsettingsbackendinternal.h"
23 #include "gsimplepermission.h"
24 #include "giomodule.h"
25  
26 #import <Foundation/Foundation.h>
27  
28 GType g_nextstep_settings_backend_get_type (void);
29  
30 #define G_NEXTSTEP_SETTINGS_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), g_nextstep_settings_backend_get_type (), GNextstepSettingsBackend))
31  
32 typedef struct _GNextstepSettingsBackend GNextstepSettingsBackend;
33 typedef GSettingsBackendClass GNextstepSettingsBackendClass;
34  
35 struct _GNextstepSettingsBackend
36 {
37 GSettingsBackend parent_instance;
38  
39 /*< private >*/
40 NSUserDefaults *user_defaults;
41 GMutex mutex;
42 };
43  
44 G_DEFINE_TYPE_WITH_CODE (GNextstepSettingsBackend,
45 g_nextstep_settings_backend,
46 G_TYPE_SETTINGS_BACKEND,
47 g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
48 g_define_type_id, "nextstep", 90));
49  
50 static void g_nextstep_settings_backend_finalize (GObject *backend);
51  
52 static GVariant * g_nextstep_settings_backend_read (GSettingsBackend *backend,
53 const gchar *key,
54 const GVariantType *expected_type,
55 gboolean default_value);
56  
57 static gboolean g_nextstep_settings_backend_get_writable (GSettingsBackend *backend,
58 const gchar *key);
59  
60 static gboolean g_nextstep_settings_backend_write (GSettingsBackend *backend,
61 const gchar *key,
62 GVariant *value,
63 gpointer origin_tag);
64  
65 static gboolean g_nextstep_settings_backend_write_tree (GSettingsBackend *backend,
66 GTree *tree,
67 gpointer origin_tag);
68  
69 static void g_nextstep_settings_backend_reset (GSettingsBackend *backend,
70 const gchar *key,
71 gpointer origin_tag);
72  
73 static void g_nextstep_settings_backend_subscribe (GSettingsBackend *backend,
74 const gchar *name);
75  
76 static void g_nextstep_settings_backend_unsubscribe (GSettingsBackend *backend,
77 const gchar *name);
78  
79 static void g_nextstep_settings_backend_sync (GSettingsBackend *backend);
80  
81 static GPermission * g_nextstep_settings_backend_get_permission (GSettingsBackend *backend,
82 const gchar *path);
83  
84 static gboolean g_nextstep_settings_backend_write_pair (gpointer name,
85 gpointer value,
86 gpointer data);
87  
88 static GVariant * g_nextstep_settings_backend_get_g_variant (id object,
89 const GVariantType *type);
90  
91 static id g_nextstep_settings_backend_get_ns_object (GVariant *variant);
92  
93 static void
94 g_nextstep_settings_backend_class_init (GNextstepSettingsBackendClass *class)
95 {
96 G_OBJECT_CLASS (class)->finalize = g_nextstep_settings_backend_finalize;
97 class->read = g_nextstep_settings_backend_read;
98 class->get_writable = g_nextstep_settings_backend_get_writable;
99 class->write = g_nextstep_settings_backend_write;
100 class->write_tree = g_nextstep_settings_backend_write_tree;
101 class->reset = g_nextstep_settings_backend_reset;
102 class->subscribe = g_nextstep_settings_backend_subscribe;
103 class->unsubscribe = g_nextstep_settings_backend_unsubscribe;
104 class->sync = g_nextstep_settings_backend_sync;
105 class->get_permission = g_nextstep_settings_backend_get_permission;
106 }
107  
108 static void
109 g_nextstep_settings_backend_init (GNextstepSettingsBackend *self)
110 {
111 NSAutoreleasePool *pool;
112  
113 pool = [[NSAutoreleasePool alloc] init];
114  
115 self->user_defaults = [[NSUserDefaults standardUserDefaults] retain];
116  
117 g_mutex_init (&self->mutex);
118  
119 [pool drain];
120 }
121  
122 static void
123 g_nextstep_settings_backend_finalize (GObject *self)
124 {
125 GNextstepSettingsBackend *backend = G_NEXTSTEP_SETTINGS_BACKEND (self);
126 NSAutoreleasePool *pool;
127  
128 pool = [[NSAutoreleasePool alloc] init];
129  
130 g_mutex_clear (&backend->mutex);
131  
132 [backend->user_defaults release];
133  
134 [pool drain];
135  
136 G_OBJECT_CLASS (g_nextstep_settings_backend_parent_class)->finalize (self);
137 }
138  
139 static GVariant *
140 g_nextstep_settings_backend_read (GSettingsBackend *backend,
141 const gchar *key,
142 const GVariantType *expected_type,
143 gboolean default_value)
144 {
145 GNextstepSettingsBackend *self = G_NEXTSTEP_SETTINGS_BACKEND (backend);
146 NSAutoreleasePool *pool;
147 NSString *name;
148 id value;
149 GVariant *variant;
150  
151 if (default_value)
152 return NULL;
153  
154 pool = [[NSAutoreleasePool alloc] init];
155 name = [NSString stringWithUTF8String:key];
156  
157 g_mutex_lock (&self->mutex);
158 value = [self->user_defaults objectForKey:name];
159 g_mutex_unlock (&self->mutex);
160  
161 variant = g_nextstep_settings_backend_get_g_variant (value, expected_type);
162  
163 [pool drain];
164  
165 return variant;
166 }
167  
168 static gboolean
169 g_nextstep_settings_backend_get_writable (GSettingsBackend *backend,
170 const gchar *key)
171 {
172 return TRUE;
173 }
174  
175 static gboolean
176 g_nextstep_settings_backend_write (GSettingsBackend *backend,
177 const gchar *key,
178 GVariant *value,
179 gpointer origin_tag)
180 {
181 GNextstepSettingsBackend *self = G_NEXTSTEP_SETTINGS_BACKEND (backend);
182 NSAutoreleasePool *pool;
183  
184 pool = [[NSAutoreleasePool alloc] init];
185  
186 g_mutex_lock (&self->mutex);
187 g_nextstep_settings_backend_write_pair ((gpointer) key, value, self);
188 g_mutex_unlock (&self->mutex);
189  
190 g_settings_backend_changed (backend, key, origin_tag);
191  
192 [pool drain];
193  
194 return TRUE;
195 }
196  
197 static gboolean
198 g_nextstep_settings_backend_write_tree (GSettingsBackend *backend,
199 GTree *tree,
200 gpointer origin_tag)
201 {
202 GNextstepSettingsBackend *self = G_NEXTSTEP_SETTINGS_BACKEND (backend);
203 NSAutoreleasePool *pool;
204  
205 pool = [[NSAutoreleasePool alloc] init];
206  
207 g_mutex_lock (&self->mutex);
208 g_tree_foreach (tree, g_nextstep_settings_backend_write_pair, self);
209 g_mutex_unlock (&self->mutex);
210 g_settings_backend_changed_tree (backend, tree, origin_tag);
211  
212 [pool drain];
213  
214 return TRUE;
215 }
216  
217 static void
218 g_nextstep_settings_backend_reset (GSettingsBackend *backend,
219 const gchar *key,
220 gpointer origin_tag)
221 {
222 GNextstepSettingsBackend *self = G_NEXTSTEP_SETTINGS_BACKEND (backend);
223 NSAutoreleasePool *pool;
224 NSString *name;
225  
226 pool = [[NSAutoreleasePool alloc] init];
227 name = [NSString stringWithUTF8String:key];
228  
229 g_mutex_lock (&self->mutex);
230 [self->user_defaults removeObjectForKey:name];
231 g_mutex_unlock (&self->mutex);
232  
233 g_settings_backend_changed (backend, key, origin_tag);
234  
235 [pool drain];
236 }
237  
238 static void
239 g_nextstep_settings_backend_subscribe (GSettingsBackend *backend,
240 const gchar *name)
241 {
242 }
243  
244 static void
245 g_nextstep_settings_backend_unsubscribe (GSettingsBackend *backend,
246 const gchar *name)
247 {
248 }
249  
250 static void
251 g_nextstep_settings_backend_sync (GSettingsBackend *backend)
252 {
253 GNextstepSettingsBackend *self = G_NEXTSTEP_SETTINGS_BACKEND (backend);
254 NSAutoreleasePool *pool;
255  
256 pool = [[NSAutoreleasePool alloc] init];
257  
258 g_mutex_lock (&self->mutex);
259 [self->user_defaults synchronize];
260 g_mutex_unlock (&self->mutex);
261  
262 [pool drain];
263 }
264  
265 static GPermission *
266 g_nextstep_settings_backend_get_permission (GSettingsBackend *backend,
267 const gchar *path)
268 {
269 return g_simple_permission_new (TRUE);
270 }
271  
272 static gboolean
273 g_nextstep_settings_backend_write_pair (gpointer name,
274 gpointer value,
275 gpointer data)
276 {
277 GNextstepSettingsBackend *backend = G_NEXTSTEP_SETTINGS_BACKEND (data);
278 NSString *key;
279 id object;
280  
281 key = [NSString stringWithUTF8String:name];
282 object = g_nextstep_settings_backend_get_ns_object (value);
283  
284 [backend->user_defaults setObject:object forKey:key];
285  
286 return FALSE;
287 }
288  
289 static GVariant *
290 g_nextstep_settings_backend_get_g_variant (id object,
291 const GVariantType *type)
292 {
293 if ([object isKindOfClass:[NSData class]])
294 return g_variant_parse (type, [[[[NSString alloc] initWithData:object encoding:NSUTF8StringEncoding] autorelease] UTF8String], NULL, NULL, NULL);
295 else if ([object isKindOfClass:[NSNumber class]])
296 {
297 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
298 return g_variant_new_boolean ([object boolValue]);
299 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
300 return g_variant_new_byte ([object unsignedCharValue]);
301 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
302 return g_variant_new_int16 ([object shortValue]);
303 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
304 return g_variant_new_uint16 ([object unsignedShortValue]);
305 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
306 return g_variant_new_int32 ([object longValue]);
307 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
308 return g_variant_new_uint32 ([object unsignedLongValue]);
309 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
310 return g_variant_new_int64 ([object longLongValue]);
311 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
312 return g_variant_new_uint64 ([object unsignedLongLongValue]);
313 else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
314 return g_variant_new_handle ([object longValue]);
315 else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
316 return g_variant_new_double ([object doubleValue]);
317 }
318 else if ([object isKindOfClass:[NSString class]])
319 {
320 const char *string;
321  
322 string = [object UTF8String];
323  
324 if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
325 return g_variant_new_string (string);
326 else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
327 return g_variant_is_object_path (string) ?
328 g_variant_new_object_path (string) : NULL;
329 else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
330 return g_variant_is_signature (string) ?
331 g_variant_new_signature (string) : NULL;
332 }
333 else if ([object isKindOfClass:[NSDictionary class]])
334 {
335 if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE ("a{s*}")))
336 {
337 const GVariantType *value_type;
338 GVariantBuilder builder;
339 NSString *key;
340  
341 value_type = g_variant_type_value (g_variant_type_element (type));
342  
343 g_variant_builder_init (&builder, type);
344  
345 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
346 for(key in object)
347 #else
348 NSEnumerator *enumerator = [object objectEnumerator];
349 while((key = [enumerator nextObject]))
350 #endif
351 {
352 GVariant *name;
353 id value;
354 GVariant *variant;
355 GVariant *entry;
356  
357 name = g_variant_new_string ([key UTF8String]);
358 value = [object objectForKey:key];
359 variant = g_nextstep_settings_backend_get_g_variant (value, value_type);
360  
361 if (variant == NULL)
362 {
363 g_variant_builder_clear (&builder);
364  
365 return NULL;
366 }
367  
368 entry = g_variant_new_dict_entry (name, variant);
369 g_variant_builder_add_value (&builder, entry);
370 }
371  
372 return g_variant_builder_end (&builder);
373 }
374 }
375 else if ([object isKindOfClass:[NSArray class]])
376 {
377 if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_ARRAY))
378 {
379 const GVariantType *value_type;
380 GVariantBuilder builder;
381 id value;
382  
383 value_type = g_variant_type_element (type);
384 g_variant_builder_init (&builder, type);
385  
386 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
387 for(value in object)
388 #else
389 NSEnumerator *enumerator = [object objectEnumerator];
390 while((value = [enumerator nextObject]))
391 #endif
392 {
393 GVariant *variant = g_nextstep_settings_backend_get_g_variant (value, value_type);
394  
395 if (variant == NULL)
396 {
397 g_variant_builder_clear (&builder);
398  
399 return NULL;
400 }
401  
402 g_variant_builder_add_value (&builder, variant);
403 }
404  
405 return g_variant_builder_end (&builder);
406 }
407 }
408  
409 return NULL;
410 }
411  
412 static id
413 g_nextstep_settings_backend_get_ns_object (GVariant *variant)
414 {
415 if (variant == NULL)
416 return nil;
417 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
418 return [NSNumber numberWithBool:g_variant_get_boolean (variant)];
419 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTE))
420 return [NSNumber numberWithUnsignedChar:g_variant_get_byte (variant)];
421 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT16))
422 return [NSNumber numberWithShort:g_variant_get_int16 (variant)];
423 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT16))
424 return [NSNumber numberWithUnsignedShort:g_variant_get_uint16 (variant)];
425 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32))
426 return [NSNumber numberWithLong:g_variant_get_int32 (variant)];
427 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32))
428 return [NSNumber numberWithUnsignedLong:g_variant_get_uint32 (variant)];
429 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64))
430 return [NSNumber numberWithLongLong:g_variant_get_int64 (variant)];
431 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT64))
432 return [NSNumber numberWithUnsignedLongLong:g_variant_get_uint64 (variant)];
433 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_HANDLE))
434 return [NSNumber numberWithLong:g_variant_get_handle (variant)];
435 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE))
436 return [NSNumber numberWithDouble:g_variant_get_double (variant)];
437 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING))
438 return [NSString stringWithUTF8String:g_variant_get_string (variant, NULL)];
439 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_OBJECT_PATH))
440 return [NSString stringWithUTF8String:g_variant_get_string (variant, NULL)];
441 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_SIGNATURE))
442 return [NSString stringWithUTF8String:g_variant_get_string (variant, NULL)];
443 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE ("a{s*}")))
444 {
445 NSMutableDictionary *dictionary;
446 GVariantIter iter;
447 GVariant *name;
448 GVariant *value;
449  
450 dictionary = [NSMutableDictionary dictionaryWithCapacity:g_variant_iter_init (&iter, variant)];
451  
452 while (g_variant_iter_loop (&iter, "{s*}", &name, &value))
453 {
454 NSString *key;
455 id object;
456  
457 key = [NSString stringWithUTF8String:g_variant_get_string (name, NULL)];
458 object = g_nextstep_settings_backend_get_ns_object (value);
459  
460 [dictionary setObject:object forKey:key];
461 }
462  
463 return dictionary;
464 }
465 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_ARRAY))
466 {
467 NSMutableArray *array;
468 GVariantIter iter;
469 GVariant *value;
470  
471 array = [NSMutableArray arrayWithCapacity:g_variant_iter_init (&iter, variant)];
472  
473 while ((value = g_variant_iter_next_value (&iter)) != NULL)
474 [array addObject:g_nextstep_settings_backend_get_ns_object (value)];
475  
476 return array;
477 }
478 else
479 return [[NSString stringWithUTF8String:g_variant_print (variant, TRUE)] dataUsingEncoding:NSUTF8StringEncoding];
480 }