[Zope-Checkins] SVN: Zope/trunk/ LP #195761: fixed ZMI XML export / import and restored it to the UI.

Tres Seaver tseaver at palladion.com
Mon Feb 15 18:04:36 EST 2010


Log message for revision 109072:
  LP #195761: fixed ZMI XML export / import and restored it to the UI.
  

Changed:
  U   Zope/trunk/doc/CHANGES.rst
  U   Zope/trunk/src/OFS/XMLExportImport.py
  U   Zope/trunk/src/OFS/dtml/importExport.dtml
  A   Zope/trunk/src/OFS/tests/export.xml
  U   Zope/trunk/src/OFS/tests/test_XMLExportImport.py
  U   Zope/trunk/src/Shared/DC/xml/ppml.py

-=-
Modified: Zope/trunk/doc/CHANGES.rst
===================================================================
--- Zope/trunk/doc/CHANGES.rst	2010-02-15 05:35:58 UTC (rev 109071)
+++ Zope/trunk/doc/CHANGES.rst	2010-02-15 23:04:36 UTC (rev 109072)
@@ -133,6 +133,8 @@
 Bugs Fixed
 ++++++++++
 
+- LP #195761: fixed ZMI XML export / import and restored it to the UI.
+
 - LP #491224: proper escaping of rendered error message
 
 - LP #246983: Enabled unicode conflict resolution on variables inside "string:"

Modified: Zope/trunk/src/OFS/XMLExportImport.py
===================================================================
--- Zope/trunk/src/OFS/XMLExportImport.py	2010-02-15 05:35:58 UTC (rev 109071)
+++ Zope/trunk/src/OFS/XMLExportImport.py	2010-02-15 23:04:36 UTC (rev 109072)
@@ -14,6 +14,8 @@
 from cStringIO import StringIO
 from ZODB.serialize import referencesf
 from ZODB.ExportImport import TemporaryFile, export_end_marker
+from ZODB.utils import p64
+from ZODB.utils import u64
 from Shared.DC.xml import ppml
 
 
@@ -23,7 +25,7 @@
     q=ppml.ToXMLUnpickler
     f=StringIO(p)
     u=q(f)
-    id=ppml.u64(oid)
+    id=u64(oid)
     aka=encodestring(oid)[:-1]
     u.idprefix=str(id)+'.'
     p=u.load().__str__(4)
@@ -93,11 +95,11 @@
     file.seek(pos)
     a=data[1]
     if a.has_key('id'): oid=a['id']
-    oid=ppml.p64(int(oid))
+    oid=p64(int(oid))
     v=''
     for x in data[2:]:
         v=v+x
-    l=ppml.p64(len(v))
+    l=p64(len(v))
     v=oid+l+v
     return v
 

Modified: Zope/trunk/src/OFS/dtml/importExport.dtml
===================================================================
--- Zope/trunk/src/OFS/dtml/importExport.dtml	2010-02-15 05:35:58 UTC (rev 109071)
+++ Zope/trunk/src/OFS/dtml/importExport.dtml	2010-02-15 23:04:36 UTC (rev 109072)
@@ -10,16 +10,12 @@
 to download the export file to your local machine, or save it
 in the "var" directory of your Zope installation 
 on the server. 
-<!--
 <br/>
 <br/>
 <b>Note:</b>
-Zope can export/import objects in two dfferent formats: a binary format (called
+Zope can export/import objects in two different formats: a binary format (called
 ZEXP) and as XML. The ZEXP format is the officially supported export/import
 format for moving data between <u>identical</u> Zope installations (it is not a migration tool).
-The XML export/import is unsupported (and possibly broken under certain circumstances) - use it
-at your own risk.
--->
 </p>
 
 <form action="manage_exportObject" method="post">
@@ -54,7 +50,6 @@
   </div>
   </td>
 </tr>  
-<!--
 <tr>
   <td align="left" valign="top">
   &nbsp;
@@ -69,7 +64,6 @@
   </div>
   </td>
 </tr>
--->
 <tr>
   <td></td>
   <td align="left" valign="top">

Added: Zope/trunk/src/OFS/tests/export.xml
===================================================================
--- Zope/trunk/src/OFS/tests/export.xml	                        (rev 0)
+++ Zope/trunk/src/OFS/tests/export.xml	2010-02-15 23:04:36 UTC (rev 109072)
@@ -0,0 +1,344 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="482504664188191745" aka="BrIzb4doBAE=">
+    <pickle>
+      <tuple id="482504664188191745.2">
+          <global id="482504664188191745.1" name="Folder" module="OFS.Folder"/>
+          <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary id="482504664188191745.3">
+        <item>
+            <key><string id="482504664188191745.4" encoding="">_objects</string></key>
+            <value>
+              <tuple id="482504664188191745.10">
+                  <dictionary id="482504664188191745.5">
+                    <item>
+                        <key><string id="482504664188191745.6" encoding="">meta_type</string></key>
+                        <value><string id="482504664188191745.7" encoding="">Image</string></value>
+                    </item>
+                    <item>
+                        <key><string id="482504664188191745.8" encoding="">id</string></key>
+                        <value><string id="482504664188191745.9" encoding="">image</string></value>
+                    </item>
+                  </dictionary>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key><reference id="482504664188191745.9"/></key>
+            <value>
+              <persistent><string id="482504664188191745.11" encoding="base64">BrIzb4doBAI=</string></persistent>
+            </value>
+        </item>
+        <item>
+            <key><reference id="482504664188191745.8"/></key>
+            <value><string id="482504664188191745.12" encoding="">sub</string></value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="482504664188191746" aka="BrIzb4doBAI=">
+    <pickle>
+      <tuple id="482504664188191746.2">
+          <global id="482504664188191746.1" name="Image" module="OFS.Image"/>
+          <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary id="482504664188191746.3">
+        <item>
+            <key><string id="482504664188191746.4" encoding="">precondition</string></key>
+            <value><string encoding=""></string></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.5" encoding="">height</string></key>
+            <value><int>16</int></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.6" encoding="">size</string></key>
+            <value><int>894</int></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.7" encoding="">title</string></key>
+            <value><string encoding=""></string></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.8" encoding="">width</string></key>
+            <value><int>16</int></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.9" encoding="">_EtagSupport__etag</string></key>
+            <value><string id="482504664188191746.10" encoding="">ts65767150.22</string></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.11" encoding="">prop3</string></key>
+            <value><long>2147483647</long></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.12" encoding="">content_type</string></key>
+            <value><string id="482504664188191746.13" encoding="">image/gif</string></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.14" encoding="">__name__</string></key>
+            <value><string id="482504664188191746.15" encoding="">image</string></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.16" encoding="">data</string></key>
+            <value><string id="482504664188191746.17" encoding="base64">R0lGODlhEAAQAPcAAP8A/wAAAFBQUICAgMDAwP8AAIAAQAAAoABAgIAAgEAAQP//AP//gACAgECA
+gP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAA
+AAhbAAMIHEhwIICDAQ4qXIhQYUKFCCIufAiAYsSLDjMWiFjgoMSODkECAMmRIcWDBTYiYMjS40qT
+DFWKRHmyY8mRKStmXJhzp04AEllSfBgUZsOWPk+2HFqwaYCAAAA7</string></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.18" encoding="">prop12</string></key>
+            <value><unicode encoding="">£</unicode></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.19" encoding="">prop10</string></key>
+            <value><string id="482504664188191746.20" encoding="">&lt;]]&gt;</string></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.21" encoding="">prop11</string></key>
+            <value><unicode id="482504664188191746.22" encoding="">&lt;]]&gt;</unicode></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.23" encoding="">prop4</string></key>
+            <value><string id="482504664188191746.24" encoding="">xxx</string></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.25" encoding="">prop5</string></key>
+            <value>
+              <tuple id="482504664188191746.27">
+                  <reference id="482504664188191746.24"/>
+                  <string id="482504664188191746.26" encoding="">zzz</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.28" encoding="">prop6</string></key>
+            <value><unicode id="482504664188191746.29" encoding="">xxx</unicode></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.30" encoding="">prop7</string></key>
+            <value>
+              <tuple id="482504664188191746.32">
+                  <reference id="482504664188191746.29"/>
+                  <unicode id="482504664188191746.31" encoding="">zzz</unicode>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.33" encoding="">prop1</string></key>
+            <value><float>3.14159265359</float></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.34" encoding="">prop2</string></key>
+            <value><int>1</int></value>
+        </item>
+        <item>
+            <key><string id="482504664188191746.35" encoding="">_properties</string></key>
+            <value>
+              <tuple id="482504664188191746.66">
+                  <dictionary id="482504664188191746.36">
+                    <item>
+                        <key><string id="482504664188191746.37" encoding="">type</string></key>
+                        <value><string id="482504664188191746.38" encoding="">string</string></value>
+                    </item>
+                    <item>
+                        <key><string id="482504664188191746.39" encoding="">id</string></key>
+                        <value><reference id="482504664188191746.7"/></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.40">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><reference id="482504664188191746.38"/></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><string id="482504664188191746.41" encoding="">alt</string></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.42">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><reference id="482504664188191746.38"/></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.12"/></value>
+                    </item>
+                    <item>
+                        <key><string id="482504664188191746.43" encoding="">mode</string></key>
+                        <value><string encoding="">w</string></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.44">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><reference id="482504664188191746.38"/></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.5"/></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.45">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><reference id="482504664188191746.38"/></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.8"/></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.46">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><string id="482504664188191746.47" encoding="">float</string></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.33"/></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.48">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><string id="482504664188191746.49" encoding="">int</string></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.34"/></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.50">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><string id="482504664188191746.51" encoding="">long</string></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.11"/></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.52">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><reference id="482504664188191746.38"/></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.23"/></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.53">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><string id="482504664188191746.54" encoding="">lines</string></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.25"/></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.55">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><string id="482504664188191746.56" encoding="">unicode</string></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.28"/></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.57">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><string id="482504664188191746.58" encoding="">ulines</string></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.30"/></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.59">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><reference id="482504664188191746.38"/></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><string id="482504664188191746.60" encoding="">prop8</string></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.61">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><reference id="482504664188191746.56"/></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><string id="482504664188191746.62" encoding="">prop9</string></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.63">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><reference id="482504664188191746.38"/></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.19"/></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.64">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><reference id="482504664188191746.56"/></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.21"/></value>
+                    </item>
+                  </dictionary>
+                  <dictionary id="482504664188191746.65">
+                    <item>
+                        <key><reference id="482504664188191746.37"/></key>
+                        <value><reference id="482504664188191746.56"/></value>
+                    </item>
+                    <item>
+                        <key><reference id="482504664188191746.39"/></key>
+                        <value><reference id="482504664188191746.18"/></value>
+                    </item>
+                  </dictionary>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key><reference id="482504664188191746.60"/></key>
+            <value><string id="482504664188191746.67" encoding="cdata"><![CDATA[<&>]]></string></value>
+        </item>
+        <item>
+            <key><reference id="482504664188191746.62"/></key>
+            <value><unicode id="482504664188191746.68" encoding="cdata"><![CDATA[<&>]]></unicode></value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>

Modified: Zope/trunk/src/OFS/tests/test_XMLExportImport.py
===================================================================
--- Zope/trunk/src/OFS/tests/test_XMLExportImport.py	2010-02-15 05:35:58 UTC (rev 109071)
+++ Zope/trunk/src/OFS/tests/test_XMLExportImport.py	2010-02-15 23:04:36 UTC (rev 109072)
@@ -1,3 +1,4 @@
+# -*- coding: iso8859-1 -*-
 ##############################################################################
 #
 # Copyright (c) 2006 Zope Corporation and Contributors. All Rights Reserved.
@@ -16,8 +17,16 @@
 import transaction
 from StringIO import StringIO
 
-_LONG_DTML = '\n'.join([('<dtml-var foo%d' % x) for x in xrange(1000)])
+try:
+    here = os.path.dirname(os.path.abspath(__file__))
+except:
+    here = os.path.dirname(os.path.abspath(sys.argv[0]))
 
+imagedata = os.path.join(here, 'test.gif')
+xmldata = os.path.join(here, 'export.xml')
+
+_LONG_DTML = ''.join([('<dtml-var foo%d' % x) for x in xrange(1000)])
+
 class XMLExportImportTests(unittest.TestCase):
 
     def _makeJarAndRoot(self):
@@ -112,6 +121,75 @@
             # the block above.
             os.remove(path)
 
+    def test_exportXML(self):
+        from OFS.Folder import Folder
+        from OFS.Image import Image
+        from OFS.XMLExportImport import exportXML
+
+        connection, app = self._makeJarAndRoot()
+        data = open(imagedata, 'rb')
+
+        sub = Folder('sub')
+        app._setObject('sub', sub)
+        img = Image('image', '', data, 'image/gif')
+        sub._setObject('image', img)
+        img._setProperty('prop1', 3.14159265359, 'float')
+        img._setProperty('prop2', 1, 'int')
+        img._setProperty('prop3', 2L**31-1, 'long')
+        img._setProperty('prop4', 'xxx', 'string')
+        img._setProperty('prop5', ['xxx', 'zzz'], 'lines')
+        img._setProperty('prop6', u'xxx', 'unicode')
+        img._setProperty('prop7', [u'xxx', u'zzz'], 'ulines')
+        img._setProperty('prop8', '<&>', 'string')
+        img._setProperty('prop9', u'<&>', 'unicode')
+        img._setProperty('prop10', '<]]>', 'string')
+        img._setProperty('prop11', u'<]]>', 'unicode')
+        img._setProperty('prop12', u'£', 'unicode')
+        transaction.savepoint(optimistic=True)
+        oid = sub._p_oid
+
+        handle, path = tempfile.mkstemp(suffix='.xml')
+        try:
+            ostream = os.fdopen(handle,'wb')
+            data = exportXML(connection, oid, ostream)
+            ostream.close()
+        finally:
+            os.remove(path)
+
+    def test_importXML(self):
+        from OFS.XMLExportImport import importXML
+
+        connection, app = self._makeJarAndRoot()
+        newobj = importXML(connection, xmldata)
+        img = newobj._getOb('image')
+        data = open(imagedata, 'rb').read()
+
+        self.assertEqual(img.data, data)
+        self.assertEqual(repr(img.getProperty('prop1')),
+                         repr(3.14159265359))
+        self.assertEqual(repr(img.getProperty('prop2')),
+                         repr(1))
+        self.assertEqual(repr(img.getProperty('prop3')),
+                         repr(2L**31-1))
+        self.assertEqual(repr(img.getProperty('prop4')),
+                         repr('xxx'))
+        self.assertEqual(repr(img.getProperty('prop5')),
+                         repr(('xxx', 'zzz')))
+        self.assertEqual(repr(img.getProperty('prop6')),
+                         repr(u'xxx'))
+        self.assertEqual(repr(img.getProperty('prop7')),
+                         repr((u'xxx', u'zzz')))
+        self.assertEqual(repr(img.getProperty('prop8')),
+                         repr('<&>'))
+        self.assertEqual(repr(img.getProperty('prop9')),
+                         repr(u'<&>'))
+        self.assertEqual(repr(img.getProperty('prop10')),
+                         repr('<]]>'))
+        self.assertEqual(repr(img.getProperty('prop11')),
+                         repr(u'<]]>'))
+        self.assertEqual(repr(img.getProperty('prop12')),
+                         repr(u'£'))
+
 def test_suite():
     return unittest.TestSuite((
         unittest.makeSuite(XMLExportImportTests),

Modified: Zope/trunk/src/Shared/DC/xml/ppml.py
===================================================================
--- Zope/trunk/src/Shared/DC/xml/ppml.py	2010-02-15 05:35:58 UTC (rev 109071)
+++ Zope/trunk/src/Shared/DC/xml/ppml.py	2010-02-15 23:04:36 UTC (rev 109072)
@@ -17,119 +17,68 @@
 __version__ = "1.9"                     # Code version
 
 from pickle import *
-from string import replace
 import struct
 import base64
-import string
-import pickle
-import tempfile
-import marshal
-import xyap
+import re
+from marshal import loads as mloads
+from xyap import NoBlanks
+from xyap import xyap
 
-mdumps = marshal.dumps
-mloads = marshal.loads
+binary = re.compile('[^\x1f-\x7f]').search
 
-xyap=xyap.xyap
 
-ListType=type([])
-
-# Create repr mappong
-reprs = {}
-for c in map(chr,range(256)): reprs[c] = repr(c)[1:-1]
-reprs['\n'] = "\\n\n"
-reprs['\t'] = "\\t"
-reprs['\\'] = "\\\\"
-reprs['\r'] = "\\r"
-reprs["'"] = "\\'"
-reprs2={}
-reprs2['<'] = "\\074"
-reprs2['>'] = "\\076"
-reprs2['&'] = "\\046"
-
-
-#  Function convert takes a string and converts it to either
-#  repr or base64 format
-
-def convert(S, find=string.find):
-    new = ''
-    encoding = 'repr'
-    new = string.join(map(reprs.get, S), '')
-    if len(new) > (1.4*len(S)):
+def escape(s, encoding='repr'):
+    if binary(s) and isinstance(s, str):
+        s = base64.encodestring(s)[:-1]
         encoding = 'base64'
-        new = base64.encodestring(S)[:-1]
-    elif find(new,'>') >= 0 or find(new,'<') >= 0 or find(new,'&') >= 0:
-        if find(new, ']]>') <0 :
-            new='<![CDATA[\n\n'+new+'\n\n]]>'
-            encoding='cdata'
+    elif '>' in s or '<' in s or '&' in s:
+        if not ']]>' in s:
+            s = '<![CDATA[' + s + ']]>'
+            encoding = 'cdata'
         else:
-            new=string.join(map(lambda s: reprs2.get(s,s), new), '')
-    return encoding, new
+            s = s.replace('&', '&amp;')
+            s = s.replace('>', '&gt;')
+            s = s.replace('<', '&lt;')
+    return encoding, s
 
-#  Function unconvert takes a encoding and a string and
-#  returns the original string
-
-def unconvert(encoding,S):
-    original = ''
+def unescape(s, encoding):
     if encoding == 'base64':
-        original = base64.decodestring(S)
+        return base64.decodestring(s)
     else:
-        x = string.replace(S, '\n', '')
-        original = eval("'"+x+"'")
-    return original
+        s = s.replace('&lt;', '<')
+        s = s.replace('&gt;', '>')
+        return s.replace('&amp;', '&')
 
-t32 = 1L << 32
-
-def p64(v, pack=struct.pack):
-    if v < t32: h=0
-    else:
-        h=v/t32
-        v=v%t32
-    return pack(">II", h, v)
-
-def u64(v, unpack=struct.unpack):
-    h, v = unpack(">ii", v)
-    if v < 0: v=t32+v
-    if h:
-        if h < 0: h=t32+h
-        v=h*t32+v
-    return v
-
 class Global:
-
     def __init__(self, module, name):
-        self.module=module
-        self.name=name
+        self.module = module
+        self.name = name
 
     def __str__(self, indent=0):
-        if hasattr(self, 'id'): id=' id="%s"' % self.id
-        else: id=''
-        name=string.lower(self.__class__.__name__)
+        if hasattr(self, 'id'):
+            id = ' id="%s"' % self.id
+        else:
+            id = ''
+        name = self.__class__.__name__.lower()
         return '%s<%s%s name="%s" module="%s"/>\n' % (
-            ' '*indent, name, id, self.name, self.module)
+            ' ' * indent, name, id, self.name, self.module)
 
 class Scalar:
-
     def __init__(self, v):
-        self._v=v
+        self._v = v
 
-    def value(self): return self._v
+    def value(self):
+        return self._v
 
     def __str__(self, indent=0):
-        if hasattr(self, 'id'): id=' id="%s"' % self.id
-        else: id=''
-        name=string.lower(self.__class__.__name__)
+        if hasattr(self, 'id'):
+            id = ' id="%s"' % self.id
+        else:
+            id = ''
+        name = self.__class__.__name__.lower()
         return '%s<%s%s>%s</%s>\n' % (
-            ' '*indent, name, id, self.value(), name)
+            ' ' * indent, name, id, self.value(), name)
 
-def xmlstr(v):
-    v=`v`
-    if v[:1]=='\'':
-        v=string.replace(v,'"','\\"')
-    v=replace(v,'%','\\045')
-    v=replace(v,'&','\\046')
-    return v[1:-1]
-
-class Int(Scalar): pass
 class Long(Scalar):
     def value(self):
         result = str(self._v)
@@ -137,65 +86,84 @@
             return result[:-1]
         return result
 
-class Float(Scalar): pass
 class String(Scalar):
     def __init__(self, v, encoding=''):
-        encoding, v = convert(v)
-        self.encoding=encoding
-        self._v=v
-    def __str__(self,indent=0):
-        if hasattr(self,'id'):id=' id="%s"' % self.id
-        else: id=''
-        if hasattr(self, 'encoding'):encoding=' encoding="%s"' % self.encoding
-        else: encoding=''
-        name=string.lower(self.__class__.__name__)
+        encoding, v = escape(v, encoding)
+        self.encoding = encoding
+        self._v = v
+
+    def __str__(self, indent=0):
+        if hasattr(self,'id'):
+            id = ' id="%s"' % self.id
+        else:
+            id = ''
+        if hasattr(self, 'encoding'):
+            encoding = ' encoding="%s"' % self.encoding
+        else:
+            encoding = ''
+        name = self.__class__.__name__.lower()
         return '%s<%s%s%s>%s</%s>\n' % (
-            ' '*indent, name, id, encoding, self.value(), name)
+            ' ' * indent, name, id, encoding, self.value(), name)
 
-class Wrapper:
+class Unicode(String):
+    def __init__(self, v, encoding):
+        v = unicode(v, encoding)
+        String.__init__(self, v)
 
-    def __init__(self, v): self._v=v
+    def value(self):
+        return self._v.encode('utf-8')
 
-    def value(self): return self._v
+class Wrapper:
+    def __init__(self, v):
+        self._v = v
 
+    def value(self):
+        return self._v
+
     def __str__(self, indent=0):
-        if hasattr(self, 'id'): id=' id="%s"' % self.id
-        else: id=''
-        name=string.lower(self.__class__.__name__)
-        v=self._v
-        i=' '*indent
-        if isinstance(v,Scalar):
-            return '%s<%s%s> %s </%s>\n' % (i, name, id, str(v)[:-1], name)
+        if hasattr(self, 'id'):
+            id = ' id="%s"' % self.id
         else:
+            id = ''
+        name = self.__class__.__name__.lower()
+        v = self._v
+        i = ' ' * indent
+        if isinstance(v, Scalar):
+            return '%s<%s%s>%s</%s>\n' % (i, name, id, str(v)[:-1], name)
+        else:
             try:
-                v=v.__str__(indent+2)
+                v = v.__str__(indent + 2)
             except TypeError:
-                v=v.__str__()
+                v = v.__str__()
             return '%s<%s%s>\n%s%s</%s>\n' % (i, name, id, v, i, name)
 
 class Collection:
-
     def __str__(self, indent=0):
-        if hasattr(self, 'id'): id=' id="%s"' % self.id
-        else: id=''
-        name=string.lower(self.__class__.__name__)
-        i=' '*indent
+        if hasattr(self, 'id'):
+            id = ' id="%s"' % self.id
+        else:
+            id = ''
+        name = self.__class__.__name__.lower()
+        i = ' ' * indent
         if self:
             return '%s<%s%s>\n%s%s</%s>\n' % (
-                i, name, id, self.value(indent+2), i, name)
+                i, name, id, self.value(indent + 2), i, name)
         else:
             return '%s<%s%s/>\n' % (i, name, id)
 
-class Key(Wrapper): pass
-class Value(Wrapper): pass
-
 class Dictionary(Collection):
-    def __init__(self): self._d=[]
-    def __len__(self): return len(self._d)
-    def __setitem__(self, k, v): self._d.append((k,v))
+    def __init__(self):
+        self._d = []
+
+    def __len__(self):
+        return len(self._d)
+
+    def __setitem__(self, k, v):
+        self._d.append((k, v))
+
     def value(self, indent):
-        return string.join(
-            map(lambda i, ind=' '*indent, indent=indent+4:
+        return ''.join(
+            map(lambda i, ind=' ' * indent, indent=indent + 4:
                 '%s<item>\n'
                 '%s'
                 '%s'
@@ -206,62 +174,73 @@
                  Value(i[1]).__str__(indent),
                  ind),
                 self._d
-                ),
-            '')
+                ))
 
 class Sequence(Collection):
-
     def __init__(self, v=None):
-        if not v: v=[]
-        self._subs=v
+        if not v:
+            v = []
+        self._subs = v
 
-    def __len__(self): return len(self._subs)
+    def __len__(self):
+        return len(self._subs)
 
-    def append(self, v): self._subs.append(v)
-    def extend(self, v): self._subs.extend(v)
+    def append(self, v):
+        self._subs.append(v)
 
+    def extend(self, v):
+        self._subs.extend(v)
+
     def _stringify(self, v, indent):
         try:
-            return v.__str__(indent+2)
+            return v.__str__(indent + 2)
         except TypeError:
             return v.__str__()
 
     def value(self, indent):
-        return string.join(map(
+        return ''.join(map(
             lambda v, indent=indent: self._stringify(v, indent),
-            self._subs),'')
+            self._subs))
 
-class List(Sequence): pass
-class Tuple(Sequence): pass
-
-class Klass(Wrapper): pass
-class State(Wrapper): pass
-class Pickle(Wrapper): pass
-class Persistent(Wrapper): pass
-
 class none:
-    def __str__(self, indent=0): return ' '*indent+'<none/>\n'
-none=none()
+    def __str__(self, indent=0):
+        return ' ' * indent + '<none/>\n'
+none = none()
 
 class Reference(Scalar):
-    def __init__(self, v): self._v=v
+    def __init__(self, v):
+        self._v = v
+
     def __str__(self, indent=0):
-        v=self._v
-        name=string.lower(self.__class__.__name__)
-        return '%s<%s id="%s"/>\n' % (' '*indent,name,v)
+        v = self._v
+        name = self.__class__.__name__.lower()
+        return '%s<%s id="%s"/>\n' % (' ' * indent, name, v)
 
-Get=Reference
+Get = Reference
 
 class Object(Sequence):
     def __init__(self, klass, args):
-        self._subs=[Klass(klass), args]
+        self._subs = [Klass(klass), args]
 
-    def __setstate__(self, v): self.append(State(v))
+    def __setstate__(self, v):
+        self.append(State(v))
 
-class ToXMLUnpickler(Unpickler):
+class Int(Scalar): pass
+class Float(Scalar): pass
+class List(Sequence): pass
+class Tuple(Sequence): pass
+class Key(Wrapper): pass
+class Value(Wrapper): pass
+class Klass(Wrapper): pass
+class State(Wrapper): pass
+class Pickle(Wrapper): pass
+class Persistent(Wrapper): pass
 
-    def load(self): return Pickle(Unpickler.load(self))
 
+class ToXMLUnpickler(Unpickler):
+    def load(self):
+        return Pickle(Unpickler.load(self))
+
     dispatch = {}
     dispatch.update(Unpickler.dispatch)
 
@@ -278,7 +257,7 @@
     dispatch[NONE] = load_none
 
     def load_int(self):
-        self.append(Int(string.atoi(self.readline()[:-1])))
+        self.append(Int(int(self.readline()[:-1])))
     dispatch[INT] = load_int
 
     def load_binint(self):
@@ -286,7 +265,7 @@
     dispatch[BININT] = load_binint
 
     def load_binint1(self):
-        self.append(Int(mloads('i' + self.read(1) + '\000\000\000')))
+        self.append(Int(ord(self.read(1))))
     dispatch[BININT1] = load_binint1
 
     def load_binint2(self):
@@ -294,11 +273,11 @@
     dispatch[BININT2] = load_binint2
 
     def load_long(self):
-        self.append(Long(string.atol(self.readline()[:-1], 0)))
+        self.append(Long(long(self.readline()[:-1], 0)))
     dispatch[LONG] = load_long
 
     def load_float(self):
-        self.append(Float(string.atof(self.readline()[:-1])))
+        self.append(Float(float(self.readline()[:-1])))
     dispatch[FLOAT] = load_float
 
     def load_binfloat(self, unpack=struct.unpack):
@@ -306,8 +285,16 @@
     dispatch[BINFLOAT] = load_binfloat
 
     def load_string(self):
-        self.append(String(eval(self.readline()[:-1],
-                                {'__builtins__': {}}))) # Let's be careful
+        rep = self.readline()[:-1]
+        for q in "\"'":
+            if rep.startswith(q):
+                if not rep.endswith(q):
+                    raise ValueError, 'insecure string pickle'
+                rep = rep[len(q):-len(q)]
+                break
+        else:
+            raise ValueError, 'insecure string pickle'
+        self.append(String(rep.decode('string-escape')))
     dispatch[STRING] = load_string
 
     def load_binstring(self):
@@ -315,14 +302,23 @@
         self.append(String(self.read(len)))
     dispatch[BINSTRING] = load_binstring
 
+    def load_unicode(self):
+        self.append(Unicode(self.readline()[:-1],'raw-unicode-escape'))
+    dispatch[UNICODE] = load_unicode
+
+    def load_binunicode(self):
+        len = mloads('i' + self.read(4))
+        self.append(Unicode(self.read(len),'utf-8'))
+    dispatch[BINUNICODE] = load_binunicode
+
     def load_short_binstring(self):
-        len = mloads('i' + self.read(1) + '\000\000\000')
+        len = ord(self.read(1))
         self.append(String(self.read(len)))
     dispatch[SHORT_BINSTRING] = load_short_binstring
 
     def load_tuple(self):
         k = self.marker()
-        self.stack[k:] = [Tuple(self.stack[k+1:])]
+        self.stack[k:] = [Tuple(self.stack[k + 1:])]
     dispatch[TUPLE] = load_tuple
 
     def load_empty_tuple(self):
@@ -339,27 +335,27 @@
 
     def load_list(self):
         k = self.marker()
-        self.stack[k:] = [List(self.stack[k+1:])]
+        self.stack[k:] = [List(self.stack[k + 1:])]
     dispatch[LIST] = load_list
 
     def load_dict(self):
         k = self.marker()
         d = Dictionary()
-        items = self.stack[k+1:]
+        items = self.stack[k + 1:]
         for i in range(0, len(items), 2):
             key = items[i]
-            value = items[i+1]
+            value = items[i + 1]
             d[key] = value
         self.stack[k:] = [d]
     dispatch[DICT] = load_dict
 
     def load_inst(self):
         k = self.marker()
-        args = Tuple(self.stack[k+1:])
+        args = Tuple(self.stack[k + 1:])
         del self.stack[k:]
         module = self.readline()[:-1]
         name = self.readline()[:-1]
-        value=Object(Global(module, name), args)
+        value = Object(Global(module, name), args)
         self.append(value)
     dispatch[INST] = load_inst
 
@@ -370,7 +366,7 @@
         del stack[k + 1]
         args = Tuple(stack[k + 1:])
         del stack[k:]
-        value=Object(klass,args)
+        value = Object(klass, args)
         self.append(value)
     dispatch[OBJ] = load_obj
 
@@ -384,45 +380,45 @@
         stack = self.stack
 
         callable = stack[-2]
-        arg_tup  = stack[-1]
+        arg_tup = stack[-1]
         del stack[-2:]
 
-        value=Object(callable, arg_tup)
+        value = Object(callable, arg_tup)
         self.append(value)
     dispatch[REDUCE] = load_reduce
 
     idprefix=''
 
     def load_get(self):
-        self.append(Get(self.idprefix+self.readline()[:-1]))
+        self.append(Get(self.idprefix + self.readline()[:-1]))
     dispatch[GET] = load_get
 
     def load_binget(self):
-        i = mloads('i' + self.read(1) + '\000\000\000')
-        self.append(Get(self.idprefix+`i`))
+        i = ord(self.read(1))
+        self.append(Get(self.idprefix + repr(i)))
     dispatch[BINGET] = load_binget
 
     def load_long_binget(self):
         i = mloads('i' + self.read(4))
-        self.append(Get(self.idprefix+`i`))
+        self.append(Get(self.idprefix + repr(i)))
     dispatch[LONG_BINGET] = load_long_binget
 
     def load_put(self):
-        self.stack[-1].id=self.idprefix+self.readline()[:-1]
+        self.stack[-1].id = self.idprefix + self.readline()[:-1]
     dispatch[PUT] = load_put
 
     def load_binput(self):
-        i = mloads('i' + self.read(1) + '\000\000\000')
+        i = ord(self.read(1))
         last = self.stack[-1]
         if getattr(last, 'id', last) is last:
-            last.id = self.idprefix + `i`
+            last.id = self.idprefix + repr(i)
     dispatch[BINPUT] = load_binput
 
     def load_long_binput(self):
         i = mloads('i' + self.read(4))
         last = self.stack[-1]
         if getattr(last, 'id', last) is last:
-            last.id = self.idprefix + `i`
+            last.id = self.idprefix + repr(i)
     dispatch[LONG_BINPUT] = load_long_binput
 
 
@@ -430,230 +426,169 @@
     return ToXMLUnpickler(file).load()
 
 def ToXMLloads(str):
+    from StringIO import StringIO
     file = StringIO(str)
     return ToXMLUnpickler(file).load()
 
+def name(self, tag, data):
+    return ''.join(data[2:]).strip()
 
-
-class NoBlanks:
-
-    def handle_data(self, data):
-        if string.strip(data): self.append(data)
-
-def name(self, tag, data, join=string.join, strip=string.strip):
-    return strip(join(data[2:],''))
-
 def start_pickle(self, tag, attrs):
-    self._pickleids={}
-    return [tag,attrs]
+    self._pickleids = {}
+    return [tag, attrs]
 
-def end_string(self, tag, data):
-    v=data[2]
-    a=data[1]
-    if a['encoding'] is not '':
-        v=unconvert(a['encoding'],v)
-    if a.has_key('id'): self._pickleids[a['id']]=v
-    return v
-
-def end_list(self, tag, data):
-    v=data[2:]
-    a=data[1]
-    if a.has_key('id'): self._pickleids[data[1]['id']]=v
-    return v
-
-def end_tuple(self, tag, data):
-    v=tuple(data[2:])
-    a=data[1]
-    if a.has_key('id'): self._pickleids[data[1]['id']]=v
-    return v
-
-def end_dictionary(self, tag, data):
-    D={}
-    a=data[1]
-    for k, v in data[2:]: D[k]=v
-    if a.has_key('id'): self._pickleids[a['id']]=D
-    return D
-
-class xmlUnpickler(NoBlanks, xyap):
-    start_handlers={'pickle': start_pickle}
-    end_handlers={
-        'int':
-        lambda self,tag,data,atoi=string.atoi,name=name:
-            atoi(name(self, tag, data)),
-        'long':
-        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': end_string ,
-        '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)),
-        'none': lambda self, tag, data: None,
-        'list': end_list,
-        'tuple': end_tuple,
-        'dictionary': end_dictionary,
-        'key': lambda self, tag, data: data[2],
-        'value': lambda self, tag, data: data[2],
-        'item': lambda self, tag, data: data[2:],
-        'reference': lambda self, tag, data: self._pickleids[data[1]['id']],
-        'state': lambda self, tag, data: data[2],
-        'klass': lambda self, tag, data: data[2],
-        }
-
 def save_int(self, tag, data):
-    binary=self.binary
-    if binary:
-        v=string.atoi(name(self, tag, data))
-        i=mdumps(v)[1:]
-        if (i[-2:] == '\000\000'):
-            if (i[-3] == '\000'):
-                v='K'+i[:-3]
-                return v
-            v='M'+i[:-2]
-            return v
-        v='J'+i
-        return v
-    v='I'+name(self, tag, data)+'\012'
-    return v
+    if self.binary:
+        v = int(name(self, tag, data))
+        if v >= 0:
+            if v <= 0xff:
+                return BININT1 + chr(v)
+            if v <= 0xffff:
+                return '%c%c%c' % (BININT2, v & 0xff, v >> 8)
+        hb = v >> 31
+        if hb == 0 or hb == -1:
+            return BININT + struct.pack('<i', v)
+    return INT + name(self, tag, data) + '\n'
 
 def save_float(self, tag, data):
-    binary=self.binary
-    if binary: v='G'+struct.pack('>d',string.atof(name(self, tag, data)))
-    else: v='F'+name(self, tag, data)+'\012'
-    return v
+    if self.binary:
+        return BINFLOAT + struct.pack('>d', float(name(self, tag, data)))
+    else:
+        return FLOAT + name(self, tag, data) + '\n'
 
 def save_put(self, v, attrs):
-    id=attrs.get('id','')
+    id = attrs.get('id', '')
     if id:
-        prefix=string.rfind(id,'.')
-        if prefix >= 0: id=id[prefix+1:]
-        elif id[0]=='i': id=id[1:]
+        prefix = id.rfind('.')
+        if prefix >= 0:
+            id = id[prefix + 1:]
+        elif id[0] == 'i':
+            id = id[1:]
         if self.binary:
-            id=string.atoi(id)
-            s=mdumps(id)[1:]
-            if (id < 256):
-                id=s[0]
-                put='q'
+            id = int(id)
+            if id < 256:
+                id = BINPUT + chr(id)
             else:
-                id=s
-                put='r'
-            id=put+id
+                id = LONG_BINPUT + struct.pack('<i', id)
         else:
-            id="p"+id+"\012"
-        return v+id
+            id = PUT + repr(id) + '\n'
+        return v + id
     return v
 
 def save_string(self, tag, data):
-    binary=self.binary
-    v=''
-    a=data[1]
-    if len(data)>2:
-        for x in data[2:]:
-            v=v+x
-    encoding=a['encoding']
+    a = data[1]
+    v = ''.join(data[2:])
+    encoding = a['encoding']
     if encoding is not '':
-        v=unconvert(encoding,v)
-    put='p'
-    if binary:
-        l=len(v)
-        s=mdumps(l)[1:]
-        if (l<256):
-            v='U'+s[0]+v
+        v = unescape(v, encoding)
+    if self.binary:
+        l = len(v)
+        if l < 256:
+            v = SHORT_BINSTRING + chr(l) + v
         else:
-            v='T'+s+v
-        put='q'
-    else: v="S'"+v+"'\012"
+            v = BINSTRING + struct.pack('<i', l) + v
+    else:
+        v = STRING + repr(v) + '\n'
     return save_put(self, v, a)
 
+def save_unicode(self, tag, data):
+    a = data[1]
+    v = ''.join(data[2:])
+    encoding = a['encoding']
+    if encoding is not '':
+        v = unescape(v, encoding)
+    if self.binary:
+        v = v.encode('utf-8')
+        v = BINUNICODE + struct.pack("<i", len(v)) + v
+    else:
+        v = v.replace("\\", "\\u005c")
+        v = v.replace("\n", "\\u000a")
+        v.encode('raw-unicode-escape')
+        v = UNICODE + v + '\n'
+    return save_put(self, v, a)
+
 def save_tuple(self, tag, data):
-    T=data[2:]
-    if not T: return ')'
-    return save_put(self, '('+string.join(T,'')+'t', data[1])
+    T = data[2:]
+    if not T:
+        return EMPTY_TUPLE
+    return save_put(self, MARK + ''.join(T) + TUPLE, data[1])
 
 def save_list(self, tag, data):
-    L=data[2:]
-    a=data[1]
+    L = data[2:]
     if self.binary:
-        v=save_put(self, ']', a)
-        if L: v=v+'('+string.join(L,'')+'e'
+        v = save_put(self, EMPTY_LIST, data[1])
+        if L:
+            v = v + MARK + ''.join(L) + APPENDS
     else:
-        v=save_put(self, '(l', a)
-        if L: v=string.join(L,'a')+'a'
+        v = save_put(self, MARK + LIST, data[1])
+        if L:
+            v = APPEND.join(L) + APPEND
     return v
 
 def save_dict(self, tag, data):
-    D=data[2:]
+    D = data[2:]
     if self.binary:
-        v=save_put(self, '}', data[1])
-        if D: v=v+'('+string.join(D,'')+'u'
+        v = save_put(self, EMPTY_DICT, data[1])
+        if D:
+            v = v + MARK + ''.join(D) + SETITEMS
     else:
-        v=save_put(self, '(d', data[1])
-        if D: v=v+string.join(D,'s')+'s'
+        v = save_put(self, MARK + DICT, data[1])
+        if D:
+            v = v + SETITEM.join(D) + SETITEM
     return v
 
 def save_reference(self, tag, data):
-    binary=self.binary
-    a=data[1]
-    id=a['id']
-    prefix=string.rfind(id,'.')
-    if prefix>=0: id=id[prefix+1:]
-    get='g'
-    if binary:
-        id=string.atoi(id)
-        s=mdumps(id)[1:]
-        if (id < 256):
-            id=s[0]
-            get='h'
+    a = data[1]
+    id = a['id']
+    prefix = id.rfind('.')
+    if prefix >= 0:
+        id = id[prefix + 1:]
+    if self.binary:
+        id = int(id)
+        if id < 256:
+            return BINGET + chr(id)
         else:
-            id=s
-            get='j'
-        v=get+id
-    else: v=get+id+'\012'
+            return LONG_BINGET + struct.pack('<i', i)
+    else:
+        return GET + repr(id) + '\n'
 
-    return v
-
 def save_object(self, tag, data):
-    v='('+data[2]
-    x=data[3][1:]
-    stop=string.rfind(x,'t')  # This seems
-    if stop>=0: x=x[:stop]    # wrong!
-    v=save_put(self, v+x+'o', data[1])
-    v=v+data[4]+'b' # state
+    v = MARK + data[2]
+    x = data[3][1:]
+    stop = x.rfind('t')  # This seems
+    if stop >= 0:        # wrong!
+        x = x[:stop]
+    v = save_put(self, v + x + OBJ, data[1])
+    v = v + data[4] + BUILD # state
     return v
 
 def save_global(self, tag, data):
-    a=data[1]
-    return save_put(self, 'c'+a['module']+'\012'+a['name']+'\012', a)
+    a = data[1]
+    return save_put(self, GLOBAL + a['module'] + '\n' + a['name'] + '\n', a)
 
 def save_persis(self, tag, data):
-    v=data[2]
-    if  self.binary:
-        v=v+'Q'
+    v = data[2]
+    if self.binary:
+        return v + BINPERSID
     else:
-        v='P'+v
-    return v
+        return PERSID + v
 
 class xmlPickler(NoBlanks, xyap):
-    start_handlers={
+    start_handlers = {
         'pickle': lambda self, tag, attrs: [tag, attrs],
         }
-    end_handlers={
-        'pickle': lambda self, tag, data: str(data[2])+'.',
-        'none': lambda self, tag, data: 'N',
+    end_handlers = {
+        'pickle': lambda self, tag, data: str(data[2]) + STOP,
+        'none': lambda self, tag, data: NONE,
         'int': save_int,
-        'long': lambda self, tag, data: 'L'+str(data[2])+'L\012',
+        'long': lambda self, tag, data: LONG + str(data[2]) + LONG + '\n',
         'float': save_float,
         'string': save_string,
         'reference': save_reference,
         'tuple': save_tuple,
         'list': save_list,
         'dictionary': save_dict,
-        'item': lambda self, tag, data, j=string.join: j(data[2:],''),
+        'item': lambda self, tag, data: ''.join(map(str, data[2:])),
         'value': lambda self, tag, data: data[2],
         'key' : lambda self, tag, data: data[2],
         'object': save_object,
@@ -661,6 +596,7 @@
         'state': lambda self, tag, data: data[2],
         'global': save_global,
         'persistent': save_persis,
+        'unicode': save_unicode,
         }
 
 
@@ -672,16 +608,17 @@
 
 def test():
     import xmllib
-    c=C()
-    c.foo=1
-    c.bar=2
-    x=[0,1,2,3]
-    y=('abc','abc',c,c)
+    import pickle
+    c = C()
+    c.foo = 1
+    c.bar = 2
+    x = [0, 1, 2, 3]
+    y = ('abc', 'abc', c, c)
     x.append(y)
     x.append(y)
-    t=()
-    l=[]
-    s=''
+    t = ()
+    l = []
+    s = ''
     L = long('999999999999')
     x.append(t)
     x.append(l)
@@ -689,78 +626,52 @@
     x.append(L)
     x.append(55555)
     x.append(13)
-    r=[x]
+    r = [x]
     print x
-    f=pickle.dumps(x)
+    f = pickle.dumps(x)
     print f
     r.append(f)
-    q=ToXMLloads(f)
-    q=str(q)
-    q='<?xml version="1.0"?>\n'+q
+    q = ToXMLloads(f)
+    q = str(q)
+    q = '<?xml version="1.0"?>\n' + q
     print q
     r.append(q)
-    file=''
-    F=xmlPickler(file)
-    p=xmllib.XMLParser()
-    p.start_handlers=F.start_handlers
-    p.end_handlers=F.end_handlers
-    p.handle_data=F.handle_data
-    p.unknown_starttag=F.unknown_starttag
-    p.unknown_endtag=F.unknown_endtag
-    p._stack=F._stack
-    p.push=F.push
-    p.append=F.append
-    p.file=F.file
-    p.tempfile=F.tempfile
-    p.binary=1
-    data=string.split(q,'\n')
+    F = xmlPickler()
+    F.binary = 1
+    p = xmllib.XMLParser()
+    p.start_handlers = F.start_handlers
+    p.end_handlers = F.end_handlers
+    p.handle_data = F.handle_data
+    p.unknown_starttag = F.unknown_starttag
+    p.unknown_endtag = F.unknown_endtag
+    p._stack = F._stack
+    p.push = F.push
+    p.append = F.append
+    data = q.split('\n')
     for l in data:
         p.feed(l)
     p.close()
-    z=p._stack
-    z=z[0][0]
-    print z, '\012'
+    z = p._stack
+    z = z[0][0]
+    print z, '\n'
     r.append(z)
-    l=pickle.loads(z)
-    print l, '\012'
+    l = pickle.loads(z)
+    print l, '\n'
     r.append(l)
 
 def test1():
-    import xmllib
-    q=open('Data.xml').read()
-    file=open('out','w'+'b')
-    F=xmlPickler(file,1)
-    p=xmllib.XMLParser()
-    p.start_handlers=F.start_handlers
-    p.end_handlers=F.end_handlers
-    p.handle_data=F.handle_data
-    p.unknown_starttag=F.unknown_starttag
-    p.unknown_endtag=F.unknown_endtag
-    p._stack=F._stack
-    p.push=F.push
-    p.append=F.append
-    p.file=F.file
-    p.tempfile=F.tempfile
-    data=string.split(q,'\n')
-    for l in data:
-        p.feed(l)
-    p.close()
-    z=p._stack
-    z=z[0][0]
-    print z, '\012'
-
-def test2():
     import xml.parsers.expat
-    c=C()
-    c.foo=1
-    c.bar=2
-    x=[0,1,2,3]
-    y=('abc','abc',c,c)
+    import pickle
+    c = C()
+    c.foo = 1
+    c.bar = 2
+    x = [0, 1, 2, 3]
+    y = ('abc', 'abc', c, c)
     x.append(y)
     x.append(y)
-    t=()
-    l=[]
-    s=''
+    t = ()
+    l = []
+    s = ''
     L = long('999999999999')
     x.append(t)
     x.append(l)
@@ -768,36 +679,21 @@
     x.append(L)
     x.append(5)
     x.append(13)
-    print x, '\012'
-    f=pickle.dumps(x)
-    print f, '\012'
-    q=ToXMLloads(f)
-    q=str(q)
-    q='<?xml version="1.0"?>\n'+q
-    print q, '\012'
-    file=''
-    F=xmlPickler()
-    F.binary=0
-    p=xml.parsers.expat.ParserCreate()
-    p.CharacterDataHandler=F.handle_data
-    p.StartElementHandler=F.unknown_starttag
-    p.EndElementHandler=F.unknown_endtag
-    r=p.Parse(q)
-    print r, '\012'
+    print x, '\n'
+    f = pickle.dumps(x)
+    print f, '\n'
+    q = ToXMLloads(f)
+    q = str(q)
+    q = '<?xml version="1.0"?>\n' + q
+    print q, '\n'
+    F = xmlPickler()
+    F.binary = 0
+    p = xml.parsers.expat.ParserCreate()
+    p.CharacterDataHandler = F.handle_data
+    p.StartElementHandler = F.unknown_starttag
+    p.EndElementHandler = F.unknown_endtag
+    r = p.Parse(q)
+    print r, '\n'
 
-def test3():
-    import xml.parsers.expat
-    data=open('Data.xml').read()
-    file=open('out','w'+'b')
-    F=xmlPickler()
-    F.file=file
-    F.binary=1
-    p=xml.parsers.expat.ParserCreate()
-    p.CharacterDataHandler=F.handle_data
-    p.StartElementHandler=F.unknown_starttag
-    p.EndElementHandler=F.unknown_endtag
-    r=p.Parse(data)
-    print r, '\012'
-
 if __name__ == '__main__':
     test()



More information about the Zope-Checkins mailing list