|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2010 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a base class for all of eric6s XML stream writers. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 try: |
|
12 str = unicode |
|
13 except NameError: |
|
14 pass |
|
15 |
|
16 import sys |
|
17 import pickle |
|
18 import base64 |
|
19 |
|
20 from PyQt5.QtCore import QXmlStreamWriter |
|
21 |
|
22 |
|
23 class XMLStreamWriterBase(QXmlStreamWriter): |
|
24 """ |
|
25 Class implementing a base class for all of eric6s XML stream writers. |
|
26 """ |
|
27 def __init__(self, device): |
|
28 """ |
|
29 Constructor |
|
30 |
|
31 @param device reference to the I/O device to write to (QIODevice) |
|
32 """ |
|
33 super(XMLStreamWriterBase, self).__init__(device) |
|
34 |
|
35 self.basics = { |
|
36 type(None): self._write_none, |
|
37 int: self._write_int, |
|
38 float: self._write_float, |
|
39 complex: self._write_complex, |
|
40 bool: self._write_bool, |
|
41 str: self._write_string, |
|
42 bytearray: self._write_bytearray, |
|
43 tuple: self._write_tuple, |
|
44 list: self._write_list, |
|
45 dict: self._write_dictionary, |
|
46 set: self._write_set, |
|
47 frozenset: self._write_frozenset, |
|
48 } |
|
49 # 'bytes' is identical to 'str' in Py2 |
|
50 if sys.version_info[0] >= 3: |
|
51 self.basics[bytes] = self._write_bytes |
|
52 |
|
53 self.setAutoFormatting(True) |
|
54 self.setAutoFormattingIndent(2) |
|
55 |
|
56 def writeXML(self): |
|
57 """ |
|
58 Public method to write the XML to the file. |
|
59 """ |
|
60 # write the XML header |
|
61 self.writeStartDocument() |
|
62 |
|
63 def writeBasics(self, tag, pyobject): |
|
64 """ |
|
65 Public method to write a tag with a basic Python object dump. |
|
66 |
|
67 @param tag tag name (string) |
|
68 @param pyobject object to be dumped |
|
69 """ |
|
70 self.writeStartElement(tag) |
|
71 self._writeBasics(pyobject) |
|
72 self.writeEndElement() |
|
73 |
|
74 def _writeBasics(self, pyobject): |
|
75 """ |
|
76 Protected method to dump an object of a basic Python type. |
|
77 |
|
78 @param pyobject object to be dumped |
|
79 """ |
|
80 writeMethod = self.basics.get(type(pyobject)) or \ |
|
81 self._write_unimplemented |
|
82 writeMethod(pyobject) |
|
83 |
|
84 ########################################################################### |
|
85 ## The various writer methods for basic types |
|
86 ########################################################################### |
|
87 |
|
88 def _write_none(self, value): |
|
89 """ |
|
90 Protected method to dump a NoneType object. |
|
91 |
|
92 @param value value to be dumped (None) (ignored) |
|
93 """ |
|
94 self.writeEmptyElement("none") |
|
95 |
|
96 def _write_int(self, value): |
|
97 """ |
|
98 Protected method to dump an int object. |
|
99 |
|
100 @param value value to be dumped (integer) |
|
101 """ |
|
102 self.writeTextElement("int", str(value)) |
|
103 |
|
104 def _write_bool(self, value): |
|
105 """ |
|
106 Protected method to dump a bool object. |
|
107 |
|
108 @param value value to be dumped (boolean) |
|
109 """ |
|
110 self.writeTextElement("bool", str(value)) |
|
111 |
|
112 def _write_float(self, value): |
|
113 """ |
|
114 Protected method to dump a float object. |
|
115 |
|
116 @param value value to be dumped (float) |
|
117 """ |
|
118 self.writeTextElement("float", str(value)) |
|
119 |
|
120 def _write_complex(self, value): |
|
121 """ |
|
122 Protected method to dump a complex object. |
|
123 |
|
124 @param value value to be dumped (complex) |
|
125 """ |
|
126 self.writeTextElement("complex", '{0} {1}'.format( |
|
127 value.real, value.imag)) |
|
128 |
|
129 def _write_string(self, value): |
|
130 """ |
|
131 Protected method to dump a str object. |
|
132 |
|
133 @param value value to be dumped (string) |
|
134 """ |
|
135 self.writeTextElement("string", str(value)) |
|
136 |
|
137 def _write_bytes(self, value): |
|
138 """ |
|
139 Protected method to dump a bytes object. |
|
140 |
|
141 @param value value to be dumped (bytes) |
|
142 """ |
|
143 self.writeTextElement( |
|
144 "bytes", ",".join(["{0:d}".format(b) for b in value])) |
|
145 |
|
146 def _write_bytearray(self, value): |
|
147 """ |
|
148 Protected method to dump a bytearray object. |
|
149 |
|
150 @param value value to be dumped (bytearray) |
|
151 """ |
|
152 self.writeTextElement( |
|
153 "bytearray", ",".join(["{0:d}".format(b) for b in value])) |
|
154 |
|
155 def _write_tuple(self, value): |
|
156 """ |
|
157 Protected method to dump a tuple object. |
|
158 |
|
159 @param value value to be dumped (tuple) |
|
160 """ |
|
161 self.writeStartElement("tuple") |
|
162 for elem in value: |
|
163 self._writeBasics(elem) |
|
164 self.writeEndElement() |
|
165 |
|
166 def _write_list(self, value): |
|
167 """ |
|
168 Protected method to dump a list object. |
|
169 |
|
170 @param value value to be dumped (list) |
|
171 """ |
|
172 self.writeStartElement("list") |
|
173 for elem in value: |
|
174 self._writeBasics(elem) |
|
175 self.writeEndElement() |
|
176 |
|
177 def _write_dictionary(self, value): |
|
178 """ |
|
179 Protected method to dump a dict object. |
|
180 |
|
181 @param value value to be dumped (dictionary) |
|
182 """ |
|
183 self.writeStartElement("dict") |
|
184 try: |
|
185 keys = sorted(list(value.keys())) |
|
186 except TypeError: |
|
187 keys = list(value.keys()) |
|
188 for key in keys: |
|
189 self.writeStartElement("key") |
|
190 self._writeBasics(key) |
|
191 self.writeEndElement() |
|
192 |
|
193 self.writeStartElement("value") |
|
194 self._writeBasics(value[key]) |
|
195 self.writeEndElement() |
|
196 self.writeEndElement() |
|
197 |
|
198 def _write_set(self, value): |
|
199 """ |
|
200 Protected method to dump a set object. |
|
201 |
|
202 @param value value to be dumped (set) |
|
203 """ |
|
204 self.writeStartElement("set") |
|
205 for elem in value: |
|
206 self._writeBasics(elem) |
|
207 self.writeEndElement() |
|
208 |
|
209 def _write_frozenset(self, value): |
|
210 """ |
|
211 Protected method to dump a frozenset object. |
|
212 |
|
213 @param value value to be dumped (frozenset) |
|
214 """ |
|
215 self.writeStartElement("frozenset") |
|
216 for elem in value: |
|
217 self._writeBasics(elem) |
|
218 self.writeEndElement() |
|
219 |
|
220 def _write_unimplemented(self, value): |
|
221 """ |
|
222 Protected method to dump a type, that has no special method. |
|
223 |
|
224 @param value value to be dumped (any pickleable object) |
|
225 """ |
|
226 self.writeStartElement("pickle") |
|
227 self.writeAttribute("method", "pickle") |
|
228 self.writeAttribute("encoding", "base64") |
|
229 self.writeCharacters( |
|
230 str(base64.b64encode(pickle.dumps(value)), "ASCII")) |
|
231 self.writeEndElement() |