[Zope3-checkins] CVS: Zope3/src/zope/xmlpickle - __init__.py:1.2 ppml.py:1.2 xmlpickle.py:1.2 xyap.py:1.2
Jim Fulton
jim@zope.com
Wed, 25 Dec 2002 09:16:07 -0500
Update of /cvs-repository/Zope3/src/zope/xmlpickle
In directory cvs.zope.org:/tmp/cvs-serv20790/src/zope/xmlpickle
Added Files:
__init__.py ppml.py xmlpickle.py xyap.py
Log Message:
Grand renaming:
- Renamed most files (especially python modules) to lower case.
- Moved views and interfaces into separate hierarchies within each
project, where each top-level directory under the zope package
is a separate project.
- Moved everything to src from lib/python.
lib/python will eventually go away. I need access to the cvs
repository to make this happen, however.
There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.
=== Zope3/src/zope/xmlpickle/__init__.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:16:06 2002
+++ Zope3/src/zope/xmlpickle/__init__.py Wed Dec 25 09:15:35 2002
@@ -0,0 +1,21 @@
+##############################################################################
+#
+# 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.
+"""
=== Zope3/src/zope/xmlpickle/ppml.py 1.1 => 1.2 === (931/1031 lines abridged)
--- /dev/null Wed Dec 25 09:16:06 2002
+++ Zope3/src/zope/xmlpickle/ppml.py Wed Dec 25 09:15:35 2002
@@ -0,0 +1,1028 @@
+##############################################################################
+#
+# 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."""
+
+import base64
+import marshal
+import re
+import struct
+
+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
+
+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:
[-=- -=- -=- 931 lines omitted -=- -=- -=-]
+ v = self.put(v, data[1])
+ 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')
=== Zope3/src/zope/xmlpickle/xmlpickle.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:16:06 2002
+++ Zope3/src/zope/xmlpickle/xmlpickle.py Wed Dec 25 09:15:35 2002
@@ -0,0 +1,98 @@
+##############################################################################
+#
+# 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$
+"""
+
+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
+
+from zope.xmlpickle import 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
=== Zope3/src/zope/xmlpickle/xyap.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:16:06 2002
+++ Zope3/src/zope/xmlpickle/xyap.py Wed Dec 25 09:15:35 2002
@@ -0,0 +1,170 @@
+"""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()