run-tests.py: Only pass the --svnadmin option to cvs2svn when needed.
[cvs2svn.git] / cvs2svn_lib / serializer.py
blob24bd81c7e218ccc33844165b48e2f782623ea984
1 # (Be in -*- python -*- mode.)
3 # ====================================================================
4 # Copyright (c) 2000-2008 CollabNet. All rights reserved.
6 # This software is licensed as described in the file COPYING, which
7 # you should have received as part of this distribution. The terms
8 # are also available at http://subversion.tigris.org/license-1.html.
9 # If newer versions of this license are posted there, you may use a
10 # newer version instead, at your option.
12 # This software consists of voluntary contributions made by many
13 # individuals. For exact contribution history, see the revision
14 # history and logs, available at http://cvs2svn.tigris.org/.
15 # ====================================================================
17 """Picklers and unpicklers that are primed with known objects."""
20 import cStringIO
21 import marshal
22 import cPickle
23 import zlib
26 class Serializer:
27 """An object able to serialize/deserialize some class of objects."""
29 def dumpf(self, f, object):
30 """Serialize OBJECT to file-like object F."""
32 raise NotImplementedError()
34 def dumps(self, object):
35 """Return a string containing OBJECT in serialized form."""
37 raise NotImplementedError()
39 def loadf(self, f):
40 """Return the next object deserialized from file-like object F."""
42 raise NotImplementedError()
44 def loads(self, s):
45 """Return the object deserialized from string S."""
47 raise NotImplementedError()
50 class MarshalSerializer(Serializer):
51 """This class uses the marshal module to serialize/deserialize.
53 This means that it shares the limitations of the marshal module,
54 namely only being able to serialize a few simple python data types
55 without reference loops."""
57 def dumpf(self, f, object):
58 marshal.dump(object, f)
60 def dumps(self, object):
61 return marshal.dumps(object)
63 def loadf(self, f):
64 return marshal.load(f)
66 def loads(self, s):
67 return marshal.loads(s)
70 class PrimedPickleSerializer(Serializer):
71 """This class acts as a pickler/unpickler with a pre-initialized memo.
73 The picklers and unpicklers are 'pre-trained' to recognize the
74 objects that are in the primer. If objects are recognized
75 from PRIMER, then only their persistent IDs need to be pickled
76 instead of the whole object. (Note that the memos needed for
77 pickling and unpickling are different.)
79 A new pickler/unpickler is created for each use, each time with the
80 memo initialized appropriately for pickling or unpickling."""
82 def __init__(self, primer):
83 """Prepare to make picklers/unpicklers with the specified primer.
85 The Pickler and Unpickler are 'primed' by pre-pickling PRIMER,
86 which can be an arbitrary object (e.g., a list of objects that are
87 expected to occur frequently in the objects to be serialized)."""
89 f = cStringIO.StringIO()
90 pickler = cPickle.Pickler(f, -1)
91 pickler.dump(primer)
92 self.pickler_memo = pickler.memo
94 unpickler = cPickle.Unpickler(cStringIO.StringIO(f.getvalue()))
95 unpickler.load()
96 self.unpickler_memo = unpickler.memo
98 def dumpf(self, f, object):
99 """Serialize OBJECT to file-like object F."""
101 pickler = cPickle.Pickler(f, -1)
102 pickler.memo = self.pickler_memo.copy()
103 pickler.dump(object)
105 def dumps(self, object):
106 """Return a string containing OBJECT in serialized form."""
108 f = cStringIO.StringIO()
109 self.dumpf(f, object)
110 return f.getvalue()
112 def loadf(self, f):
113 """Return the next object deserialized from file-like object F."""
115 unpickler = cPickle.Unpickler(f)
116 unpickler.memo = self.unpickler_memo.copy()
117 return unpickler.load()
119 def loads(self, s):
120 """Return the object deserialized from string S."""
122 return self.loadf(cStringIO.StringIO(s))
125 class CompressingSerializer(Serializer):
126 """This class wraps other Serializers to compress their serialized data."""
128 def __init__(self, wrapee):
129 """Constructor. WRAPEE is the Serializer whose bitstream ought to be
130 compressed."""
132 self.wrapee = wrapee
134 def dumpf(self, f, object):
135 marshal.dump(zlib.compress(self.wrapee.dumps(object), 9), f)
137 def dumps(self, object):
138 return marshal.dumps(zlib.compress(self.wrapee.dumps(object), 9))
140 def loadf(self, f):
141 return self.wrapee.loads(zlib.decompress(marshal.load(f)))
143 def loads(self, s):
144 return self.wrapee.loads(zlib.decompress(marshal.loads(s)))