/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/**
* bonobo-moniker: Object naming abstraction
*
* Author:
* Michael Meeks (michael@helixcode.com)
*
* Copyright 2000, Ximian, Inc.
*/
#include "config.h"
#include <string.h>
#include <glib/gi18n-lib.h>
#include <bonobo/bonobo-exception.h>
#include <bonobo/bonobo-moniker.h>
#include <bonobo/bonobo-moniker-util.h>
#include <bonobo/bonobo-moniker-extender.h>
struct _BonoboMonikerPrivate {
Bonobo_Moniker parent;
int prefix_len;
char *prefix;
char *name;
gboolean sensitive;
};
#define PARENT_TYPE BONOBO_TYPE_OBJECT
static GObjectClass *bonobo_moniker_parent_class;
#define CLASS(o) BONOBO_MONIKER_CLASS (G_OBJECT_GET_CLASS (o))
static inline BonoboMoniker *
bonobo_moniker_from_servant (PortableServer_Servant servant)
{
return BONOBO_MONIKER (bonobo_object_from_servant (servant));
}
static Bonobo_Moniker
impl_get_parent (PortableServer_Servant servant,
CORBA_Environment *ev)
{
BonoboMoniker *moniker = bonobo_moniker_from_servant (servant);
return bonobo_moniker_get_parent (moniker, ev);
}
static void
impl_set_parent (PortableServer_Servant servant,
const Bonobo_Moniker value,
CORBA_Environment *ev)
{
BonoboMoniker *moniker = bonobo_moniker_from_servant (servant);
bonobo_moniker_set_parent (moniker, value, ev);
}
/**
* bonobo_moniker_set_parent:
* @moniker: the moniker
* @parent: the parent
* @opt_ev: an optional corba exception environment
*
* This sets the monikers parent; a moniker is really a long chain
* of hierarchical monikers; referenced by the most local moniker.
* This sets the parent pointer.
**/
void
bonobo_moniker_set_parent (BonoboMoniker *moniker,
Bonobo_Moniker parent,
CORBA_Environment *opt_ev)
{
CORBA_Environment ev, *my_ev;
bonobo_return_if_fail (BONOBO_IS_MONIKER (moniker), opt_ev);
if (!opt_ev) {
CORBA_exception_init (&ev);
my_ev = &ev;
} else
my_ev = opt_ev;
if (moniker->priv->parent != CORBA_OBJECT_NIL) {
Bonobo_Moniker_setParent (moniker->priv->parent, parent, my_ev);
} else
moniker->priv->parent = bonobo_object_dup_ref (parent, my_ev);
if (!opt_ev)
CORBA_exception_free (&ev);
}
/**
* bonobo_moniker_get_parent:
* @moniker: the moniker
* @opt_ev: an optional corba exception environment
*
* See bonobo_moniker_set_parent;
*
* Return value: the parent of this moniker
**/
Bonobo_Moniker
bonobo_moniker_get_parent (BonoboMoniker *moniker,
CORBA_Environment *opt_ev)
{
Bonobo_Moniker rval;
bonobo_return_val_if_fail (BONOBO_IS_MONIKER (moniker),
CORBA_OBJECT_NIL, opt_ev);
if (moniker->priv->parent == CORBA_OBJECT_NIL)
return CORBA_OBJECT_NIL;
rval = bonobo_object_dup_ref (moniker->priv->parent, opt_ev);
return rval;
}
/**
* bonobo_moniker_get_name:
* @moniker: the moniker
*
* gets the unescaped name of the moniker less the prefix eg
* file:/tmp/hash\#.gz returns /tmp/hash#.gz
*
* Return value: the string or NULL in case of failure
**/
const char *
bonobo_moniker_get_name (BonoboMoniker *moniker)
{
const char *str;
g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), NULL);
str = CLASS (moniker)->get_internal_name (moniker);
if (str)
return str + moniker->priv->prefix_len;
else
return "";
}
/**
* bonobo_moniker_get_name_full:
* @moniker: the moniker
*
* gets the full unescaped name of the moniker eg.
* file:/tmp/hash\#.gz returns file:/tmp/hash#.gz
*
* Return value: the string in case of failure
**/
const char *
bonobo_moniker_get_name_full (BonoboMoniker *moniker)
{
g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), NULL);
return CLASS (moniker)->get_internal_name (moniker);
}
/**
* bonobo_moniker_get_name_escaped:
* @moniker: a moniker
*
* Get the full, escaped name of the moniker eg.
* file:/tmp/hash\#.gz returns file:/tmp/hash\#.gz
*
* Return value: the dynamically allocated string,
* or NULL in case of failure.
* Must release with g_free().
**/
char *
bonobo_moniker_get_name_escaped (BonoboMoniker *moniker)
{
g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), NULL);
return bonobo_moniker_util_escape (
CLASS (moniker)->get_internal_name (moniker), 0);
}
/**
* bonobo_moniker_set_name:
* @moniker: the BonoboMoniker to configure.
* @name: new, unescaped, name for this moniker.
*
* This functions sets the moniker name in @moniker to be @name.
*/
void
bonobo_moniker_set_name (BonoboMoniker *moniker,
const char *name)
{
char *str;
g_return_if_fail (BONOBO_IS_MONIKER (moniker));
str = bonobo_moniker_util_unescape (name, strlen (name));
CLASS (moniker)->set_internal_name (moniker, str);
g_free (str);
}
/**
* bonobo_moniker_get_prefix:
* @moniker: a moniker
*
* Return value: the registered prefix for this moniker or
* NULL if there isn't one. eg "file:", or in case of failure
**/
const char *
bonobo_moniker_get_prefix (BonoboMoniker *moniker)
{
g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), NULL);
return moniker->priv->prefix;
}
static void
impl_bonobo_moniker_set_internal_name (BonoboMoniker *moniker,
const char *unescaped_name)
{
g_return_if_fail (BONOBO_IS_MONIKER (moniker));
g_return_if_fail (strlen (unescaped_name) >= moniker->priv->prefix_len);
g_free (moniker->priv->name);
moniker->priv->name = g_strdup (unescaped_name);
}
static const char *
impl_bonobo_moniker_get_internal_name (BonoboMoniker *moniker)
{
g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), NULL);
return moniker->priv->name;
}
static CORBA_char *
impl_get_name (PortableServer_Servant servant,
CORBA_Environment *ev)
{
BonoboMoniker *moniker = bonobo_moniker_from_servant (servant);
CORBA_char *ans, *parent_name;
char *tmp;
parent_name = Bonobo_Moniker_getName (moniker->priv->parent, ev);
if (BONOBO_EX (ev))
return NULL;
if (!parent_name)
return CORBA_string_dup (moniker->priv->name);
if (!moniker->priv->name)
return parent_name;
tmp = g_strdup_printf ("%s%s", parent_name, moniker->priv->name);
if (parent_name)
CORBA_free (parent_name);
ans = CORBA_string_dup (tmp);
g_free (tmp);
return ans;
}
static void
impl_set_name (PortableServer_Servant servant,
const CORBA_char *name,
CORBA_Environment *ev)
{
const char *mname;
int plen;
Bonobo_Moniker parent;
BonoboMoniker *moniker = bonobo_moniker_from_servant (servant);
bonobo_return_if_fail (moniker->priv != NULL, ev);
bonobo_return_if_fail (strlen (name) >= moniker->priv->prefix_len, ev);
mname = bonobo_moniker_util_parse_name (name, &plen);
if (plen) {
char *pname;
pname = g_strndup (name, plen);
parent = bonobo_moniker_client_new_from_name (pname, ev);
g_free (pname);
if (BONOBO_EX (ev))
return;
bonobo_object_release_unref (moniker->priv->parent, NULL);
moniker->priv->parent = bonobo_object_dup_ref (parent, ev);
}
bonobo_moniker_set_name (moniker, mname);
}
static Bonobo_Unknown
impl_resolve (PortableServer_Servant servant,
const Bonobo_ResolveOptions *options,
const CORBA_char *requested_interface,
CORBA_Environment *ev)
{
BonoboMoniker *moniker = bonobo_moniker_from_servant (servant);
Bonobo_Unknown retval;
/* Try a standard resolve */
retval = CLASS (moniker)->resolve (moniker, options,
requested_interface, ev);
/* Try an extender */
if (!BONOBO_EX (ev) && retval == CORBA_OBJECT_NIL &&
moniker->priv->prefix) {
Bonobo_Unknown extender;
extender = bonobo_moniker_find_extender (
moniker->priv->prefix,
requested_interface, ev);
if (BONOBO_EX (ev))
return CORBA_OBJECT_NIL;
else if (extender != CORBA_OBJECT_NIL) {
retval = Bonobo_MonikerExtender_resolve (
extender, BONOBO_OBJREF (moniker),
options, moniker->priv->name,
requested_interface, ev);
bonobo_object_release_unref (extender, ev);
}
}
if (!BONOBO_EX (ev) && retval == CORBA_OBJECT_NIL) {
bonobo_exception_general_error_set (
ev, NULL, _("Failed to resolve, or extend '%s"),
bonobo_moniker_get_name_full (moniker));
}
return retval;
}
static CORBA_long
impl_equal (PortableServer_Servant servant,
const CORBA_char *moniker_name,
CORBA_Environment *ev)
{
int i, retval;
CORBA_long offset;
const char *p;
char *name;
BonoboMoniker *moniker = bonobo_moniker_from_servant (servant);
if (moniker->priv->parent != CORBA_OBJECT_NIL) {
offset = Bonobo_Moniker_equal (
moniker->priv->parent, moniker_name, ev);
if (BONOBO_EX (ev) || offset == 0)
return 0;
} else
offset = 0;
p = &moniker_name [offset];
i = bonobo_moniker_util_seek_std_separator (p, moniker->priv->prefix_len);
name = bonobo_moniker_get_name_escaped (moniker);
/* g_warning ("Compare %d chars of '%s' to '%s' - case sensitive ?%c",
i, name, p, moniker->priv->sensitive?'y':'n');*/
if (( moniker->priv->sensitive && !strncmp (name, p, i)) ||
(!moniker->priv->sensitive && !g_ascii_strncasecmp (name, p, i))) {
/* g_warning ("Matching moniker - equal");*/
retval = i + offset;
} else {
/* g_warning ("No match");*/
retval = 0;
}
g_free (name);
return retval;
}
static void
bonobo_moniker_finalize (GObject *object)
{
BonoboMoniker *moniker = BONOBO_MONIKER (object);
if (moniker->priv->parent != CORBA_OBJECT_NIL)
bonobo_object_release_unref (moniker->priv->parent, NULL);
g_free (moniker->priv->prefix);
g_free (moniker->priv->name);
g_free (moniker->priv);
bonobo_moniker_parent_class->finalize (object);
}
static void
bonobo_moniker_class_init (BonoboMonikerClass *klass)
{
GObjectClass *oclass = (GObjectClass *)klass;
POA_Bonobo_Moniker__epv *epv = &klass->epv;
bonobo_moniker_parent_class = g_type_class_peek_parent (klass);
oclass->finalize = bonobo_moniker_finalize;
klass->set_internal_name = impl_bonobo_moniker_set_internal_name;
klass->get_internal_name = impl_bonobo_moniker_get_internal_name;
epv->getParent = impl_get_parent;
epv->setParent = impl_set_parent;
epv->getName = impl_get_name;
epv->setName = impl_set_name;
epv->resolve = impl_resolve;
epv->equal = impl_equal;
}
static void
bonobo_moniker_init (GObject *object)
{
BonoboMoniker *moniker = BONOBO_MONIKER (object);
moniker->priv = g_new (BonoboMonikerPrivate, 1);
moniker->priv->parent = CORBA_OBJECT_NIL;
moniker->priv->name = NULL;
moniker->priv->prefix = NULL;
}
BONOBO_TYPE_FUNC_FULL (BonoboMoniker,
Bonobo_Moniker,
PARENT_TYPE,
bonobo_moniker)
/**
* bonobo_moniker_construct:
* @moniker: an un-constructed moniker object.
* @prefix: the prefix name of the moniker eg. 'file:', '!' or 'tar:' or NULL
*
* Constructs a newly created bonobo moniker with the given arguments.
*
* Return value: the constructed moniker or NULL on failure.
**/
BonoboMoniker *
bonobo_moniker_construct (BonoboMoniker *moniker,
const char *prefix)
{
if (prefix) {
moniker->priv->prefix = g_strdup (prefix);
moniker->priv->prefix_len = strlen (prefix);
}
moniker->priv->sensitive = TRUE;
return moniker;
}
/**
* bonobo_moniker_set_case_sensitive:
* @moniker: the moniker
* @sensitive: whether to see case on equality compare
*
* Sets up whether we use case sensitivity for the default equal impl.
**/
void
bonobo_moniker_set_case_sensitive (BonoboMoniker *moniker,
gboolean sensitive)
{
g_return_if_fail (BONOBO_IS_MONIKER (moniker));
moniker->priv->sensitive = sensitive;
}
/**
* bonobo_moniker_get_case_sensitive:
* @moniker: the moniker
*
* Return value: whether we use case sensitivity for the default equal impl.
**/
gboolean
bonobo_moniker_get_case_sensitive (BonoboMoniker *moniker)
{
g_return_val_if_fail (BONOBO_IS_MONIKER (moniker), FALSE);
return moniker->priv->sensitive;
}
syntax highlighted by Code2HTML, v. 0.9.1