31
32
Packs objects into XML and vice versa.
35
__slots__ = ['_utf8_re']
40
def write_inventory_to_string(self, inv):
41
sio = cStringIO.StringIO()
42
self.write_inventory(inv, sio)
45
def write_inventory(self, inv, f):
46
"""Write inventory to a file.
48
:param inv: the inventory to write.
49
:param f: the file to write.
52
self._append_inventory_root(output, inv)
53
entries = inv.iter_entries()
54
root_path, root_ie = entries.next()
55
for path, ie in entries:
56
self._append_entry(output, ie)
57
f.write(''.join(output))
58
# elt = self._pack_inventory(inv)
59
# for child in elt.getchildren():
60
# if isinstance(child, inventory.InventoryDirectory):
63
# ElementTree(child).write(f, 'utf-8')
64
f.write('</inventory>\n')
66
def _append_inventory_root(self, output, inv):
67
"""Append the inventory root to output."""
68
output.append('<inventory')
69
if inv.root.file_id not in (None, ROOT_ID):
70
output.append(' file_id="')
71
self._append_utf8_escaped(output, inv.root.file_id)
72
output.append(' format="5"')
73
if inv.revision_id is not None:
74
output.append(' revision_id="')
75
self._append_utf8_escaped(output, inv.revision_id)
78
def _append_entry(self, output, ie):
79
"""Convert InventoryEntry to XML element and append to output."""
80
# TODO: should just be a plain assertion
81
assert InventoryEntry.versionable_kind(ie.kind), \
82
'unsupported entry kind %s' % ie.kind
85
output.append(ie.kind)
87
output.append(' executable="yes"')
88
output.append(' file_id="')
89
self._append_utf8_escaped(output, ie.file_id)
90
output.append(' name="')
91
self._append_utf8_escaped(output, ie.name)
92
if ie.parent_id != ROOT_ID:
93
assert isinstance(ie.parent_id, basestring)
94
output.append(' parent_id="')
95
self._append_utf8_escaped(output, ie.parent_id)
96
if ie.revision is not None:
97
output.append(' revision="')
98
self._append_utf8_escaped(output, ie.revision)
99
if ie.symlink_target is not None:
100
output.append(' symlink_target="')
101
self._append_utf8_escaped(output, ie.symlink_target)
102
if ie.text_sha1 is not None:
103
output.append(' text_size="')
104
output.append(ie.text_sha1)
106
if ie.text_size is not None:
107
output.append(' text_size="%d"' % ie.text_size)
108
output.append(" />\n")
111
def _append_utf8_escaped(self, output, a_string):
112
"""Append a_string to output as utf8."""
113
if self._utf8_re is None:
115
self._utf8_re = re.compile("[&'\"<>]")
116
# escape attribute value
117
text = a_string.encode('utf8')
118
output.append(self._utf8_re.sub(self._utf8_escape_replace, text))
123
"'":"'", # FIXME: overkill
128
def _utf8_escape_replace(self, match, map=_utf8_escape_map):
129
return map[match.group()]
36
131
def _pack_inventory(self, inv):
37
132
"""Convert to XML Element"""
38
133
entries = inv.iter_entries()