Subject: Re: XML config file
To: Iain Hibbert <plunky@rya-online.net>
From: Jason Thorpe <thorpej@shagadelic.org>
List: tech-userlevel
Date: 07/23/2006 14:03:47
[ Resending, because the message got chopped off prematurely by the
MTA... ]
On Jul 22, 2006, at 1:36 PM, Iain Hibbert wrote:
> struct prop_hint {
> const char *name;
> prop_type_t type;
> void *arg;
> };
>
> struct prop_hint service_hints[] = {
> { "smtp", PROP_TYPE_DICTIONARY, NULL },
> { "nntp", PROP_TYPE_DICTIONARY, NULL },
> };
>
> struct prop_hint hints[] = {
> { "name", PROP_TYPE_STRING, NULL },
> { "address", PROP_TYPE_STRING, ip4 },
> { "services", PROP_TYPE_DICTIONARY, service_hints },
> };
>
> prop_object_t
> ip4(prop_string_t str)
> {
> /* we transform the string object to our preferred form */
> return obj or NULL;
> }
>
> dict = prop_dictionary_internalize(xml, hints);
>
> and if anything is not mentioned in the hints, it is just passed
> through
> as normal. Does anything like this exist in the OSXAPI?
No, the OS X property list API doesn't have anything like this. But
that's not too surprising, considering how the OS X APIs (esp. the
Foundation APIs) are designed to be used.
I like you suggestion, and I have been considering something like it
since the beginning of proplib, but I do not want it to be part of
the internalize step.
I have been thinking of a "property list ingest" helper that could
"parse" the internalized form (i.e. a prop_dictionary_t, NOT the
XML). The reason for this is that you might want to be able to pass
a dictionary to some application plugin or shared library and give it
the opportunity to gobble it up into its own format.
The stuff I've been playing around with looks a bit like this:
typedef boolean_t (*prop_ingest_handler_t)(void *, prop_object_t);
typedef struct {
const char *pite_key;
prop_type_t pite_type;
prop_ingest_handler_t pite_handler;
} prop_ingest_table_entry;
#define PROP_INGEST(key_, type_, handler_) \
{ .pite_key = key_, .pite_type = type_, \
.pite_handler = handler_ }
#define PROP_INGEST_END { .pite_key = NULL }
.
.
.
static prop_ingest_table_entry bsd44_geom_ingest_table[] = {
.
.
.
PROP_INGEST("sectors-per-unit", PROP_TYPE_NUMBER,
bsd44_geom_sectors_per_unit),
.
.
.
PROP_INGEST_END
};
static boolean_t
bsd44_geom_sectors_per_unit(void *v, prop_object_t obj)
{
struct bsd44_ingest_context *ctx = v;
struct disklabel *lp = ctx->label;
uint64_t val;
val = prop_number_integer_value(obj);
if (val > 0xffffffff) {
ctx->errorstr =
"sectors-per-unit exceeds maximum allowed value";
return (FALSE);
}
lp->d_secperunit = (uint32_t)(val & 0xffffffff);
return (TRUE);
}
.
.
.
{
.
.
.
struct disklabel *lp;
bsd44_ingest_context ctx;
.
.
.
geom_dict = prop_dictionary_get(props, "disk-geometry");
if (prop_object_type(geom_dict) != PROP_TYPE_DICTIONARY) {
/* return an error */
}
ctx.label = lp;
ctx.errorstr = NULL;
if (prop_dictionary_ingest(geom_dict,
bsd44_geom_ingest_table,
&ctx) == FALSE) {
/* return the error string */
}
.
.
.
(I've been toying around with this in partition map manipulation
library... in my new world order, a partition maps and other disk
information are dictionaries and arrays of dictionaries.)
-- thorpej