148
156
append = output.append
149
157
self._append_inventory_root(append, inv)
150
158
serialize_inventory_flat(inv, append,
151
self.root_id, self.supported_kinds, working)
159
self.root_id, self.supported_kinds, working)
152
160
if f is not None:
153
161
f.writelines(output)
154
162
# Just to keep the cache from growing without bounds
155
163
# but we may actually not want to do clear the cache
159
167
def _append_inventory_root(self, append, inv):
160
168
"""Append the inventory root to output."""
161
169
if inv.revision_id is not None:
163
[b' revision_id="', encode_and_escape(inv.revision_id), b'"'])
170
revid1 = ' revision_id="'
171
revid2 = encode_and_escape(inv.revision_id)
166
append(b'<inventory format="%s"%s>\n' % (
167
self.format_num, revid1))
168
append(b'<directory file_id="%s" name="%s" revision="%s" />\n' % (
175
append('<inventory format="%s"%s%s>\n' % (
176
self.format_num, revid1, revid2))
177
append('<directory file_id="%s name="%s revision="%s />\n' % (
169
178
encode_and_escape(inv.root.file_id),
170
179
encode_and_escape(inv.root.name),
171
180
encode_and_escape(inv.root.revision)))
173
def write_revision_to_lines(self, rev):
182
def _pack_revision(self, rev):
174
183
"""Revision object -> xml tree"""
175
184
# For the XML format, we need to write them as Unicode rather than as
176
185
# utf-8 strings. So that cElementTree can handle properly escaping
179
el = (b'<revision committer="%s" format="%s" '
180
b'inventory_sha1="%s" revision_id="%s" '
181
b'timestamp="%.3f"' % (
182
encode_and_escape(rev.committer),
183
self.revision_format_num or self.format_num,
185
encode_and_escape(cache_utf8.decode(rev.revision_id)),
187
decode_utf8 = cache_utf8.decode
188
revision_id = rev.revision_id
189
if isinstance(revision_id, str):
190
revision_id = decode_utf8(revision_id)
191
format_num = self.format_num
192
if self.revision_format_num is not None:
193
format_num = self.revision_format_num
194
root = Element('revision',
195
committer = rev.committer,
196
timestamp = '%.3f' % rev.timestamp,
197
revision_id = revision_id,
198
inventory_sha1 = rev.inventory_sha1,
187
201
if rev.timezone is not None:
188
el += b' timezone="%s"' % str(rev.timezone).encode('ascii')
189
lines.append(el + b'>\n')
190
message = encode_and_escape(escape_invalid_chars(rev.message)[0])
191
lines.extend((b'<message>' + message + b'</message>\n').splitlines(True))
202
root.set('timezone', str(rev.timezone))
204
msg = SubElement(root, 'message')
205
msg.text = escape_invalid_chars(rev.message)[0]
192
207
if rev.parent_ids:
193
lines.append(b'<parents>\n')
208
pelts = SubElement(root, 'parents')
209
pelts.tail = pelts.text = '\n'
194
210
for parent_id in rev.parent_ids:
195
211
_mod_revision.check_not_reserved_id(parent_id)
197
b'<revision_ref revision_id="%s" />\n'
198
% encode_and_escape(cache_utf8.decode(parent_id)))
199
lines.append(b'</parents>\n')
212
p = SubElement(pelts, 'revision_ref')
214
if isinstance(parent_id, str):
215
parent_id = decode_utf8(parent_id)
216
p.set('revision_id', parent_id)
200
217
if rev.properties:
201
preamble = b'<properties>'
202
for prop_name, prop_value in sorted(rev.properties.items()):
204
proplines = (preamble + b'<property name="%s">%s</property>\n' % (
205
encode_and_escape(prop_name),
206
encode_and_escape(escape_invalid_chars(prop_value)[0]))).splitlines(True)
208
proplines = [preamble + b'<property name="%s" />\n' % (encode_and_escape(prop_name), )]
210
lines.extend(proplines)
211
lines.append(b'</properties>\n')
212
lines.append(b'</revision>\n')
218
self._pack_revision_properties(rev, root)
221
def _pack_revision_properties(self, rev, under_element):
222
top_elt = SubElement(under_element, 'properties')
223
for prop_name, prop_value in sorted(rev.properties.items()):
224
prop_elt = SubElement(top_elt, 'property')
225
prop_elt.set('name', prop_name)
226
prop_elt.text = prop_value
215
230
def _unpack_entry(self, elt, entry_cache=None, return_from_cache=False):
216
231
# This is here because it's overridden by xml7
217
232
return unpack_inventory_entry(elt, entry_cache,
220
235
def _unpack_inventory(self, elt, revision_id=None, entry_cache=None,
221
236
return_from_cache=False):
222
237
"""Construct from XML Element"""
223
238
inv = unpack_inventory_flat(elt, self.format_num, self._unpack_entry,
224
entry_cache, return_from_cache)
239
entry_cache, return_from_cache)
225
240
self._check_cache_size(len(inv), entry_cache)