| 
Here's an example implementation to further illustrate my point.
Regards,
Anthony Liguori
Anthony Liguori wrote:
 One of the first things I noticed is that the spec defines some 
extended types.  This is a bit challenging in XML-RPC.  It's unclear 
to me how 64 bit integer is represented (since XML-RPC only defines 32 
bit integers).  Also, defining void to an empty string is 
understandable but requires some special casing that really shouldn't 
be necessary.
Here's what I propose:
As a convention, we never use <struct>'s on the wire to directly 
represent structures.  By convention, structs always appear as: 
<struct>
<member><name>kind</name><value><string>[typename]</string></value></member> 
 <member><name>value</name><value>[typevalue]</value></member>
</struct>
Where typename is the string representation of the type and typevalue 
is the type-specific value. 
Some common types would be:
struct - use this to represent actual structs.  typevalue is the 
normal encoding of a struct
long - 64 bit representation of struct.  typevalue is the string 
representation 
void - use to represent None.  typevalue is ignored.
What's nice about this sort of consistent approach is that we can 
write a marshalling/unmarshalling wrapper for Python that 
automagically does this conversion.  Furthermore, if we did decide to 
support objects (as the current spec does), we could automagically 
marshal/unmarshal these over the wire. 
The general idea here is that this is an extensible typing system for 
XML-RPC. 
Another thing to consider is having a type of exception.  I like 
exception based APIs (i'll say that for another email) however the 
format of the standard XML-RPC exception leaves a lot to be desired. 
Thoughts?
Regards,
Anthony Liguori
_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-api
 
 import xmlrpclib
import SimpleXMLRPCServer
from types import DictType, NoneType
class Marshaller(xmlrpclib.Marshaller):
    def dump_struct(self, value, write, escape=xmlrpclib.escape):
        write("""<value><struct>
<member>
<name>type</name>
<value>struct</value>
</member>
<member>
<name>value</name>
""")
        self.__dump_struct(self, value, write, escape)
        write('</member></struct></value>\n')
    
    def __init__(self, encoding=None, allow_none=0):
        xmlrpclib.Marshaller.__init__(self, encoding, allow_none)
        self.__dump_struct = self.dispatch[DictType]
        self.dispatch[DictType] = Marshaller.dump_struct
class Unmarshaller(xmlrpclib.Unmarshaller):
    dispatch_ext = {}
    def ext_struct(self, value):
        return value
    dispatch_ext['struct'] = ext_struct
    def end_struct(self, data):
        self.__end_struct(self, data)
        if self._on:
            a = self._stack[-1]
            if self.dispatch_ext.has_key(a['type']):
                a = self.dispatch_ext[a['type']](self, a['value'])
            self._stack[-1] = a
            
        self._on = not self._on
    
    def __init__(self, *args):
        xmlrpclib.Unmarshaller.__init__(self)
        self.__end_struct = self.dispatch["struct"]
        self.dispatch["struct"] = Unmarshaller.end_struct
        self._on = False
xmlrpclib.FastMarshaller = Marshaller
xmlrpclib.FastParser = xmlrpclib.ExpatParser
xmlrpclib.FastUnmarshaller = Unmarshaller
a = xmlrpclib.ServerProxy("http://localhost:8001/RPC2")
print a.ident({'z': 'z', 'foo': {'poo': 'foo'}, 'doo': {'da': 'qe'}, 'a': 'b'})
_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-api
 |