~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/chk_serializer.py

  • Committer: Jelmer Vernooij
  • Date: 2011-12-16 19:18:39 UTC
  • mto: This revision was merged to the branch mainline in revision 6391.
  • Revision ID: jelmer@samba.org-20111216191839-eg681lxqibi1qxu1
Fix remaining tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Serializer object for CHK based inventory storage."""
18
18
 
 
19
from cStringIO import StringIO
 
20
 
 
21
from bzrlib import lazy_import
 
22
lazy_import.lazy_import(globals(),
 
23
"""
 
24
from bzrlib import (
 
25
    xml_serializer,
 
26
    )
 
27
""")
19
28
from bzrlib import (
20
29
    bencode,
21
30
    cache_utf8,
22
 
    inventory,
 
31
    errors,
23
32
    revision as _mod_revision,
24
 
    xml6,
25
 
    xml7,
 
33
    serializer,
26
34
    )
27
35
 
28
36
 
131
139
        return self.read_revision_from_string(f.read())
132
140
 
133
141
 
134
 
class CHKSerializerSubtree(BEncodeRevisionSerializer1, xml7.Serializer_v7):
135
 
    """A CHKInventory based serializer that supports tree references"""
 
142
class CHKSerializer(serializer.Serializer):
 
143
    """A CHKInventory based serializer with 'plain' behaviour."""
136
144
 
137
 
    supported_kinds = set(['file', 'directory', 'symlink', 'tree-reference'])
138
145
    format_num = '9'
139
146
    revision_format_num = None
140
147
    support_altered_by_hack = False
141
 
 
142
 
    def _unpack_entry(self, elt, entry_cache=None, return_from_cache=False):
143
 
        kind = elt.tag
144
 
        if not kind in self.supported_kinds:
145
 
            raise AssertionError('unsupported entry kind %s' % kind)
146
 
        if kind == 'tree-reference':
147
 
            file_id = elt.attrib['file_id']
148
 
            name = elt.attrib['name']
149
 
            parent_id = elt.attrib['parent_id']
150
 
            revision = elt.get('revision')
151
 
            reference_revision = elt.get('reference_revision')
152
 
            return inventory.TreeReference(file_id, name, parent_id, revision,
153
 
                                           reference_revision)
 
148
    supported_kinds = set(['file', 'directory', 'symlink'])
 
149
 
 
150
    def __init__(self, node_size, search_key_name):
 
151
        self.maximum_size = node_size
 
152
        self.search_key_name = search_key_name
 
153
 
 
154
    def _unpack_inventory(self, elt, revision_id=None, entry_cache=None,
 
155
                          return_from_cache=False):
 
156
        """Construct from XML Element"""
 
157
        inv = xml_serializer.unpack_inventory_flat(elt, self.format_num,
 
158
            xml_serializer.unpack_inventory_entry, entry_cache,
 
159
            return_from_cache)
 
160
        return inv
 
161
 
 
162
    def read_inventory_from_string(self, xml_string, revision_id=None,
 
163
                                   entry_cache=None, return_from_cache=False):
 
164
        """Read xml_string into an inventory object.
 
165
 
 
166
        :param xml_string: The xml to read.
 
167
        :param revision_id: If not-None, the expected revision id of the
 
168
            inventory.
 
169
        :param entry_cache: An optional cache of InventoryEntry objects. If
 
170
            supplied we will look up entries via (file_id, revision_id) which
 
171
            should map to a valid InventoryEntry (File/Directory/etc) object.
 
172
        :param return_from_cache: Return entries directly from the cache,
 
173
            rather than copying them first. This is only safe if the caller
 
174
            promises not to mutate the returned inventory entries, but it can
 
175
            make some operations significantly faster.
 
176
        """
 
177
        try:
 
178
            return self._unpack_inventory(
 
179
                xml_serializer.fromstring(xml_string), revision_id,
 
180
                entry_cache=entry_cache,
 
181
                return_from_cache=return_from_cache)
 
182
        except xml_serializer.ParseError, e:
 
183
            raise errors.UnexpectedInventoryFormat(e)
 
184
 
 
185
    def read_inventory(self, f, revision_id=None):
 
186
        """Read an inventory from a file-like object."""
 
187
        try:
 
188
            try:
 
189
                return self._unpack_inventory(self._read_element(f),
 
190
                    revision_id=None)
 
191
            finally:
 
192
                f.close()
 
193
        except xml_serializer.ParseError, e:
 
194
            raise errors.UnexpectedInventoryFormat(e)
 
195
 
 
196
    def write_inventory_to_lines(self, inv):
 
197
        """Return a list of lines with the encoded inventory."""
 
198
        return self.write_inventory(inv, None)
 
199
 
 
200
    def write_inventory_to_string(self, inv, working=False):
 
201
        """Just call write_inventory with a StringIO and return the value.
 
202
 
 
203
        :param working: If True skip history data - text_sha1, text_size,
 
204
            reference_revision, symlink_target.
 
205
        """
 
206
        sio = StringIO()
 
207
        self.write_inventory(inv, sio, working)
 
208
        return sio.getvalue()
 
209
 
 
210
    def write_inventory(self, inv, f, working=False):
 
211
        """Write inventory to a file.
 
212
 
 
213
        :param inv: the inventory to write.
 
214
        :param f: the file to write. (May be None if the lines are the desired
 
215
            output).
 
216
        :param working: If True skip history data - text_sha1, text_size,
 
217
            reference_revision, symlink_target.
 
218
        :return: The inventory as a list of lines.
 
219
        """
 
220
        output = []
 
221
        append = output.append
 
222
        if inv.revision_id is not None:
 
223
            revid1 = ' revision_id="'
 
224
            revid2 = xml_serializer.encode_and_escape(inv.revision_id)
154
225
        else:
155
 
            return xml7.Serializer_v7._unpack_entry(self, elt,
156
 
                entry_cache=entry_cache, return_from_cache=return_from_cache)
157
 
 
158
 
    def __init__(self, node_size, search_key_name):
159
 
        self.maximum_size = node_size
160
 
        self.search_key_name = search_key_name
161
 
 
162
 
 
163
 
class CHKSerializer(xml6.Serializer_v6):
164
 
    """A CHKInventory based serializer with 'plain' behaviour."""
165
 
 
166
 
    format_num = '9'
167
 
    revision_format_num = None
168
 
    support_altered_by_hack = False
169
 
 
170
 
    def __init__(self, node_size, search_key_name):
171
 
        self.maximum_size = node_size
172
 
        self.search_key_name = search_key_name
 
226
            revid1 = ""
 
227
            revid2 = ""
 
228
        append('<inventory format="%s"%s%s>\n' % (
 
229
            self.format_num, revid1, revid2))
 
230
        append('<directory file_id="%s name="%s revision="%s />\n' % (
 
231
            xml_serializer.encode_and_escape(inv.root.file_id),
 
232
            xml_serializer.encode_and_escape(inv.root.name),
 
233
            xml_serializer.encode_and_escape(inv.root.revision)))
 
234
        xml_serializer.serialize_inventory_flat(inv,
 
235
            append,
 
236
            root_id=None, supported_kinds=self.supported_kinds, 
 
237
            working=working)
 
238
        if f is not None:
 
239
            f.writelines(output)
 
240
        return output
173
241
 
174
242
 
175
243
chk_serializer_255_bigpage = CHKSerializer(65536, 'hash-255-way')