Commit 082807aa authored by Tres Seaver's avatar Tres Seaver

LP #195761: fixed ZMI XML export / import and restored it to the UI.

parents 3bc19628 62b5578e
...@@ -4,6 +4,12 @@ Zope Changes ...@@ -4,6 +4,12 @@ Zope Changes
Change information for previous versions of Zope can be found in the Change information for previous versions of Zope can be found in the
file HISTORY.txt. file HISTORY.txt.
Zope 2.10.12 (unreleased)
Bugs fixed
- LP #195761: fixed ZMI XML export / import and restored it to the UI.
Zope 2.10.11 (2010/01/12) Zope 2.10.11 (2010/01/12)
Bugs fixed Bugs fixed
......
...@@ -14,6 +14,8 @@ from base64 import encodestring ...@@ -14,6 +14,8 @@ from base64 import encodestring
from cStringIO import StringIO from cStringIO import StringIO
from ZODB.serialize import referencesf from ZODB.serialize import referencesf
from ZODB.ExportImport import TemporaryFile, export_end_marker from ZODB.ExportImport import TemporaryFile, export_end_marker
from ZODB.utils import p64
from ZODB.utils import u64
from Shared.DC.xml import ppml from Shared.DC.xml import ppml
...@@ -23,7 +25,7 @@ def XMLrecord(oid, len, p): ...@@ -23,7 +25,7 @@ def XMLrecord(oid, len, p):
q=ppml.ToXMLUnpickler q=ppml.ToXMLUnpickler
f=StringIO(p) f=StringIO(p)
u=q(f) u=q(f)
id=ppml.u64(oid) id=u64(oid)
aka=encodestring(oid)[:-1] aka=encodestring(oid)[:-1]
u.idprefix=str(id)+'.' u.idprefix=str(id)+'.'
p=u.load().__str__(4) p=u.load().__str__(4)
...@@ -87,11 +89,11 @@ def save_record(parser, tag, data): ...@@ -87,11 +89,11 @@ def save_record(parser, tag, data):
file.seek(pos) file.seek(pos)
a=data[1] a=data[1]
if a.has_key('id'): oid=a['id'] if a.has_key('id'): oid=a['id']
oid=ppml.p64(int(oid)) oid=p64(int(oid))
v='' v=''
for x in data[2:]: for x in data[2:]:
v=v+x v=v+x
l=ppml.p64(len(v)) l=p64(len(v))
v=oid+l+v v=oid+l+v
return v return v
......
...@@ -13,11 +13,9 @@ on the server. ...@@ -13,11 +13,9 @@ on the server.
<br/> <br/>
<br/> <br/>
<b>Note:</b> <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 ZEXP) and as XML. The ZEXP format is the officially supported export/import
format for moving data between <u>identicial</u> Zope installations (it is not a migration tool). format for moving data between <u>identicial</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> </p>
<form action="manage_exportObject" method="post"> <form action="manage_exportObject" method="post">
......
<?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>
# -*- coding: iso8859-1 -*-
############################################################################## ##############################################################################
# #
# Copyright (c) 2006 Zope Corporation and Contributors. All Rights Reserved. # Copyright (c) 2006 Zope Corporation and Contributors. All Rights Reserved.
...@@ -16,7 +17,15 @@ import tempfile ...@@ -16,7 +17,15 @@ import tempfile
import transaction import transaction
from StringIO import StringIO 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): class XMLExportImportTests(unittest.TestCase):
...@@ -112,6 +121,75 @@ class XMLExportImportTests(unittest.TestCase): ...@@ -112,6 +121,75 @@ class XMLExportImportTests(unittest.TestCase):
# the block above. # the block above.
os.remove(path) 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(): def test_suite():
return unittest.TestSuite(( return unittest.TestSuite((
unittest.makeSuite(XMLExportImportTests), unittest.makeSuite(XMLExportImportTests),
......
...@@ -17,119 +17,68 @@ ...@@ -17,119 +17,68 @@
__version__ = "1.9" # Code version __version__ = "1.9" # Code version
from pickle import * from pickle import *
from string import replace
import struct import struct
import base64 import base64
import string import re
import pickle from marshal import loads as mloads
import tempfile from xyap import NoBlanks
import marshal from xyap import xyap
import xyap
binary = re.compile('[^\x1f-\x7f]').search
mdumps = marshal.dumps
mloads = marshal.loads
def escape(s, encoding='repr'):
xyap=xyap.xyap if binary(s) and isinstance(s, str):
s = base64.encodestring(s)[:-1]
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)):
encoding = 'base64' encoding = 'base64'
new = base64.encodestring(S)[:-1] elif '>' in s or '<' in s or '&' in s:
elif find(new,'>') >= 0 or find(new,'<') >= 0 or find(new,'&') >= 0: if not ']]>' in s:
if find(new, ']]>') <0 : s = '<![CDATA[' + s + ']]>'
new='<![CDATA[\n\n'+new+'\n\n]]>' encoding = 'cdata'
encoding='cdata'
else: else:
new=string.join(map(lambda s: reprs2.get(s,s), new), '') s = s.replace('&', '&amp;')
return encoding, new s = s.replace('>', '&gt;')
s = s.replace('<', '&lt;')
# Function unconvert takes a encoding and a string and return encoding, s
# returns the original string
def unconvert(encoding,S): def unescape(s, encoding):
original = ''
if encoding == 'base64': if encoding == 'base64':
original = base64.decodestring(S) return base64.decodestring(s)
else: else:
x = string.replace(S, '\n', '') s = s.replace('&lt;', '<')
original = eval("'"+x+"'") s = s.replace('&gt;', '>')
return original 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: class Global:
def __init__(self, module, name): def __init__(self, module, name):
self.module=module self.module = module
self.name=name self.name = name
def __str__(self, indent=0): def __str__(self, indent=0):
if hasattr(self, 'id'): id=' id="%s"' % self.id if hasattr(self, 'id'):
else: id='' id = ' id="%s"' % self.id
name=string.lower(self.__class__.__name__) else:
id = ''
name = self.__class__.__name__.lower()
return '%s<%s%s name="%s" module="%s"/>\n' % ( 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: class Scalar:
def __init__(self, v): 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): def __str__(self, indent=0):
if hasattr(self, 'id'): id=' id="%s"' % self.id if hasattr(self, 'id'):
else: id='' id = ' id="%s"' % self.id
name=string.lower(self.__class__.__name__) else:
id = ''
name = self.__class__.__name__.lower()
return '%s<%s%s>%s</%s>\n' % ( 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): class Long(Scalar):
def value(self): def value(self):
result = str(self._v) result = str(self._v)
...@@ -137,65 +86,84 @@ class Long(Scalar): ...@@ -137,65 +86,84 @@ class Long(Scalar):
return result[:-1] return result[:-1]
return result return result
class Float(Scalar): pass
class String(Scalar): class String(Scalar):
def __init__(self, v, encoding=''): def __init__(self, v, encoding=''):
encoding, v = convert(v) encoding, v = escape(v, encoding)
self.encoding=encoding self.encoding = encoding
self._v=v self._v = v
def __str__(self,indent=0):
if hasattr(self,'id'):id=' id="%s"' % self.id def __str__(self, indent=0):
else: id='' if hasattr(self,'id'):
if hasattr(self, 'encoding'):encoding=' encoding="%s"' % self.encoding id = ' id="%s"' % self.id
else: encoding='' else:
name=string.lower(self.__class__.__name__) 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' % ( 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 value(self):
return self._v.encode('utf-8')
def __init__(self, v): self._v=v class Wrapper:
def __init__(self, v):
self._v = v
def value(self): return self._v def value(self):
return self._v
def __str__(self, indent=0): def __str__(self, indent=0):
if hasattr(self, 'id'): id=' id="%s"' % self.id if hasattr(self, 'id'):
else: id='' id = ' id="%s"' % self.id
name=string.lower(self.__class__.__name__) else:
v=self._v id = ''
i=' '*indent name = self.__class__.__name__.lower()
if isinstance(v,Scalar): v = self._v
return '%s<%s%s> %s </%s>\n' % (i, name, id, str(v)[:-1], name) i = ' ' * indent
if isinstance(v, Scalar):
return '%s<%s%s>%s</%s>\n' % (i, name, id, str(v)[:-1], name)
else: else:
try: try:
v=v.__str__(indent+2) v = v.__str__(indent + 2)
except TypeError: except TypeError:
v=v.__str__() v = v.__str__()
return '%s<%s%s>\n%s%s</%s>\n' % (i, name, id, v, i, name) return '%s<%s%s>\n%s%s</%s>\n' % (i, name, id, v, i, name)
class Collection: class Collection:
def __str__(self, indent=0): def __str__(self, indent=0):
if hasattr(self, 'id'): id=' id="%s"' % self.id if hasattr(self, 'id'):
else: id='' id = ' id="%s"' % self.id
name=string.lower(self.__class__.__name__) else:
i=' '*indent id = ''
name = self.__class__.__name__.lower()
i = ' ' * indent
if self: if self:
return '%s<%s%s>\n%s%s</%s>\n' % ( 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: else:
return '%s<%s%s/>\n' % (i, name, id) return '%s<%s%s/>\n' % (i, name, id)
class Key(Wrapper): pass
class Value(Wrapper): pass
class Dictionary(Collection): class Dictionary(Collection):
def __init__(self): self._d=[] def __init__(self):
def __len__(self): return len(self._d) self._d = []
def __setitem__(self, k, v): self._d.append((k,v))
def __len__(self):
return len(self._d)
def __setitem__(self, k, v):
self._d.append((k, v))
def value(self, indent): def value(self, indent):
return string.join( return ''.join(
map(lambda i, ind=' '*indent, indent=indent+4: map(lambda i, ind=' ' * indent, indent=indent + 4:
'%s<item>\n' '%s<item>\n'
'%s' '%s'
'%s' '%s'
...@@ -206,61 +174,72 @@ class Dictionary(Collection): ...@@ -206,61 +174,72 @@ class Dictionary(Collection):
Value(i[1]).__str__(indent), Value(i[1]).__str__(indent),
ind), ind),
self._d self._d
), ))
'')
class Sequence(Collection): class Sequence(Collection):
def __init__(self, v=None): def __init__(self, v=None):
if not v: v=[] if not v:
self._subs=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 append(self, v):
def extend(self, v): self._subs.extend(v) self._subs.append(v)
def extend(self, v):
self._subs.extend(v)
def _stringify(self, v, indent): def _stringify(self, v, indent):
try: try:
return v.__str__(indent+2) return v.__str__(indent + 2)
except TypeError: except TypeError:
return v.__str__() return v.__str__()
def value(self, indent): def value(self, indent):
return string.join(map( return ''.join(map(
lambda v, indent=indent: self._stringify(v, indent), 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: class none:
def __str__(self, indent=0): return ' '*indent+'<none/>\n' def __str__(self, indent=0):
none=none() return ' ' * indent + '<none/>\n'
none = none()
class Reference(Scalar): class Reference(Scalar):
def __init__(self, v): self._v=v def __init__(self, v):
self._v = v
def __str__(self, indent=0): def __str__(self, indent=0):
v=self._v v = self._v
name=string.lower(self.__class__.__name__) name = self.__class__.__name__.lower()
return '%s<%s id="%s"/>\n' % (' '*indent,name,v) return '%s<%s id="%s"/>\n' % (' ' * indent, name, v)
Get=Reference Get = Reference
class Object(Sequence): class Object(Sequence):
def __init__(self, klass, args): 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 = {}
dispatch.update(Unpickler.dispatch) dispatch.update(Unpickler.dispatch)
...@@ -278,7 +257,7 @@ class ToXMLUnpickler(Unpickler): ...@@ -278,7 +257,7 @@ class ToXMLUnpickler(Unpickler):
dispatch[NONE] = load_none dispatch[NONE] = load_none
def load_int(self): def load_int(self):
self.append(Int(string.atoi(self.readline()[:-1]))) self.append(Int(int(self.readline()[:-1])))
dispatch[INT] = load_int dispatch[INT] = load_int
def load_binint(self): def load_binint(self):
...@@ -286,7 +265,7 @@ class ToXMLUnpickler(Unpickler): ...@@ -286,7 +265,7 @@ class ToXMLUnpickler(Unpickler):
dispatch[BININT] = load_binint dispatch[BININT] = load_binint
def load_binint1(self): 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 dispatch[BININT1] = load_binint1
def load_binint2(self): def load_binint2(self):
...@@ -294,11 +273,11 @@ class ToXMLUnpickler(Unpickler): ...@@ -294,11 +273,11 @@ class ToXMLUnpickler(Unpickler):
dispatch[BININT2] = load_binint2 dispatch[BININT2] = load_binint2
def load_long(self): 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 dispatch[LONG] = load_long
def load_float(self): def load_float(self):
self.append(Float(string.atof(self.readline()[:-1]))) self.append(Float(float(self.readline()[:-1])))
dispatch[FLOAT] = load_float dispatch[FLOAT] = load_float
def load_binfloat(self, unpack=struct.unpack): def load_binfloat(self, unpack=struct.unpack):
...@@ -306,8 +285,16 @@ class ToXMLUnpickler(Unpickler): ...@@ -306,8 +285,16 @@ class ToXMLUnpickler(Unpickler):
dispatch[BINFLOAT] = load_binfloat dispatch[BINFLOAT] = load_binfloat
def load_string(self): def load_string(self):
self.append(String(eval(self.readline()[:-1], rep = self.readline()[:-1]
{'__builtins__': {}}))) # Let's be careful 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 dispatch[STRING] = load_string
def load_binstring(self): def load_binstring(self):
...@@ -315,14 +302,23 @@ class ToXMLUnpickler(Unpickler): ...@@ -315,14 +302,23 @@ class ToXMLUnpickler(Unpickler):
self.append(String(self.read(len))) self.append(String(self.read(len)))
dispatch[BINSTRING] = load_binstring 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): 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))) self.append(String(self.read(len)))
dispatch[SHORT_BINSTRING] = load_short_binstring dispatch[SHORT_BINSTRING] = load_short_binstring
def load_tuple(self): def load_tuple(self):
k = self.marker() k = self.marker()
self.stack[k:] = [Tuple(self.stack[k+1:])] self.stack[k:] = [Tuple(self.stack[k + 1:])]
dispatch[TUPLE] = load_tuple dispatch[TUPLE] = load_tuple
def load_empty_tuple(self): def load_empty_tuple(self):
...@@ -339,27 +335,27 @@ class ToXMLUnpickler(Unpickler): ...@@ -339,27 +335,27 @@ class ToXMLUnpickler(Unpickler):
def load_list(self): def load_list(self):
k = self.marker() k = self.marker()
self.stack[k:] = [List(self.stack[k+1:])] self.stack[k:] = [List(self.stack[k + 1:])]
dispatch[LIST] = load_list dispatch[LIST] = load_list
def load_dict(self): def load_dict(self):
k = self.marker() k = self.marker()
d = Dictionary() d = Dictionary()
items = self.stack[k+1:] items = self.stack[k + 1:]
for i in range(0, len(items), 2): for i in range(0, len(items), 2):
key = items[i] key = items[i]
value = items[i+1] value = items[i + 1]
d[key] = value d[key] = value
self.stack[k:] = [d] self.stack[k:] = [d]
dispatch[DICT] = load_dict dispatch[DICT] = load_dict
def load_inst(self): def load_inst(self):
k = self.marker() k = self.marker()
args = Tuple(self.stack[k+1:]) args = Tuple(self.stack[k + 1:])
del self.stack[k:] del self.stack[k:]
module = self.readline()[:-1] module = self.readline()[:-1]
name = self.readline()[:-1] name = self.readline()[:-1]
value=Object(Global(module, name), args) value = Object(Global(module, name), args)
self.append(value) self.append(value)
dispatch[INST] = load_inst dispatch[INST] = load_inst
...@@ -370,7 +366,7 @@ class ToXMLUnpickler(Unpickler): ...@@ -370,7 +366,7 @@ class ToXMLUnpickler(Unpickler):
del stack[k + 1] del stack[k + 1]
args = Tuple(stack[k + 1:]) args = Tuple(stack[k + 1:])
del stack[k:] del stack[k:]
value=Object(klass,args) value = Object(klass, args)
self.append(value) self.append(value)
dispatch[OBJ] = load_obj dispatch[OBJ] = load_obj
...@@ -384,45 +380,45 @@ class ToXMLUnpickler(Unpickler): ...@@ -384,45 +380,45 @@ class ToXMLUnpickler(Unpickler):
stack = self.stack stack = self.stack
callable = stack[-2] callable = stack[-2]
arg_tup = stack[-1] arg_tup = stack[-1]
del stack[-2:] del stack[-2:]
value=Object(callable, arg_tup) value = Object(callable, arg_tup)
self.append(value) self.append(value)
dispatch[REDUCE] = load_reduce dispatch[REDUCE] = load_reduce
idprefix='' idprefix=''
def load_get(self): def load_get(self):
self.append(Get(self.idprefix+self.readline()[:-1])) self.append(Get(self.idprefix + self.readline()[:-1]))
dispatch[GET] = load_get dispatch[GET] = load_get
def load_binget(self): def load_binget(self):
i = mloads('i' + self.read(1) + '\000\000\000') i = ord(self.read(1))
self.append(Get(self.idprefix+`i`)) self.append(Get(self.idprefix + repr(i)))
dispatch[BINGET] = load_binget dispatch[BINGET] = load_binget
def load_long_binget(self): def load_long_binget(self):
i = mloads('i' + self.read(4)) 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 dispatch[LONG_BINGET] = load_long_binget
def load_put(self): 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 dispatch[PUT] = load_put
def load_binput(self): def load_binput(self):
i = mloads('i' + self.read(1) + '\000\000\000') i = ord(self.read(1))
last = self.stack[-1] last = self.stack[-1]
if getattr(last, 'id', last) is last: if getattr(last, 'id', last) is last:
last.id = self.idprefix + `i` last.id = self.idprefix + repr(i)
dispatch[BINPUT] = load_binput dispatch[BINPUT] = load_binput
def load_long_binput(self): def load_long_binput(self):
i = mloads('i' + self.read(4)) i = mloads('i' + self.read(4))
last = self.stack[-1] last = self.stack[-1]
if getattr(last, 'id', last) is last: if getattr(last, 'id', last) is last:
last.id = self.idprefix + `i` last.id = self.idprefix + repr(i)
dispatch[LONG_BINPUT] = load_long_binput dispatch[LONG_BINPUT] = load_long_binput
...@@ -430,230 +426,169 @@ def ToXMLload(file): ...@@ -430,230 +426,169 @@ def ToXMLload(file):
return ToXMLUnpickler(file).load() return ToXMLUnpickler(file).load()
def ToXMLloads(str): def ToXMLloads(str):
from StringIO import StringIO
file = StringIO(str) file = StringIO(str)
return ToXMLUnpickler(file).load() 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): def start_pickle(self, tag, attrs):
self._pickleids={} self._pickleids = {}
return [tag,attrs] 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): def save_int(self, tag, data):
binary=self.binary if self.binary:
if binary: v = int(name(self, tag, data))
v=string.atoi(name(self, tag, data)) if v >= 0:
i=mdumps(v)[1:] if v <= 0xff:
if (i[-2:] == '\000\000'): return BININT1 + chr(v)
if (i[-3] == '\000'): if v <= 0xffff:
v='K'+i[:-3] return '%c%c%c' % (BININT2, v & 0xff, v >> 8)
return v hb = v >> 31
v='M'+i[:-2] if hb == 0 or hb == -1:
return v return BININT + struct.pack('<i', v)
v='J'+i return INT + name(self, tag, data) + '\n'
return v
v='I'+name(self, tag, data)+'\012'
return v
def save_float(self, tag, data): def save_float(self, tag, data):
binary=self.binary if self.binary:
if binary: v='G'+struct.pack('>d',string.atof(name(self, tag, data))) return BINFLOAT + struct.pack('>d', float(name(self, tag, data)))
else: v='F'+name(self, tag, data)+'\012' else:
return v return FLOAT + name(self, tag, data) + '\n'
def save_put(self, v, attrs): def save_put(self, v, attrs):
id=attrs.get('id','') id = attrs.get('id', '')
if id: if id:
prefix=string.rfind(id,'.') prefix = id.rfind('.')
if prefix >= 0: id=id[prefix+1:] if prefix >= 0:
elif id[0]=='i': id=id[1:] id = id[prefix + 1:]
elif id[0] == 'i':
id = id[1:]
if self.binary: if self.binary:
id=string.atoi(id) id = int(id)
s=mdumps(id)[1:] if id < 256:
if (id < 256): id = BINPUT + chr(id)
id=s[0]
put='q'
else: else:
id=s id = LONG_BINPUT + struct.pack('<i', id)
put='r'
id=put+id
else: else:
id="p"+id+"\012" id = PUT + repr(id) + '\n'
return v+id return v + id
return v return v
def save_string(self, tag, data): def save_string(self, tag, data):
binary=self.binary a = data[1]
v='' v = ''.join(data[2:])
a=data[1] encoding = a['encoding']
if len(data)>2:
for x in data[2:]:
v=v+x
encoding=a['encoding']
if encoding is not '': if encoding is not '':
v=unconvert(encoding,v) v = unescape(v, encoding)
put='p' if self.binary:
if binary: l = len(v)
l=len(v) if l < 256:
s=mdumps(l)[1:] v = SHORT_BINSTRING + chr(l) + v
if (l<256):
v='U'+s[0]+v
else: else:
v='T'+s+v v = BINSTRING + struct.pack('<i', l) + v
put='q' else:
else: v="S'"+v+"'\012" 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) return save_put(self, v, a)
def save_tuple(self, tag, data): def save_tuple(self, tag, data):
T=data[2:] T = data[2:]
if not T: return ')' if not T:
return save_put(self, '('+string.join(T,'')+'t', data[1]) return EMPTY_TUPLE
return save_put(self, MARK + ''.join(T) + TUPLE, data[1])
def save_list(self, tag, data): def save_list(self, tag, data):
L=data[2:] L = data[2:]
a=data[1]
if self.binary: if self.binary:
v=save_put(self, ']', a) v = save_put(self, EMPTY_LIST, data[1])
if L: v=v+'('+string.join(L,'')+'e' if L:
v = v + MARK + ''.join(L) + APPENDS
else: else:
v=save_put(self, '(l', a) v = save_put(self, MARK + LIST, data[1])
if L: v=string.join(L,'a')+'a' if L:
v = APPEND.join(L) + APPEND
return v return v
def save_dict(self, tag, data): def save_dict(self, tag, data):
D=data[2:] D = data[2:]
if self.binary: if self.binary:
v=save_put(self, '}', data[1]) v = save_put(self, EMPTY_DICT, data[1])
if D: v=v+'('+string.join(D,'')+'u' if D:
v = v + MARK + ''.join(D) + SETITEMS
else: else:
v=save_put(self, '(d', data[1]) v = save_put(self, MARK + DICT, data[1])
if D: v=v+string.join(D,'s')+'s' if D:
v = v + SETITEM.join(D) + SETITEM
return v return v
def save_reference(self, tag, data): def save_reference(self, tag, data):
binary=self.binary a = data[1]
a=data[1] id = a['id']
id=a['id'] prefix = id.rfind('.')
prefix=string.rfind(id,'.') if prefix >= 0:
if prefix>=0: id=id[prefix+1:] id = id[prefix + 1:]
get='g' if self.binary:
if binary: id = int(id)
id=string.atoi(id) if id < 256:
s=mdumps(id)[1:] return BINGET + chr(id)
if (id < 256):
id=s[0]
get='h'
else: else:
id=s return LONG_BINGET + struct.pack('<i', i)
get='j' else:
v=get+id return GET + repr(id) + '\n'
else: v=get+id+'\012'
return v
def save_object(self, tag, data): def save_object(self, tag, data):
v='('+data[2] v = MARK + data[2]
x=data[3][1:] x = data[3][1:]
stop=string.rfind(x,'t') # This seems stop = x.rfind('t') # This seems
if stop>=0: x=x[:stop] # wrong! if stop >= 0: # wrong!
v=save_put(self, v+x+'o', data[1]) x = x[:stop]
v=v+data[4]+'b' # state v = save_put(self, v + x + OBJ, data[1])
v = v + data[4] + BUILD # state
return v return v
def save_global(self, tag, data): def save_global(self, tag, data):
a=data[1] a = data[1]
return save_put(self, 'c'+a['module']+'\012'+a['name']+'\012', a) return save_put(self, GLOBAL + a['module'] + '\n' + a['name'] + '\n', a)
def save_persis(self, tag, data): def save_persis(self, tag, data):
v=data[2] v = data[2]
if self.binary: if self.binary:
v=v+'Q' return v + BINPERSID
else: else:
v='P'+v return PERSID + v
return v
class xmlPickler(NoBlanks, xyap): class xmlPickler(NoBlanks, xyap):
start_handlers={ start_handlers = {
'pickle': lambda self, tag, attrs: [tag, attrs], 'pickle': lambda self, tag, attrs: [tag, attrs],
} }
end_handlers={ end_handlers = {
'pickle': lambda self, tag, data: str(data[2])+'.', 'pickle': lambda self, tag, data: str(data[2]) + STOP,
'none': lambda self, tag, data: 'N', 'none': lambda self, tag, data: NONE,
'int': save_int, '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, 'float': save_float,
'string': save_string, 'string': save_string,
'reference': save_reference, 'reference': save_reference,
'tuple': save_tuple, 'tuple': save_tuple,
'list': save_list, 'list': save_list,
'dictionary': save_dict, '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], 'value': lambda self, tag, data: data[2],
'key' : lambda self, tag, data: data[2], 'key' : lambda self, tag, data: data[2],
'object': save_object, 'object': save_object,
...@@ -661,6 +596,7 @@ class xmlPickler(NoBlanks, xyap): ...@@ -661,6 +596,7 @@ class xmlPickler(NoBlanks, xyap):
'state': lambda self, tag, data: data[2], 'state': lambda self, tag, data: data[2],
'global': save_global, 'global': save_global,
'persistent': save_persis, 'persistent': save_persis,
'unicode': save_unicode,
} }
...@@ -672,16 +608,17 @@ class C: ...@@ -672,16 +608,17 @@ class C:
def test(): def test():
import xmllib import xmllib
c=C() import pickle
c.foo=1 c = C()
c.bar=2 c.foo = 1
x=[0,1,2,3] c.bar = 2
y=('abc','abc',c,c) x = [0, 1, 2, 3]
y = ('abc', 'abc', c, c)
x.append(y) x.append(y)
x.append(y) x.append(y)
t=() t = ()
l=[] l = []
s='' s = ''
L = long('999999999999') L = long('999999999999')
x.append(t) x.append(t)
x.append(l) x.append(l)
...@@ -689,78 +626,52 @@ def test(): ...@@ -689,78 +626,52 @@ def test():
x.append(L) x.append(L)
x.append(55555) x.append(55555)
x.append(13) x.append(13)
r=[x] r = [x]
print x print x
f=pickle.dumps(x) f = pickle.dumps(x)
print f print f
r.append(f) r.append(f)
q=ToXMLloads(f) q = ToXMLloads(f)
q=str(q) q = str(q)
q='<?xml version="1.0"?>\n'+q q = '<?xml version="1.0"?>\n' + q
print q print q
r.append(q) r.append(q)
file='' F = xmlPickler()
F=xmlPickler(file) F.binary = 1
p=xmllib.XMLParser() p = xmllib.XMLParser()
p.start_handlers=F.start_handlers p.start_handlers = F.start_handlers
p.end_handlers=F.end_handlers p.end_handlers = F.end_handlers
p.handle_data=F.handle_data p.handle_data = F.handle_data
p.unknown_starttag=F.unknown_starttag p.unknown_starttag = F.unknown_starttag
p.unknown_endtag=F.unknown_endtag p.unknown_endtag = F.unknown_endtag
p._stack=F._stack p._stack = F._stack
p.push=F.push p.push = F.push
p.append=F.append p.append = F.append
p.file=F.file data = q.split('\n')
p.tempfile=F.tempfile
p.binary=1
data=string.split(q,'\n')
for l in data: for l in data:
p.feed(l) p.feed(l)
p.close() p.close()
z=p._stack z = p._stack
z=z[0][0] z = z[0][0]
print z, '\012' print z, '\n'
r.append(z) r.append(z)
l=pickle.loads(z) l = pickle.loads(z)
print l, '\012' print l, '\n'
r.append(l) r.append(l)
def test1(): 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 import xml.parsers.expat
c=C() import pickle
c.foo=1 c = C()
c.bar=2 c.foo = 1
x=[0,1,2,3] c.bar = 2
y=('abc','abc',c,c) x = [0, 1, 2, 3]
y = ('abc', 'abc', c, c)
x.append(y) x.append(y)
x.append(y) x.append(y)
t=() t = ()
l=[] l = []
s='' s = ''
L = long('999999999999') L = long('999999999999')
x.append(t) x.append(t)
x.append(l) x.append(l)
...@@ -768,36 +679,21 @@ def test2(): ...@@ -768,36 +679,21 @@ def test2():
x.append(L) x.append(L)
x.append(5) x.append(5)
x.append(13) x.append(13)
print x, '\012' print x, '\n'
f=pickle.dumps(x) f = pickle.dumps(x)
print f, '\012' print f, '\n'
q=ToXMLloads(f) q = ToXMLloads(f)
q=str(q) q = str(q)
q='<?xml version="1.0"?>\n'+q q = '<?xml version="1.0"?>\n' + q
print q, '\012' print q, '\n'
file='' F = xmlPickler()
F=xmlPickler() F.binary = 0
F.binary=0 p = xml.parsers.expat.ParserCreate()
p=xml.parsers.expat.ParserCreate() p.CharacterDataHandler = F.handle_data
p.CharacterDataHandler=F.handle_data p.StartElementHandler = F.unknown_starttag
p.StartElementHandler=F.unknown_starttag p.EndElementHandler = F.unknown_endtag
p.EndElementHandler=F.unknown_endtag r = p.Parse(q)
r=p.Parse(q) print r, '\n'
print r, '\012'
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__': if __name__ == '__main__':
test() test()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment