[omniORB] Passing dictionary.

William Noon noon@snow.nrcc.cornell.edu
Thu Jun 20 13:48:01 2002


On Thu, 20 Jun 2002 09:48:07, Duncan Grisby wrote:
> 
> On Thursday 20 June, Nathaniel Smith wrote:
> 
> > I think you misunderstood -- "dictionary" is Python-ese for "hash
> > table".  It's a basic mapping type, and I've wondered what the best
> > way to send one down the wire is myself.  I don't really have a good
> > answer, though; one option would of course be to wrap it in a CORBA
> > object with methods "get", "set", etc., but if you want to actually
> > send the whole dictionary across the wire, then you'll have to do some
> > "marshalling" by hand.
> > 
> > Perhaps to send a dictionary mapping strings to strings, one could use
> >   struct StrStrPair { string key, value; }
> >   typedef sequence<StrStrPair> StrStrDictionary;
> > and then pack/unpack by hand on each end of the connection.
> 
> Yes, that's a sensible representation for a Python dictionary. Of
> course, Python dictionaries can contain values with any types, and
> keys with a wide range of types, not just strings. To cope with all
> Python dictionaries in a single CORBA type, you'd have to use a
> sequence of structs of Anys. That would be a real pain, though.
> 
> ILU had (has?) an interesting feature where if you have a sequence of
> structs, and the struct's member names are "key" and "value", it would
> map that to a Python dictionary, rather than the normal Python
> language mapping. I have resisted doing that sort of thing in
> omniORBpy since it's a bit too magic for my liking.
> 
I used to use that ILU functionality all the time, but it didn't end
up in the CORBA <-> python mapping and I converted all the dictionaries
to:
	struct NameAnyPair {string name; any value};
	typedef sequence<NameAnyPair> FieldsDict;

This requires that all keys in the dictionary to be strings but the values
can be any object (defined in the idl).  It is possible to pass a sequence
with several identical keys that would be overwritten in the resulting
python dictionary.

Filling the NameAnyPair sequence requires constructing any's for each value:

NameAny = Meta.MetaQuery.NameAnyPair
any = CORBA.Any
tc = CORBA.TypeCode
tc_short = CORBA.TC_short
tc_string = CORBA.TC_string

qual = [
        NameAny('postal',any(tc_string,'NY')),
        NameAny('clim_div_code',any(tc_string,'10')),
        NameAny('var_major_id',any(tc_short,4)),
        NameAny('begin_date',any(tc(ShortSeq),(2000,1,1))),
        NameAny('end_date',any(tc(ShortSeq),(2000,7,1))),
        ]

A simple function to de-marshal the NameAnySeq to a python dictionary would
be as follows:

def NameAny_to_dict(na) :
        ret = {}
        for a in na :
                ret[a.name] = a.value.value()
        return ret

This will silently remove any duplicate keys in the sequence (keeping the
lastest in the sequence).

--Bill Noon
Northeast Regional Climate Center
Cornell University