/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/xml_serializer.py

Merge benchmark branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: UTF-8 -*-
 
2
 
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
 
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
 
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""XML externalization support."""
 
18
 
 
19
# "XML is like violence: if it doesn't solve your problem, you aren't
 
20
# using enough of it." -- various
 
21
 
 
22
# importing this module is fairly slow because it has to load several
 
23
# ElementTree bits
 
24
 
 
25
from bzrlib.trace import mutter, warning
 
26
 
 
27
try:
 
28
    from cElementTree import (ElementTree, SubElement, Element,
 
29
                              XMLTreeBuilder, fromstring, tostring)
 
30
except ImportError:
 
31
    mutter('WARNING: using slower ElementTree; consider installing cElementTree'
 
32
           " and make sure it's on your PYTHONPATH")
 
33
    from util.elementtree.ElementTree import (ElementTree, SubElement,
 
34
                                              Element, XMLTreeBuilder,
 
35
                                              fromstring, tostring)
 
36
 
 
37
from bzrlib.errors import BzrError
 
38
 
 
39
 
 
40
class Serializer(object):
 
41
    """Abstract object serialize/deserialize"""
 
42
    def write_inventory(self, inv, f):
 
43
        """Write inventory to a file"""
 
44
        elt = self._pack_inventory(inv)
 
45
        self._write_element(elt, f)
 
46
 
 
47
    def write_inventory_to_string(self, inv):
 
48
        return tostring(self._pack_inventory(inv)) + '\n'
 
49
 
 
50
    def read_inventory_from_string(self, xml_string):
 
51
        return self._unpack_inventory(fromstring(xml_string))
 
52
 
 
53
    def read_inventory(self, f):
 
54
        return self._unpack_inventory(self._read_element(f))
 
55
 
 
56
    def write_revision(self, rev, f):
 
57
        self._write_element(self._pack_revision(rev), f)
 
58
 
 
59
    def write_revision_to_string(self, rev):
 
60
        return tostring(self._pack_revision(rev)) + '\n'
 
61
 
 
62
    def read_revision(self, f):
 
63
        return self._unpack_revision(self._read_element(f))
 
64
 
 
65
    def read_revision_from_string(self, xml_string):
 
66
        return self._unpack_revision(fromstring(xml_string))
 
67
 
 
68
    def _write_element(self, elt, f):
 
69
        ElementTree(elt).write(f, 'utf-8')
 
70
        f.write('\n')
 
71
 
 
72
    def _read_element(self, f):
 
73
        return ElementTree().parse(f)
 
74
 
 
75
 
 
76
# before in bench_add_kernel_like
 
77
# 10831        10824   9384.4890   1847.5270   elementtree.ElementTree:662(_write)
 
78
#+10824            0   9295.0140   1761.0460   +elementtree.ElementTree:662(_write)
 
79
#+32471            0   4585.8950   1331.2060   +elementtree.ElementTree:812(_escape_attrib)
 
80
#after switching to text.replace rather than string.replace.
 
81
# 10831        10824   7486.1120   1832.2340   elementtree.ElementTree:662(_write)
 
82
#+10824            0   7397.3120   1745.6300   +elementtree.ElementTree:662(_write)
 
83
#+32471            0   2762.3760   1300.3990   +bzrlib.xml_serializer:85(_escape_attrib)
 
84
 
 
85
 
 
86
import elementtree.ElementTree
 
87
import re
 
88
escape_re = re.compile("&'\"<>")
 
89
escape_map = {
 
90
    "&":'&amp;',
 
91
    "'":"&apos;", # FIXME: overkill
 
92
    "\"":"&quot;",
 
93
    "<":"&lt;",
 
94
    ">":"&gt;",
 
95
    }
 
96
def _escape_replace(match, map=escape_map):
 
97
    return map[match.group()]
 
98
 
 
99
def _escape_attrib(text, encoding=None, replace=None):
 
100
    # escape attribute value
 
101
    try:
 
102
        if encoding:
 
103
            try:
 
104
                text = elementtree.ElementTree._encode(text, encoding)
 
105
            except UnicodeError:
 
106
                return elementtree.ElementTree._encode_entity(text)
 
107
        if replace is None:
 
108
            return escape_re.sub(_escape_replace, text)
 
109
        else:
 
110
            text = replace(text, "&", "&amp;")
 
111
            text = replace(text, "'", "&apos;") # FIXME: overkill
 
112
            text = replace(text, "\"", "&quot;")
 
113
            text = replace(text, "<", "&lt;")
 
114
            text = replace(text, ">", "&gt;")
 
115
            return text
 
116
    except (TypeError, AttributeError):
 
117
        elementtree.ElementTree._raise_serialization_error(text)
 
118
 
 
119
elementtree.ElementTree._escape_attrib = _escape_attrib
 
120
 
 
121
escape_cdata_re = re.compile("&<>")
 
122
escape_cdata_map = {
 
123
    "&":'&amp;',
 
124
    "<":"&lt;",
 
125
    ">":"&gt;",
 
126
    }
 
127
def _escape_cdata_replace(match, map=escape_cdata_map):
 
128
    return map[match.group()]
 
129
 
 
130
def _escape_cdata(text, encoding=None, replace=None):
 
131
    # escape character data
 
132
    try:
 
133
        if encoding:
 
134
            try:
 
135
                text = elementtree.ElementTree._encode(text, encoding)
 
136
            except UnicodeError:
 
137
                return elementtree.ElementTree._encode_entity(text)
 
138
        if replace is None:
 
139
            return escape_cdata_re.sub(_escape_cdata_replace, text)
 
140
        else:
 
141
            text = replace(text, "&", "&amp;")
 
142
            text = replace(text, "<", "&lt;")
 
143
            text = replace(text, ">", "&gt;")
 
144
            return text
 
145
    except (TypeError, AttributeError):
 
146
        elementtree.ElementTree._raise_serialization_error(text)
 
147
 
 
148
elementtree.ElementTree._escape_cdata = _escape_cdata