[Zope3-checkins] CVS: Zope3/src/zope/xmlpickle - __init__.py:1.1.2.1 ppml.py:1.1.2.1 xmlpickle.py:1.1.2.1 xyap.py:1.1.2.1
Jim Fulton
jim@zope.com
Mon, 23 Dec 2002 14:33:39 -0500
Update of /cvs-repository/Zope3/src/zope/xmlpickle
In directory cvs.zope.org:/tmp/cvs-serv19908/zope/xmlpickle
Added Files:
Tag: NameGeddon-branch
__init__.py ppml.py xmlpickle.py xyap.py
Log Message:
Initial renaming before debugging
=== Added File Zope3/src/zope/xmlpickle/__init__.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Utility for creating Python pickles in XML format.
The XMLPickle module exports two functions:
dumps(object) -- Returns an XML pickle
loads(xmlpickle) -- Returns an object loaded from the pickle.
"""
=== Added File Zope3/src/zope/xmlpickle/ppml.py === (930/1030 lines abridged)
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Provide conversion between Python pickles and XML
"""
from pickle import Unpickler
from pickle import \
PERSID, NONE, INT, BININT, BININT1, BININT2, LONG, FLOAT, \
BINFLOAT, STRING, BINSTRING, SHORT_BINSTRING, UNICODE, \
BINUNICODE, TUPLE, EMPTY_TUPLE, EMPTY_LIST, EMPTY_DICT, LIST, \
DICT, INST, OBJ, GLOBAL, REDUCE, GET, BINGET, LONG_BINGET, PUT, \
BINPUT, LONG_BINPUT, STOP, MARK, BUILD, SETITEMS, SETITEM, \
BINPERSID, APPEND, APPENDS
from cStringIO import StringIO
import struct
import base64
import marshal
import re
mdumps = marshal.dumps
mloads = marshal.loads
identifier = re.compile("^[_a-zA-Z][_a-zA-Z0-9]{1,40}$").match
def _convert_sub(string):
# We don't want to get returns "normalized away, so we quote them
# This means we can't use cdata.
rpos = string.find('\r')
lpos = string.find('<')
apos = string.find('&')
if rpos >= 0 or lpos >= 0 or apos >= 0:
# Need to do something about special characters
[-=- -=- -=- 930 lines omitted -=- -=- -=-]
v.extend(data[3])
v.append(BUILD)
return v
def classic_object(self, tag, data):
v = [MARK]
v.extend(data[2])
v.append(OBJ)
v = self.put(v, data[1])
v.extend(data[3])
v.append(BUILD)
return v
def global_(self, tag, data):
attrs=data[1]
module = attrs['module'].encode('ascii')
name = attrs['name'].encode('ascii')
return self.put((GLOBAL, module, '\n', name, '\n'), attrs)
def item(self, tag, data, key_name = 'key'):
attrs = data[1]
if key_name in attrs:
assert len(data) == 3
key = attrs[key_name].encode('ascii')
key = self._string(key, attrs)
value = data[2]
if type(value) is list:
value[0:0] = list(key)
else:
value = tuple(key) + value
return value
else:
assert len(data) == 4
key = data[2]
if type(key) is not list:
key = list(key)
key.extend(data[3])
return key
def attribute(self, tag, data):
return self.item(tag, data, 'name')
=== Added File Zope3/src/zope/xmlpickle/xmlpickle.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Pickle-based serialization of Python objects to and from XML.
$Id: xmlpickle.py,v 1.1.2.1 2002/12/23 19:33:37 jim Exp $
"""
from xml.parsers import expat
from cStringIO import StringIO
from cPickle import loads as pickle_loads
from pickle import \
Pickler as _StandardPickler, \
MARK as _MARK, \
EMPTY_DICT as _EMPTY_DICT, \
DICT as _DICT, \
SETITEM as _SETITEM, \
SETITEMS as _SETITEMS
import zope.xmlpickle.ppml
class _Pickler(_StandardPickler):
dispatch = {}
dispatch.update(_StandardPickler.dispatch)
def save_dict(self, object):
d = id(object)
write = self.write
save = self.save
memo = self.memo
if self.bin:
write(_EMPTY_DICT)
else:
write(_MARK + _DICT)
memo_len = len(memo)
self.write(self.put(memo_len))
memo[d] = (memo_len, object)
using_setitems = (self.bin and (len(object) > 1))
if using_setitems:
write(_MARK)
items = object.items()
items.sort()
for key, value in items:
save(key)
save(value)
if not using_setitems:
write(_SETITEM)
if using_setitems:
write(_SETITEMS)
dispatch[dict] = save_dict
def _dumps(object, bin = 0):
file = StringIO()
_Pickler(file, bin).dump(object)
return file.getvalue()
def dumps(ob):
"""Serialize an object to XML
"""
p = _dumps(ob, 1)
u = ppml.ToXMLUnpickler(StringIO(p))
xmlob = u.load()
r = ['<?xml version="1.0" encoding="utf-8" ?>\n']
xmlob.output(r.append)
return ''.join(r)
def loads(xml):
"""Create an object from serialized XML
"""
handler = ppml.xmlPickler()
parser = expat.ParserCreate()
parser.CharacterDataHandler = handler.handle_data
parser.StartElementHandler = handler.handle_starttag
parser.EndElementHandler = handler.handle_endtag
parser.Parse(xml)
pickle = handler.get_value()
pickle = str(pickle)
ob = pickle_loads(pickle)
return ob
=== Added File Zope3/src/zope/xmlpickle/xyap.py ===
"""Yet another XML parser
This is meant to be very simple:
- stack based
- The parser has a table of start handlers and end handlers.
- start tag handlers are called with the parser instance, tag names
and attributes. The result is placed on the stack. The default
handler places a special object on the stack (uh, a list, with the
tag name and attributes as the first two elements. ;)
- end tag handlers are called with the object on the parser, the tag
name, and top of the stack right after it has been removed. The
result is appended to the object on the top of the stack.
Note that namespace attributes should recieve some special handling.
Oh well.
"""
import string
import xmllib
from pickle import *
from types import ListType
class xyap:
start_handlers={}
end_handlers={}
def __init__(self):
top=[]
self._stack=_stack=[top]
self.push=_stack.append
self.append=top.append
def handle_data(self, data): self.append(data)
def unknown_starttag(self, tag, attrs):
if type(attrs) is ListType:
x=0
temp={}
while x<len(attrs):
temp[attrs[x]]=attrs[x+1]
x=x+2
attrs=temp
start=self.start_handlers
if start.has_key(tag): tag = start[tag](self, tag, attrs)
else: tag = [tag, attrs]
self.push(tag)
self.append=tag.append
def unknown_endtag(self, tag):
_stack=self._stack
top=_stack[-1]
del _stack[-1]
append=self.append=_stack[-1].append
end=self.end_handlers
if end.has_key(tag): top=end[tag](self, tag, top)
append(top)
class NoBlanks:
def handle_data(self, data):
if string.strip(data): self.append(data)
def struct(self, tag, data):
r={}
for k, v in data[2:]: r[k]=v
return r
def name(self, tag, data, join=string.join, strip=string.strip):
return strip(join(data[2:],''))
def tuplef(self, tag, data): return tuple(data[2:])
class XYap(xyap, xmllib.XMLParser):
def __init__(self):
xmllib.XMLParser.__init__(self)
top=[]
self._stack=_stack=[top]
self.push=_stack.append
self.append=top.append
class xmlrpc(NoBlanks, XYap, xmllib.XMLParser):
end_handlers={
'methodCall': tuplef,
'methodName': name,
'params': tuplef,
'param': lambda self, tag, data: data[2],
'value': lambda self, tag, data: data[2],
'i4':
lambda self, tag, data, atoi=string.atoi, name=name:
atoi(name(self, tag, data)),
'int':
lambda self, tag, data, atoi=string.atoi, name=name:
atoi(name(self, tag, data)),
'boolean':
lambda self, tag, data, atoi=string.atoi, name=name:
atoi(name(self, tag, data)),
'string': lambda self, tag, data, join=string.join:
join(data[2:], ''),
'double':
lambda self, tag, data, atof=string.atof, name=name:
atof(name(self, tag, data)),
'float':
lambda self, tag, data, atof=string.atof, name=name:
atof(name(self, tag, data)),
'struct': struct,
'member': tuplef,
'name': name,
'array': lambda self, tag, data: data[2],
'data': lambda self, tag, data: data[2:],
}
def test():
data="""<?xml version="1.0"?>
<methodCall>
<methodName>examples.getStateName
</methodName>
<params>
<param>
<value><i4>41</i4></value>
</param>
<param><value>
<struct>
<member>
<name>lowerBound</name>
<value><i4>18</i4></value>
</member>
<member>
<name>upperBound</name>
<value><i4>139</i4></value>
</member>
</struct></value>
</param>
<param><value>
<array>
<data>
<value><i4>12</i4></value>
<value><string>Egypt</string></value>
<value><boolean>0</boolean></value>
<value><i4>-31</i4></value>
</data>
</array></value>
</param>
</params>
</methodCall>
"""
data=string.split(data,'\n')
r=[]
for C in XYap, xmlrpc:
p=C()
for l in data:
p.feed(l)
p.close()
r.append(p._stack)
return r
if __name__=='__main__': print test()