20
20
# "XML is like violence: if it doesn't solve your problem, you aren't
21
21
# using enough of it." -- various
23
# importing this module is fairly slow because it has to load several ElementTree bits
23
# importing this module is fairly slow because it has to load several
25
27
from util.cElementTree import ElementTree, SubElement, Element
26
28
except ImportError:
27
29
from util.elementtree.ElementTree import ElementTree, SubElement, Element
31
from bzrlib.inventory import ROOT_ID, Inventory, InventoryEntry
35
class Serializer(object):
36
"""Abstract object serialize/deserialize"""
37
def write_inventory(self, inv, f):
38
"""Write inventory to a file"""
39
elt = self._pack_inventory(inv)
40
self._write_element(elt, f)
42
def read_inventory(self, f):
43
return self._unpack_inventory(self._read_element(f))
45
def _write_element(self, elt, f):
46
ElementTree(elt).write(f, 'utf-8')
49
def _read_element(self, f):
50
return ElementTree().parse(f)
54
class _Serializer_v4(Serializer):
55
"""Version 0.0.4 serializer"""
59
def _pack_inventory(self, inv):
60
"""Convert to XML Element"""
61
e = Element('inventory')
63
if inv.root.file_id not in (None, ROOT_ID):
64
e.set('file_id', inv.root.file_id)
65
for path, ie in inv.iter_entries():
66
e.append(self._pack_entry(ie))
70
def _pack_entry(self, ie):
71
"""Convert InventoryEntry to XML element"""
73
e.set('name', ie.name)
74
e.set('file_id', ie.file_id)
75
e.set('kind', ie.kind)
77
if ie.text_size != None:
78
e.set('text_size', '%d' % ie.text_size)
80
for f in ['text_id', 'text_sha1']:
85
# to be conservative, we don't externalize the root pointers
86
# for now, leaving them as null in the xml form. in a future
87
# version it will be implied by nested elements.
88
if ie.parent_id != ROOT_ID:
89
assert isinstance(ie.parent_id, basestring)
90
e.set('parent_id', ie.parent_id)
97
def _unpack_inventory(self, elt):
98
"""Construct from XML Element
100
assert elt.tag == 'inventory'
101
root_id = elt.get('file_id') or ROOT_ID
102
inv = Inventory(root_id)
104
ie = self._unpack_entry(e)
105
if ie.parent_id == ROOT_ID:
106
ie.parent_id = root_id
111
def _unpack_entry(self, elt):
112
assert elt.tag == 'entry'
114
## original format inventories don't have a parent_id for
115
## nodes in the root directory, but it's cleaner to use one
117
parent_id = elt.get('parent_id')
118
if parent_id == None:
121
ie = InventoryEntry(elt.get('file_id'),
125
ie.text_id = elt.get('text_id')
126
ie.text_sha1 = elt.get('text_sha1')
128
## mutter("read inventoryentry: %r" % (elt.attrib))
130
v = elt.get('text_size')
131
ie.text_size = v and int(v)
136
"""singleton instance"""
137
serializer_v4 = _Serializer_v4()
30
143
def pack_xml(o, f):
31
144
"""Write object o to file f as XML.