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