1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """xml serializer and component comparison
19 """
20
21 from cStringIO import StringIO
22 from xml.sax.saxutils import quoteattr
23
24 __version__ = "$Rev$"
25
26
28
29 encoding = '<?xml version="1.0" encoding="UTF-8"?>\n'
30
32 self._data = StringIO()
33 self._tagStack = []
34 self._indent = 0
35 self._indentChar = ' '
36 self._indentUnit = 2
37 self._data.write(self.encoding)
38
39
40
42 if indent == -1:
43 return -1
44 attrLength = 0
45 for attr, value in attributes:
46 if value is None:
47 raise ValueError(
48 "value for attribute %s cannot be None" % (attr, ))
49 attrLength += 1 + len(attr) + len(quoteattr(value))
50 return attrLength + indent
51
53 if not attributes:
54 return ''
55
56 if self._calcAttrsLength(attributes, indent) > 79:
57 indentLen = self._indent + indent
58 else:
59 indentLen = 0
60 first = True
61 attrValue = ''
62 for attr, value in attributes:
63 if indentLen and not first:
64 attrValue += '\n%s' % (self._indentChar * indentLen)
65 if value is None:
66 raise ValueError(
67 "value for attribute %s cannot be None" % (attr, ))
68 attrValue += ' %s=%s' % (attr, quoteattr(value))
69 if first:
70 first = False
71 return attrValue
72
73 - def _openTag(self, tagName, attributes=None):
77
80
81
82
84 """Fetches the xml written by the writer
85 @returns: the xml
86 @rtype: string
87 """
88 return self._data.getvalue()
89
91 """Write a line to the xml.
92 This method honors the current indentation.
93 """
94 self._data.write('%s%s\n' % (self._indentChar * self._indent,
95 line.encode('utf8')))
96
97 - def writeTag(self, tagName, attributes=None, data=None):
98 """Writes out and closes a tag. Optionally writes data as a child node.
99 @param tagName: name of the tag
100 @param attributes: attributes or None
101 @param data: data or None
102 """
103 if attributes is None:
104 attributes = []
105 prefix = '<%s' % (tagName, )
106 if data is not None:
107 suffix = '>%s</%s>' % (data, tagName)
108 else:
109 suffix = '/>'
110 attrs = self._collectAttributes(
111 attributes, len(prefix) + len(suffix))
112 self.writeLine(prefix + attrs + suffix)
113
114 - def pushTag(self, tagName, attributes=None):
115 """Push a tag::
116 - writes the tag and the attributes
117 - increase the indentation for subsequent calls
118 @param tagName: name of the tag to write
119 @type tagName: string
120 @param attributes: attributes to write
121 @type attributes: list of 2 sizes tuples; (name, value)
122 """
123 self._openTag(tagName, attributes)
124 self._tagStack.append(tagName)
125 self._indent += self._indentUnit
126
128 """Decreases the indentation and closes the previously opened tag.
129 @returns: name of the closed tag
130 """
131 self._indent -= self._indentUnit
132 tagName = self._tagStack.pop()
133 self._closeTag(tagName)
134 return tagName
135
136
138 """Compare two component types the way they should be written in an xml
139 file. Suitable for using as cmp argument to list.sort() or sorted().
140 @param aType: first component type
141 @type aType:
142 @param bType: second component type
143 @type bType:
144 @returns: -1, 0 or 1, see L{__builtin__.cmp}
145 """
146 for suffix in ['-producer',
147 '-converter',
148 '-encoder',
149 '-muxer',
150 '-streamer']:
151 bHasSuffix = bType.endswith(suffix)
152 if aType.endswith(suffix):
153 if bHasSuffix:
154 return cmp(aType, bType)
155 else:
156 return -1
157 elif bHasSuffix:
158 return 1
159 return cmp(aType, bType)
160