[Galago-devel] Soylent: Get and Set Fields API

Christian Hammond chipx86 at gnupdate.org
Fri Jul 15 10:46:51 EEST 2005


On Thu, Jul 14, 2005 at 10:15:36PM -0700, Travis Reitter wrote:
> I think I like this for the final, main function APIs:
> 
> static char*
> soylent_get_contact_field(unsigned int spid,
> 				SoylentContactField scf,
> 				SoylentLocation loc,
> 				unsigned int fieldPos);
> 
> /* 
>  * @returns int: number of bytes recorded
>  */
> unsigned int
> soylent_set_contact_field(unsigned int spid,
> 				SoylentContactField scf,
> 				SoylentLocation loc,
> 				unsigned int fieldPos,
> 				void* fieldData
> 				unsigned int dataSizeBytes);

<snip>

A couple comments on the above.

Rather than working with numeric IDs, we should be using an object
system. So:

unsigned int
soylent_person_set_contact_field(SoylentPerson *person, ......);

Also, the fact that we'd need to specify the data size means that
we're perhaps generalizing things too much, which could lead us to
trouble.

I've been jotting down notes on how I'd like to see this done. If you
like the idea, I'll put this all up on the wiki.

And here it is:


Proposed Design
===============

Introduction
------------

The whole API will be GObject-based, which gives us a nice signal and
property system, subclassing, and easy binding to several languages
through existing binding systems.


Object design
-------------

The main object of focus will be SoylentPerson. SoylentPerson is a
first-class object, providing an abstract interface to whatever
backend is in use. More on this later.

Rather than reinventing several wheels, the GObject property system
and signal system will be heavily used in SoylentPerson. Each property
of a person will be a GObject property. This allows for any program
that can introspect any GObject to get all the data about
SoylentPerson and lets us overcome several issues, such as needing to
re-implement marshalling.


Property generation
-------------------

As a lot of code is needed for each property, the whole property
support will be auto-generated from a perl script based on a data
file. The current format of that file that I have looks like this:

name {
    type: SoylentName *
}

nickname {
    type: string
}

emails {
    type: collection
    subtype: string
}

phones {
    type: collection
    subtype: string
}

ims {
    type: collection
    subtype: GalagoAccount *
}

And so on.

This file will be transformed into a .c and .h file that will be
compiled into the library. The type and subtype fields have some magic
values (string, boolean, integer, and collection). Anything
unrecognized is passed through (e.g., GalagoAccount *) and is assumed
to be a valid type.

Properties will be able to be marked as read-only. Otherwise, the
read-only/read-write state of the property will be dependent on the
backend. If a property is marked read-write in SoylentPerson, but the
backend only supports read-only, the read-only state takes precedence.
That is, both SoylentPerson and the backend must both specify
read-write for it to be read-write, otherwise it will be read-only.

The standard data types (string, integer, boolean) are fairly
self-explanatory. However, there is a special type called 'collection'
that should be described.

Collections
-----------

The collection data type represents a collection of data of type
'subtype.' This can be a collection of strings, a collection of
structs, etc. In code, this will be represented by a
SoylentCollection object. A SoylentCollection object maintains a list
of key, value pairs. The key is a human-readable label for the value,
and the value is of whatever type the collection holds. A list of
pairs can be retrieved from a collection, as can a list of labels
(keys) or list of values.

Signals can be attached to a collection to notify on any additions,
removals, or changes.

Many types of data will live in a collection. IM accounts, phone
numbers, and e-mails, to name a few.


Accessing Properties
--------------------

Properties can be accessed the standard GObject way. For example:

SoylentName *name;
SoylentCollection *phones;
char *nickname;

g_object_get(G_OBJECT(person),
             "name", &name,
             "phones", &phones,
             "nickname", &nickname,
             NULL);

g_free(nickname);
g_object_unref(name);
g_object_unref(phones);


or:


SoylentName *name = g_object_get_data(G_OBJECT(person), "name");


It's a fairly easy, standard API, with notifications on properties.
However, this could also be wrapped a bit more, in two ways (both of
which can be used). The first is a set of type-specific generic API
functions, such as:

SoylentName *name = soylent_person_get_struct(person, "name");
const char *soylent_person_get_string(person, "nickname");

and:

SoylentName *name = soylent_person_get_name(person);
const char *soylent_person_get_nickname(person);


The specific set of functions could be automatically created by the
generator script.


Property names won't actually have to be specified as literal strings.
The generator script will generate a set of #defines to map a constant
name to the literal string.


I'm tired, so that's all I'm writing up tonight :)

Christian

-- 
Christian Hammond         <>  The Galago Project
chipx86 at gnupdate.org      <>  http://www.galago.info/
   Best file compression around:  "DEL *.*" = 100% compression
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.freedesktop.org/archives/galago-devel/attachments/20050715/ebcc83e9/attachment.pgp 


More information about the galago-devel mailing list