[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()