~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/chk_serializer.py

NEWS section template into a separate file

Show diffs side-by-side

added added

removed removed

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