1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ |
---|
2 | /** |
---|
3 | * bonobo-moniker: Object naming abstraction |
---|
4 | * |
---|
5 | * Author: |
---|
6 | * Michael Meeks (michael@helixcode.com) |
---|
7 | * |
---|
8 | * Copyright 2000, Helix Code, Inc. |
---|
9 | */ |
---|
10 | #include <config.h> |
---|
11 | |
---|
12 | #include <bonobo/bonobo-exception.h> |
---|
13 | #include <bonobo/bonobo-moniker.h> |
---|
14 | #include <bonobo/bonobo-moniker-util.h> |
---|
15 | #include <bonobo/bonobo-moniker-extender.h> |
---|
16 | |
---|
17 | struct _BonoboMonikerPrivate { |
---|
18 | Bonobo_Moniker parent; |
---|
19 | |
---|
20 | int prefix_len; |
---|
21 | char *prefix; |
---|
22 | |
---|
23 | char *name; |
---|
24 | |
---|
25 | gboolean sensitive; |
---|
26 | }; |
---|
27 | |
---|
28 | #define PARENT_TYPE BONOBO_X_OBJECT_TYPE |
---|
29 | |
---|
30 | static GtkObjectClass *bonobo_moniker_parent_class; |
---|
31 | |
---|
32 | #define CLASS(o) BONOBO_MONIKER_CLASS (GTK_OBJECT (o)->klass) |
---|
33 | |
---|
34 | static inline BonoboMoniker * |
---|
35 | bonobo_moniker_from_servant (PortableServer_Servant servant) |
---|
36 | { |
---|
37 | return BONOBO_MONIKER (bonobo_object_from_servant (servant)); |
---|
38 | } |
---|
39 | |
---|
40 | static Bonobo_Moniker |
---|
41 | impl_get_parent (PortableServer_Servant servant, |
---|
42 | CORBA_Environment *ev) |
---|
43 | { |
---|
44 | BonoboMoniker *moniker = bonobo_moniker_from_servant (servant); |
---|
45 | |
---|
46 | return CLASS (moniker)->get_parent (moniker, ev); |
---|
47 | } |
---|
48 | |
---|
49 | static void |
---|
50 | impl_set_parent (PortableServer_Servant servant, |
---|
51 | const Bonobo_Moniker value, |
---|
52 | CORBA_Environment *ev) |
---|
53 | { |
---|
54 | BonoboMoniker *moniker = bonobo_moniker_from_servant (servant); |
---|
55 | |
---|
56 | CLASS (moniker)->set_parent (moniker, value, ev); |
---|
57 | } |
---|
58 | |
---|
59 | /** |
---|
60 | * bonobo_moniker_set_parent: |
---|
61 | * @moniker: the moniker |
---|
62 | * @parent: the parent |
---|
63 | * @ev: a corba exception environment |
---|
64 | * |
---|
65 | * This sets the monikers parent; a moniker is really a long chain |
---|
66 | * of hierarchical monikers; referenced by the most local moniker. |
---|
67 | * This sets the parent pointer. |
---|
68 | **/ |
---|
69 | void |
---|
70 | bonobo_moniker_set_parent (BonoboMoniker *moniker, |
---|
71 | Bonobo_Moniker parent, |
---|
72 | CORBA_Environment *ev) |
---|
73 | { |
---|
74 | g_return_if_fail (BONOBO_IS_MONIKER (moniker)); |
---|
75 | |
---|
76 | bonobo_object_release_unref (moniker->priv->parent, ev); |
---|
77 | moniker->priv->parent = bonobo_object_dup_ref (parent, ev); |
---|
78 | } |
---|
79 | |
---|
80 | /** |
---|
81 | * bonobo_moniker_get_parent: |
---|
82 | * @moniker: the moniker |
---|
83 | * @ev: a corba exception environment |
---|
84 | * |
---|
85 | * See bonobo_moniker_set_parent; |
---|
86 | * |
---|
87 | * Return value: the parent of this moniker |
---|
88 | **/ |
---|
89 | Bonobo_Moniker |
---|
90 | bonobo_moniker_get_parent (BonoboMoniker *moniker, |
---|
91 | CORBA_Environment *ev) |
---|
92 | { |
---|
93 | g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), |
---|
94 | CORBA_OBJECT_NIL); |
---|
95 | |
---|
96 | if (moniker->priv->parent == CORBA_OBJECT_NIL) |
---|
97 | return CORBA_OBJECT_NIL; |
---|
98 | |
---|
99 | return bonobo_object_dup_ref (moniker->priv->parent, ev); |
---|
100 | } |
---|
101 | |
---|
102 | /** |
---|
103 | * bonobo_moniker_get_name: |
---|
104 | * @moniker: the moniker |
---|
105 | * |
---|
106 | * gets the unescaped name of the moniker less the prefix eg |
---|
107 | * file:/tmp/hash\#.gz returns /tmp/hash#.gz |
---|
108 | * |
---|
109 | * Return value: the string |
---|
110 | **/ |
---|
111 | const char * |
---|
112 | bonobo_moniker_get_name (BonoboMoniker *moniker) |
---|
113 | { |
---|
114 | const char *str; |
---|
115 | |
---|
116 | g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), ""); |
---|
117 | |
---|
118 | str = CLASS (moniker)->get_name (moniker); |
---|
119 | |
---|
120 | if (str) |
---|
121 | return str + moniker->priv->prefix_len; |
---|
122 | else |
---|
123 | return ""; |
---|
124 | } |
---|
125 | |
---|
126 | /** |
---|
127 | * bonobo_moniker_get_name_full: |
---|
128 | * @moniker: the moniker |
---|
129 | * |
---|
130 | * gets the full unescaped display name of the moniker eg. |
---|
131 | * file:/tmp/hash\#.gz returns file:/tmp/hash#.gz |
---|
132 | * |
---|
133 | * Return value: the string |
---|
134 | **/ |
---|
135 | const char * |
---|
136 | bonobo_moniker_get_name_full (BonoboMoniker *moniker) |
---|
137 | { |
---|
138 | g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), ""); |
---|
139 | |
---|
140 | return CLASS (moniker)->get_name (moniker); |
---|
141 | } |
---|
142 | |
---|
143 | /** |
---|
144 | * bonobo_moniker_get_name_escaped: |
---|
145 | * @moniker: a moniker |
---|
146 | * |
---|
147 | * Get the full, escaped display name of the moniker eg. |
---|
148 | * file:/tmp/hash\#.gz returns file:/tmp/hash\#.gz |
---|
149 | * |
---|
150 | * Return value: the dynamically allocated string, |
---|
151 | * or NULL in case of failure. |
---|
152 | * Must release with g_free(). |
---|
153 | **/ |
---|
154 | char * |
---|
155 | bonobo_moniker_get_name_escaped (BonoboMoniker *moniker) |
---|
156 | { |
---|
157 | g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), NULL); |
---|
158 | |
---|
159 | return bonobo_moniker_util_escape ( |
---|
160 | CLASS (moniker)->get_name (moniker), 0); |
---|
161 | } |
---|
162 | |
---|
163 | /** |
---|
164 | * bonobo_moniker_set_name: |
---|
165 | * @moniker: the BonoboMoniker to configure. |
---|
166 | * @name: new name for this moniker. |
---|
167 | * @num_chars: number of characters in name to copy. |
---|
168 | * |
---|
169 | * This functions sets the moniker name in @moniker to be @name. |
---|
170 | */ |
---|
171 | void |
---|
172 | bonobo_moniker_set_name (BonoboMoniker *moniker, |
---|
173 | const char *name, |
---|
174 | int num_chars) |
---|
175 | { |
---|
176 | char *str; |
---|
177 | |
---|
178 | g_return_if_fail (BONOBO_IS_MONIKER (moniker)); |
---|
179 | |
---|
180 | str = bonobo_moniker_util_unescape (name, num_chars); |
---|
181 | |
---|
182 | CLASS (moniker)->set_name (moniker, str); |
---|
183 | |
---|
184 | g_free (str); |
---|
185 | } |
---|
186 | |
---|
187 | /** |
---|
188 | * bonobo_moniker_get_prefix: |
---|
189 | * @moniker: a moniker |
---|
190 | * |
---|
191 | * Return value: the registered prefix for this moniker or |
---|
192 | * NULL if there isn't one. eg "file:" |
---|
193 | **/ |
---|
194 | const char * |
---|
195 | bonobo_moniker_get_prefix (BonoboMoniker *moniker) |
---|
196 | { |
---|
197 | g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), ""); |
---|
198 | |
---|
199 | return moniker->priv->prefix; |
---|
200 | } |
---|
201 | |
---|
202 | static void |
---|
203 | impl_bonobo_moniker_set_name (BonoboMoniker *moniker, |
---|
204 | const char *unescaped_name) |
---|
205 | { |
---|
206 | g_return_if_fail (BONOBO_IS_MONIKER (moniker)); |
---|
207 | g_return_if_fail (strlen (unescaped_name) >= moniker->priv->prefix_len); |
---|
208 | |
---|
209 | g_free (moniker->priv->name); |
---|
210 | moniker->priv->name = g_strdup (unescaped_name); |
---|
211 | } |
---|
212 | |
---|
213 | static const char * |
---|
214 | impl_bonobo_moniker_get_name (BonoboMoniker *moniker) |
---|
215 | { |
---|
216 | g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), ""); |
---|
217 | |
---|
218 | return moniker->priv->name; |
---|
219 | } |
---|
220 | |
---|
221 | static CORBA_char * |
---|
222 | bonobo_moniker_default_get_display_name (BonoboMoniker *moniker, |
---|
223 | CORBA_Environment *ev) |
---|
224 | { |
---|
225 | CORBA_char *ans, *parent_name; |
---|
226 | char *tmp; |
---|
227 | |
---|
228 | parent_name = bonobo_moniker_util_get_parent_name ( |
---|
229 | BONOBO_OBJREF (moniker), ev); |
---|
230 | |
---|
231 | if (BONOBO_EX (ev)) |
---|
232 | return NULL; |
---|
233 | |
---|
234 | if (!parent_name) |
---|
235 | return CORBA_string_dup (moniker->priv->name); |
---|
236 | |
---|
237 | if (!moniker->priv->name) |
---|
238 | return parent_name; |
---|
239 | |
---|
240 | tmp = g_strdup_printf ("%s%s", parent_name, moniker->priv->name); |
---|
241 | |
---|
242 | if (parent_name) |
---|
243 | CORBA_free (parent_name); |
---|
244 | |
---|
245 | ans = CORBA_string_dup (tmp); |
---|
246 | |
---|
247 | g_free (tmp); |
---|
248 | |
---|
249 | return ans; |
---|
250 | } |
---|
251 | |
---|
252 | static Bonobo_Moniker |
---|
253 | bonobo_moniker_default_parse_display_name (BonoboMoniker *moniker, |
---|
254 | Bonobo_Moniker parent, |
---|
255 | const CORBA_char *name, |
---|
256 | CORBA_Environment *ev) |
---|
257 | { |
---|
258 | int i; |
---|
259 | |
---|
260 | g_return_val_if_fail (moniker != NULL, CORBA_OBJECT_NIL); |
---|
261 | g_return_val_if_fail (moniker->priv != NULL, CORBA_OBJECT_NIL); |
---|
262 | g_return_val_if_fail (strlen (name) >= moniker->priv->prefix_len, CORBA_OBJECT_NIL); |
---|
263 | |
---|
264 | bonobo_moniker_set_parent (moniker, parent, ev); |
---|
265 | |
---|
266 | i = bonobo_moniker_util_seek_std_separator (name, moniker->priv->prefix_len); |
---|
267 | |
---|
268 | bonobo_moniker_set_name (moniker, name, i); |
---|
269 | |
---|
270 | return bonobo_moniker_util_new_from_name_full (BONOBO_OBJREF (moniker), |
---|
271 | &name [i], ev); |
---|
272 | } |
---|
273 | |
---|
274 | static CORBA_long |
---|
275 | bonobo_moniker_default_equal (BonoboMoniker *moniker, |
---|
276 | const CORBA_char *display_name, |
---|
277 | CORBA_Environment *ev) |
---|
278 | { |
---|
279 | int i; |
---|
280 | CORBA_long offset; |
---|
281 | const char *p; |
---|
282 | char *name; |
---|
283 | |
---|
284 | if (moniker->priv->parent != CORBA_OBJECT_NIL) { |
---|
285 | offset = Bonobo_Moniker_equal ( |
---|
286 | moniker->priv->parent, display_name, ev); |
---|
287 | if (BONOBO_EX (ev) || offset == 0) |
---|
288 | return 0; |
---|
289 | } else |
---|
290 | offset = 0; |
---|
291 | |
---|
292 | p = &display_name [offset]; |
---|
293 | |
---|
294 | i = bonobo_moniker_util_seek_std_separator (p, moniker->priv->prefix_len); |
---|
295 | |
---|
296 | name = bonobo_moniker_get_name_escaped (moniker); |
---|
297 | |
---|
298 | /* FIXME: this has not been tested with moniker lists */ |
---|
299 | /* g_warning ("Compare %d chars of '%s' to '%s' - case sensitive ?%c", |
---|
300 | i, name, p, moniker->priv->sensitive?'y':'n');*/ |
---|
301 | |
---|
302 | if (( moniker->priv->sensitive && !strncmp (name, p, i)) || |
---|
303 | (!moniker->priv->sensitive && !g_strncasecmp (name, p, i))) { |
---|
304 | /* g_warning ("Matching moniker - equal");*/ |
---|
305 | return i + offset; |
---|
306 | } else { |
---|
307 | /* g_warning ("No match");*/ |
---|
308 | return 0; |
---|
309 | } |
---|
310 | |
---|
311 | g_free (name); |
---|
312 | } |
---|
313 | |
---|
314 | static CORBA_char * |
---|
315 | impl_get_display_name (PortableServer_Servant servant, |
---|
316 | CORBA_Environment *ev) |
---|
317 | { |
---|
318 | BonoboMoniker *moniker = bonobo_moniker_from_servant (servant); |
---|
319 | |
---|
320 | return CLASS (moniker)->get_display_name (moniker, ev); |
---|
321 | } |
---|
322 | |
---|
323 | static Bonobo_Moniker |
---|
324 | impl_parse_display_name (PortableServer_Servant servant, |
---|
325 | Bonobo_Moniker parent, |
---|
326 | const CORBA_char *name, |
---|
327 | CORBA_Environment *ev) |
---|
328 | { |
---|
329 | BonoboMoniker *moniker = bonobo_moniker_from_servant (servant); |
---|
330 | |
---|
331 | return CLASS (moniker)->parse_display_name (moniker, parent, name, ev); |
---|
332 | } |
---|
333 | |
---|
334 | static Bonobo_Unknown |
---|
335 | impl_resolve (PortableServer_Servant servant, |
---|
336 | const Bonobo_ResolveOptions *options, |
---|
337 | const CORBA_char *requested_interface, |
---|
338 | CORBA_Environment *ev) |
---|
339 | { |
---|
340 | BonoboMoniker *moniker = bonobo_moniker_from_servant (servant); |
---|
341 | Bonobo_Unknown retval; |
---|
342 | |
---|
343 | /* Try a standard resolve */ |
---|
344 | retval = CLASS (moniker)->resolve (moniker, options, |
---|
345 | requested_interface, ev); |
---|
346 | |
---|
347 | /* Try an extender */ |
---|
348 | if (!BONOBO_EX (ev) && retval == CORBA_OBJECT_NIL && |
---|
349 | moniker->priv->prefix) { |
---|
350 | |
---|
351 | Bonobo_Unknown extender; |
---|
352 | |
---|
353 | extender = bonobo_moniker_find_extender ( |
---|
354 | moniker->priv->prefix, |
---|
355 | requested_interface, ev); |
---|
356 | |
---|
357 | if (BONOBO_EX (ev)) |
---|
358 | return CORBA_OBJECT_NIL; |
---|
359 | |
---|
360 | else if (extender != CORBA_OBJECT_NIL) { |
---|
361 | retval = Bonobo_MonikerExtender_resolve ( |
---|
362 | extender, BONOBO_OBJREF (moniker), |
---|
363 | options, moniker->priv->name, |
---|
364 | requested_interface, ev); |
---|
365 | |
---|
366 | bonobo_object_release_unref (extender, ev); |
---|
367 | } |
---|
368 | } |
---|
369 | |
---|
370 | if (!BONOBO_EX (ev) && retval == CORBA_OBJECT_NIL) |
---|
371 | CORBA_exception_set (ev, CORBA_USER_EXCEPTION, |
---|
372 | ex_Bonobo_Moniker_InterfaceNotFound, |
---|
373 | NULL); |
---|
374 | |
---|
375 | return retval; |
---|
376 | } |
---|
377 | |
---|
378 | static CORBA_long |
---|
379 | impl_equal (PortableServer_Servant servant, |
---|
380 | const CORBA_char *displayName, |
---|
381 | CORBA_Environment *ev) |
---|
382 | { |
---|
383 | BonoboMoniker *moniker = bonobo_moniker_from_servant (servant); |
---|
384 | |
---|
385 | return CLASS (moniker)->equal (moniker, displayName, ev); |
---|
386 | } |
---|
387 | |
---|
388 | static void |
---|
389 | bonobo_moniker_destroy (GtkObject *object) |
---|
390 | { |
---|
391 | BonoboMoniker *moniker = BONOBO_MONIKER (object); |
---|
392 | |
---|
393 | if (moniker->priv->parent != CORBA_OBJECT_NIL) |
---|
394 | bonobo_object_release_unref (moniker->priv->parent, NULL); |
---|
395 | |
---|
396 | g_free (moniker->priv->prefix); |
---|
397 | g_free (moniker->priv->name); |
---|
398 | g_free (moniker->priv); |
---|
399 | |
---|
400 | bonobo_moniker_parent_class->destroy (object); |
---|
401 | } |
---|
402 | |
---|
403 | static void |
---|
404 | bonobo_moniker_class_init (BonoboMonikerClass *klass) |
---|
405 | { |
---|
406 | GtkObjectClass *oclass = (GtkObjectClass *)klass; |
---|
407 | POA_Bonobo_Moniker__epv *epv = &klass->epv; |
---|
408 | |
---|
409 | bonobo_moniker_parent_class = gtk_type_class (PARENT_TYPE); |
---|
410 | |
---|
411 | oclass->destroy = bonobo_moniker_destroy; |
---|
412 | |
---|
413 | klass->get_parent = bonobo_moniker_get_parent; |
---|
414 | klass->set_parent = bonobo_moniker_set_parent; |
---|
415 | klass->get_display_name = bonobo_moniker_default_get_display_name; |
---|
416 | klass->parse_display_name = bonobo_moniker_default_parse_display_name; |
---|
417 | klass->equal = bonobo_moniker_default_equal; |
---|
418 | |
---|
419 | klass->set_name = impl_bonobo_moniker_set_name; |
---|
420 | klass->get_name = impl_bonobo_moniker_get_name; |
---|
421 | |
---|
422 | epv->_get_parent = impl_get_parent; |
---|
423 | epv->_set_parent = impl_set_parent; |
---|
424 | epv->getDisplayName = impl_get_display_name; |
---|
425 | epv->parseDisplayName = impl_parse_display_name; |
---|
426 | epv->resolve = impl_resolve; |
---|
427 | epv->equal = impl_equal; |
---|
428 | } |
---|
429 | |
---|
430 | static void |
---|
431 | bonobo_moniker_init (GtkObject *object) |
---|
432 | { |
---|
433 | BonoboMoniker *moniker = BONOBO_MONIKER (object); |
---|
434 | |
---|
435 | moniker->priv = g_new (BonoboMonikerPrivate, 1); |
---|
436 | |
---|
437 | moniker->priv->parent = CORBA_OBJECT_NIL; |
---|
438 | moniker->priv->name = NULL; |
---|
439 | } |
---|
440 | |
---|
441 | BONOBO_X_TYPE_FUNC_FULL (BonoboMoniker, |
---|
442 | Bonobo_Moniker, |
---|
443 | PARENT_TYPE, |
---|
444 | bonobo_moniker); |
---|
445 | |
---|
446 | /** |
---|
447 | * bonobo_moniker_construct: |
---|
448 | * @moniker: an un-constructed moniker object. |
---|
449 | * @corba_moniker: a CORBA handle inheriting from Bonobo::Moniker, or |
---|
450 | * CORBA_OBJECT_NIL, in which case a base Bonobo::Moniker is created. |
---|
451 | * @prefix: the prefix name of the moniker eg. 'file:', '!' or 'tar:' or NULL |
---|
452 | * @shlib_id: |
---|
453 | * |
---|
454 | * Constructs a newly created bonobo moniker with the given arguments. |
---|
455 | * |
---|
456 | * Return value: the constructed moniker or NULL on failure. |
---|
457 | **/ |
---|
458 | BonoboMoniker * |
---|
459 | bonobo_moniker_construct (BonoboMoniker *moniker, |
---|
460 | const char *prefix) |
---|
461 | { |
---|
462 | if (prefix) { |
---|
463 | moniker->priv->prefix = g_strdup (prefix); |
---|
464 | moniker->priv->prefix_len = strlen (prefix); |
---|
465 | } |
---|
466 | |
---|
467 | moniker->priv->sensitive = TRUE; |
---|
468 | |
---|
469 | return moniker; |
---|
470 | } |
---|
471 | |
---|
472 | /** |
---|
473 | * bonobo_moniker_set_case_sensitive: |
---|
474 | * @moniker: the moniker |
---|
475 | * @sensitive: whether to see case on equality compare |
---|
476 | * |
---|
477 | * Sets up whether we use case sensitivity for the default equal impl. |
---|
478 | **/ |
---|
479 | void |
---|
480 | bonobo_moniker_set_case_sensitive (BonoboMoniker *moniker, |
---|
481 | gboolean sensitive) |
---|
482 | { |
---|
483 | g_return_if_fail (BONOBO_IS_MONIKER (moniker)); |
---|
484 | |
---|
485 | moniker->priv->sensitive = sensitive; |
---|
486 | } |
---|
487 | |
---|
488 | /** |
---|
489 | * bonobo_moniker_get_case_sensitive: |
---|
490 | * @moniker: the moniker |
---|
491 | * |
---|
492 | * Return value: whether we use case sensitivity for the default equal impl. |
---|
493 | **/ |
---|
494 | gboolean |
---|
495 | bonobo_moniker_get_case_sensitive (BonoboMoniker *moniker) |
---|
496 | { |
---|
497 | g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), FALSE); |
---|
498 | |
---|
499 | return moniker->priv->sensitive; |
---|
500 | } |
---|