13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""XML externalization support."""
34
33
except ImportError:
35
34
from cElementTree import (ElementTree, SubElement, Element,
36
35
XMLTreeBuilder, fromstring, tostring)
37
import elementtree.ElementTree
38
37
ParseError = SyntaxError
39
38
except ImportError:
40
39
mutter('WARNING: using slower ElementTree; consider installing cElementTree'
49
48
from bzrlib import errors
52
class XMLSerializer(Serializer):
53
"""Abstract XML object serialize/deserialize"""
55
def read_inventory_from_string(self, xml_string, revision_id=None,
57
"""Read xml_string into an inventory object.
59
:param xml_string: The xml to read.
60
:param revision_id: If not-None, the expected revision id of the
61
inventory. Some serialisers use this to set the results' root
62
revision. This should be supplied for deserialising all
63
from-repository inventories so that xml5 inventories that were
64
serialised without a revision identifier can be given the right
65
revision id (but not for working tree inventories where users can
66
edit the data without triggering checksum errors or anything).
67
:param entry_cache: An optional cache of InventoryEntry objects. If
68
supplied we will look up entries via (file_id, revision_id) which
69
should map to a valid InventoryEntry (File/Directory/etc) object.
51
class Serializer(object):
52
"""Abstract object serialize/deserialize"""
53
def write_inventory(self, inv, f):
54
"""Write inventory to a file"""
55
elt = self._pack_inventory(inv)
56
self._write_element(elt, f)
58
def write_inventory_to_string(self, inv):
59
return tostring(self._pack_inventory(inv)) + '\n'
61
def read_inventory_from_string(self, xml_string):
72
return self._unpack_inventory(fromstring(xml_string), revision_id,
73
entry_cache=entry_cache)
63
return self._unpack_inventory(fromstring(xml_string))
74
64
except ParseError, e:
75
65
raise errors.UnexpectedInventoryFormat(e)
77
def read_inventory(self, f, revision_id=None):
67
def read_inventory(self, f):
79
return self._unpack_inventory(self._read_element(f),
69
return self._unpack_inventory(self._read_element(f))
81
70
except ParseError, e:
82
71
raise errors.UnexpectedInventoryFormat(e)
166
155
elementtree.ElementTree._raise_serialization_error(text)
168
157
elementtree.ElementTree._escape_cdata = _escape_cdata
171
def escape_invalid_chars(message):
172
"""Escape the XML-invalid characters in a commit message.
174
:param message: Commit message to escape
175
:param count: Number of characters that were escaped
177
# Python strings can include characters that can't be
178
# represented in well-formed XML; escape characters that
179
# aren't listed in the XML specification
180
# (http://www.w3.org/TR/REC-xml/#NT-Char).
181
return re.subn(u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
182
lambda match: match.group(0).encode('unicode_escape'),