25
25
__all__ = ['InventoryDeltaSerializer']
27
from bzrlib import errors, lazy_regex
27
from bzrlib import errors
28
28
from bzrlib.osutils import basename
29
29
from bzrlib import inventory
30
30
from bzrlib.revision import NULL_REVISION
33
33
def _directory_content(entry):
34
"""Serialise the content component of entry which is a directory.
34
"""Serialize the content component of entry which is a directory.
36
36
:param entry: An InventoryDirectory.
67
67
def _reference_content(entry):
68
"""Serialise the content component of entry which is a tree-reference.
68
"""Serialize the content component of entry which is a tree-reference.
70
70
:param entry: A TreeReference.
120
120
"""Serialize and deserialize inventory deltas."""
122
122
FORMAT_1 = 'bzr inventory delta v1 (bzr 1.14)'
123
_file_ids_altered_regex = lazy_regex.lazy_compile(
124
'^(?P<path_utf8>[^\x00]+)\x00(?P<file_id>[^\x00]+)\x00[^\x00]*\x00'
125
'(?P<revision_id>[^\x00]+)\x00'
128
124
def __init__(self, versioned_root, tree_references):
129
125
"""Create an InventoryDeltaSerializer.
153
149
:param delta_to_new: An inventory delta such as Inventory.apply_delta
155
:return: The serialised delta as lines.
151
:return: The serialized delta as lines.
157
153
lines = ['', '', '', '', '']
158
154
to_line = self._delta_item_to_line
194
190
oldpath_utf8 = '/' + oldpath.encode('utf8')
195
191
# TODO: Test real-world utf8 cache hit rate. It may be a win.
196
192
newpath_utf8 = '/' + newpath.encode('utf8')
197
# Serialise None as ''
193
# Serialize None as ''
198
194
parent_id = entry.parent_id or ''
199
# Serialise unknown revisions as NULL_REVISION
195
# Serialize unknown revisions as NULL_REVISION
200
196
last_modified = entry.revision
201
197
# special cases for /
202
198
if newpath_utf8 == '/' and not self._versioned_root:
223
219
raise errors.BzrError("value %r is not a bool" % (value,))
225
221
def parse_text_bytes(self, bytes):
226
"""Parse the text bytes of a journal entry.
222
"""Parse the text bytes of a serialized inventory delta.
228
224
:param bytes: The bytes to parse. This can be obtained by calling
229
225
delta_to_lines and then doing ''.join(delta_lines).
234
230
raise errors.BzrError('unknown format %r' % lines[0:1])
235
231
if len(lines) < 2 or not lines[1].startswith('parent: '):
236
232
raise errors.BzrError('missing parent: marker')
237
journal_parent_id = lines[1][8:]
233
delta_parent_id = lines[1][8:]
238
234
if len(lines) < 3 or not lines[2].startswith('version: '):
239
235
raise errors.BzrError('missing version: marker')
240
journal_version_id = lines[2][9:]
236
delta_version_id = lines[2][9:]
241
237
if len(lines) < 4 or not lines[3].startswith('versioned_root: '):
242
238
raise errors.BzrError('missing versioned_root: marker')
243
journal_versioned_root = self._deserialize_bool(lines[3][16:])
239
delta_versioned_root = self._deserialize_bool(lines[3][16:])
244
240
if len(lines) < 5 or not lines[4].startswith('tree_references: '):
245
241
raise errors.BzrError('missing tree_references: marker')
246
journal_tree_references = self._deserialize_bool(lines[4][17:])
247
if journal_versioned_root != self._versioned_root:
242
delta_tree_references = self._deserialize_bool(lines[4][17:])
243
if delta_versioned_root != self._versioned_root:
248
244
raise errors.BzrError(
249
245
"serialized versioned_root flag is wrong: %s" %
250
(journal_versioned_root,))
251
if journal_tree_references != self._tree_references:
246
(delta_versioned_root,))
247
if delta_tree_references != self._tree_references:
252
248
raise errors.BzrError(
253
249
"serialized tree_references flag is wrong: %s" %
254
(journal_tree_references,))
250
(delta_tree_references,))
257
253
line_iter = iter(lines)
263
259
parent_id = parent_id or None
264
260
if file_id in seen_ids:
265
261
raise errors.BzrError(
266
"duplicate file id in journal entry %r" % lines)
262
"duplicate file id in inventory delta %r" % lines)
267
263
seen_ids.add(file_id)
268
if newpath_utf8 == '/' and not journal_versioned_root and (
264
if newpath_utf8 == '/' and not delta_versioned_root and (
269
265
last_modified != 'null:' or file_id != 'TREE_ROOT'):
270
266
raise errors.BzrError("Versioned root found: %r" % line)
271
267
elif last_modified[-1] == ':':
272
268
raise errors.BzrError('special revisionid found: %r' % line)
273
if not journal_tree_references and content.startswith('tree\x00'):
269
if not delta_tree_references and content.startswith('tree\x00'):
274
270
raise errors.BzrError("Tree reference found: %r" % line)
275
271
content_tuple = tuple(content.split('\x00'))
276
272
entry = _parse_entry(
285
281
newpath = newpath_utf8.decode('utf8')
286
282
delta_item = (oldpath, newpath, file_id, entry)
287
283
result.append(delta_item)
288
return journal_parent_id, journal_version_id, result
284
return delta_parent_id, delta_version_id, result
291
287
def _parse_entry(utf8_path, file_id, parent_id, last_modified, content):