~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/chk_serializer.py

  • Committer: Vincent Ladeuil
  • Date: 2013-05-25 17:12:43 UTC
  • mto: (6437.77.1 2.5)
  • mto: This revision was merged to the branch mainline in revision 6577.
  • Revision ID: v.ladeuil+lp@free.fr-20130525171243-au0073fnspecl3kg
Empty arguments in EDITOR are now properly preserved

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 __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
""")
19
30
from bzrlib import (
20
31
    bencode,
21
32
    cache_utf8,
22
 
    inventory,
 
33
    errors,
23
34
    revision as _mod_revision,
24
 
    xml6,
25
 
    xml7,
 
35
    serializer,
26
36
    )
27
37
 
28
38
 
131
141
        return self.read_revision_from_string(f.read())
132
142
 
133
143
 
134
 
class CHKSerializerSubtree(BEncodeRevisionSerializer1, xml7.Serializer_v7):
135
 
    """A CHKInventory based serializer that supports tree references"""
 
144
class CHKSerializer(serializer.Serializer):
 
145
    """A CHKInventory based serializer with 'plain' behaviour."""
136
146
 
137
 
    supported_kinds = set(['file', 'directory', 'symlink', 'tree-reference'])
138
147
    format_num = '9'
139
148
    revision_format_num = None
140
149
    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)
 
150
    supported_kinds = set(['file', 'directory', 'symlink'])
 
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)
154
227
        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
 
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
173
243
 
174
244
 
175
245
chk_serializer_255_bigpage = CHKSerializer(65536, 'hash-255-way')