|
1 |
|
2 import yaml |
|
3 |
|
4 def get_version_string(): |
|
5 return yaml_get_version_string() |
|
6 |
|
7 def get_version(): |
|
8 cdef int major, minor, patch |
|
9 yaml_get_version(&major, &minor, &patch) |
|
10 return (major, minor, patch) |
|
11 |
|
12 #Mark = yaml.error.Mark |
|
13 YAMLError = yaml.error.YAMLError |
|
14 ReaderError = yaml.reader.ReaderError |
|
15 ScannerError = yaml.scanner.ScannerError |
|
16 ParserError = yaml.parser.ParserError |
|
17 ComposerError = yaml.composer.ComposerError |
|
18 ConstructorError = yaml.constructor.ConstructorError |
|
19 EmitterError = yaml.emitter.EmitterError |
|
20 SerializerError = yaml.serializer.SerializerError |
|
21 RepresenterError = yaml.representer.RepresenterError |
|
22 |
|
23 StreamStartToken = yaml.tokens.StreamStartToken |
|
24 StreamEndToken = yaml.tokens.StreamEndToken |
|
25 DirectiveToken = yaml.tokens.DirectiveToken |
|
26 DocumentStartToken = yaml.tokens.DocumentStartToken |
|
27 DocumentEndToken = yaml.tokens.DocumentEndToken |
|
28 BlockSequenceStartToken = yaml.tokens.BlockSequenceStartToken |
|
29 BlockMappingStartToken = yaml.tokens.BlockMappingStartToken |
|
30 BlockEndToken = yaml.tokens.BlockEndToken |
|
31 FlowSequenceStartToken = yaml.tokens.FlowSequenceStartToken |
|
32 FlowMappingStartToken = yaml.tokens.FlowMappingStartToken |
|
33 FlowSequenceEndToken = yaml.tokens.FlowSequenceEndToken |
|
34 FlowMappingEndToken = yaml.tokens.FlowMappingEndToken |
|
35 KeyToken = yaml.tokens.KeyToken |
|
36 ValueToken = yaml.tokens.ValueToken |
|
37 BlockEntryToken = yaml.tokens.BlockEntryToken |
|
38 FlowEntryToken = yaml.tokens.FlowEntryToken |
|
39 AliasToken = yaml.tokens.AliasToken |
|
40 AnchorToken = yaml.tokens.AnchorToken |
|
41 TagToken = yaml.tokens.TagToken |
|
42 ScalarToken = yaml.tokens.ScalarToken |
|
43 |
|
44 StreamStartEvent = yaml.events.StreamStartEvent |
|
45 StreamEndEvent = yaml.events.StreamEndEvent |
|
46 DocumentStartEvent = yaml.events.DocumentStartEvent |
|
47 DocumentEndEvent = yaml.events.DocumentEndEvent |
|
48 AliasEvent = yaml.events.AliasEvent |
|
49 ScalarEvent = yaml.events.ScalarEvent |
|
50 SequenceStartEvent = yaml.events.SequenceStartEvent |
|
51 SequenceEndEvent = yaml.events.SequenceEndEvent |
|
52 MappingStartEvent = yaml.events.MappingStartEvent |
|
53 MappingEndEvent = yaml.events.MappingEndEvent |
|
54 |
|
55 ScalarNode = yaml.nodes.ScalarNode |
|
56 SequenceNode = yaml.nodes.SequenceNode |
|
57 MappingNode = yaml.nodes.MappingNode |
|
58 |
|
59 cdef class Mark: |
|
60 cdef readonly object name |
|
61 cdef readonly int index |
|
62 cdef readonly int line |
|
63 cdef readonly int column |
|
64 cdef readonly buffer |
|
65 cdef readonly pointer |
|
66 |
|
67 def __init__(self, object name, int index, int line, int column, |
|
68 object buffer, object pointer): |
|
69 self.name = name |
|
70 self.index = index |
|
71 self.line = line |
|
72 self.column = column |
|
73 self.buffer = buffer |
|
74 self.pointer = pointer |
|
75 |
|
76 def get_snippet(self): |
|
77 return None |
|
78 |
|
79 def __str__(self): |
|
80 where = " in \"%s\", line %d, column %d" \ |
|
81 % (self.name, self.line+1, self.column+1) |
|
82 return where |
|
83 |
|
84 #class YAMLError(Exception): |
|
85 # pass |
|
86 # |
|
87 #class MarkedYAMLError(YAMLError): |
|
88 # |
|
89 # def __init__(self, context=None, context_mark=None, |
|
90 # problem=None, problem_mark=None, note=None): |
|
91 # self.context = context |
|
92 # self.context_mark = context_mark |
|
93 # self.problem = problem |
|
94 # self.problem_mark = problem_mark |
|
95 # self.note = note |
|
96 # |
|
97 # def __str__(self): |
|
98 # lines = [] |
|
99 # if self.context is not None: |
|
100 # lines.append(self.context) |
|
101 # if self.context_mark is not None \ |
|
102 # and (self.problem is None or self.problem_mark is None |
|
103 # or self.context_mark.name != self.problem_mark.name |
|
104 # or self.context_mark.line != self.problem_mark.line |
|
105 # or self.context_mark.column != self.problem_mark.column): |
|
106 # lines.append(str(self.context_mark)) |
|
107 # if self.problem is not None: |
|
108 # lines.append(self.problem) |
|
109 # if self.problem_mark is not None: |
|
110 # lines.append(str(self.problem_mark)) |
|
111 # if self.note is not None: |
|
112 # lines.append(self.note) |
|
113 # return '\n'.join(lines) |
|
114 # |
|
115 #class ReaderError(YAMLError): |
|
116 # |
|
117 # def __init__(self, name, position, character, encoding, reason): |
|
118 # self.name = name |
|
119 # self.character = character |
|
120 # self.position = position |
|
121 # self.encoding = encoding |
|
122 # self.reason = reason |
|
123 # |
|
124 # def __str__(self): |
|
125 # if isinstance(self.character, str): |
|
126 # return "'%s' codec can't decode byte #x%02x: %s\n" \ |
|
127 # " in \"%s\", position %d" \ |
|
128 # % (self.encoding, ord(self.character), self.reason, |
|
129 # self.name, self.position) |
|
130 # else: |
|
131 # return "unacceptable character #x%04x: %s\n" \ |
|
132 # " in \"%s\", position %d" \ |
|
133 # % (ord(self.character), self.reason, |
|
134 # self.name, self.position) |
|
135 # |
|
136 #class ScannerError(MarkedYAMLError): |
|
137 # pass |
|
138 # |
|
139 #class ParserError(MarkedYAMLError): |
|
140 # pass |
|
141 # |
|
142 #class EmitterError(YAMLError): |
|
143 # pass |
|
144 # |
|
145 #cdef class Token: |
|
146 # cdef readonly Mark start_mark |
|
147 # cdef readonly Mark end_mark |
|
148 # def __init__(self, Mark start_mark, Mark end_mark): |
|
149 # self.start_mark = start_mark |
|
150 # self.end_mark = end_mark |
|
151 # |
|
152 #cdef class StreamStartToken(Token): |
|
153 # cdef readonly object encoding |
|
154 # def __init__(self, Mark start_mark, Mark end_mark, encoding): |
|
155 # self.start_mark = start_mark |
|
156 # self.end_mark = end_mark |
|
157 # self.encoding = encoding |
|
158 # |
|
159 #cdef class StreamEndToken(Token): |
|
160 # pass |
|
161 # |
|
162 #cdef class DirectiveToken(Token): |
|
163 # cdef readonly object name |
|
164 # cdef readonly object value |
|
165 # def __init__(self, name, value, Mark start_mark, Mark end_mark): |
|
166 # self.name = name |
|
167 # self.value = value |
|
168 # self.start_mark = start_mark |
|
169 # self.end_mark = end_mark |
|
170 # |
|
171 #cdef class DocumentStartToken(Token): |
|
172 # pass |
|
173 # |
|
174 #cdef class DocumentEndToken(Token): |
|
175 # pass |
|
176 # |
|
177 #cdef class BlockSequenceStartToken(Token): |
|
178 # pass |
|
179 # |
|
180 #cdef class BlockMappingStartToken(Token): |
|
181 # pass |
|
182 # |
|
183 #cdef class BlockEndToken(Token): |
|
184 # pass |
|
185 # |
|
186 #cdef class FlowSequenceStartToken(Token): |
|
187 # pass |
|
188 # |
|
189 #cdef class FlowMappingStartToken(Token): |
|
190 # pass |
|
191 # |
|
192 #cdef class FlowSequenceEndToken(Token): |
|
193 # pass |
|
194 # |
|
195 #cdef class FlowMappingEndToken(Token): |
|
196 # pass |
|
197 # |
|
198 #cdef class KeyToken(Token): |
|
199 # pass |
|
200 # |
|
201 #cdef class ValueToken(Token): |
|
202 # pass |
|
203 # |
|
204 #cdef class BlockEntryToken(Token): |
|
205 # pass |
|
206 # |
|
207 #cdef class FlowEntryToken(Token): |
|
208 # pass |
|
209 # |
|
210 #cdef class AliasToken(Token): |
|
211 # cdef readonly object value |
|
212 # def __init__(self, value, Mark start_mark, Mark end_mark): |
|
213 # self.value = value |
|
214 # self.start_mark = start_mark |
|
215 # self.end_mark = end_mark |
|
216 # |
|
217 #cdef class AnchorToken(Token): |
|
218 # cdef readonly object value |
|
219 # def __init__(self, value, Mark start_mark, Mark end_mark): |
|
220 # self.value = value |
|
221 # self.start_mark = start_mark |
|
222 # self.end_mark = end_mark |
|
223 # |
|
224 #cdef class TagToken(Token): |
|
225 # cdef readonly object value |
|
226 # def __init__(self, value, Mark start_mark, Mark end_mark): |
|
227 # self.value = value |
|
228 # self.start_mark = start_mark |
|
229 # self.end_mark = end_mark |
|
230 # |
|
231 #cdef class ScalarToken(Token): |
|
232 # cdef readonly object value |
|
233 # cdef readonly object plain |
|
234 # cdef readonly object style |
|
235 # def __init__(self, value, plain, Mark start_mark, Mark end_mark, style=None): |
|
236 # self.value = value |
|
237 # self.plain = plain |
|
238 # self.start_mark = start_mark |
|
239 # self.end_mark = end_mark |
|
240 # self.style = style |
|
241 |
|
242 cdef class CParser: |
|
243 |
|
244 cdef yaml_parser_t parser |
|
245 cdef yaml_event_t parsed_event |
|
246 |
|
247 cdef object stream |
|
248 cdef object stream_name |
|
249 cdef object current_token |
|
250 cdef object current_event |
|
251 cdef object anchors |
|
252 |
|
253 def __init__(self, stream): |
|
254 if yaml_parser_initialize(&self.parser) == 0: |
|
255 raise MemoryError |
|
256 self.parsed_event.type = YAML_NO_EVENT |
|
257 if hasattr(stream, 'read'): |
|
258 self.stream = stream |
|
259 try: |
|
260 self.stream_name = stream.name |
|
261 except AttributeError: |
|
262 self.stream_name = '<file>' |
|
263 yaml_parser_set_input(&self.parser, input_handler, <void *>self) |
|
264 else: |
|
265 if PyUnicode_CheckExact(stream) != 0: |
|
266 stream = PyUnicode_AsUTF8String(stream) |
|
267 self.stream_name = '<unicode string>' |
|
268 else: |
|
269 self.stream_name = '<string>' |
|
270 if PyString_CheckExact(stream) == 0: |
|
271 raise TypeError("a string or stream input is required") |
|
272 self.stream = stream |
|
273 yaml_parser_set_input_string(&self.parser, PyString_AS_STRING(stream), PyString_GET_SIZE(stream)) |
|
274 self.current_token = None |
|
275 self.current_event = None |
|
276 self.anchors = {} |
|
277 |
|
278 def __dealloc__(self): |
|
279 yaml_parser_delete(&self.parser) |
|
280 yaml_event_delete(&self.parsed_event) |
|
281 |
|
282 cdef object _parser_error(self): |
|
283 if self.parser.error == YAML_MEMORY_ERROR: |
|
284 raise MemoryError |
|
285 elif self.parser.error == YAML_READER_ERROR: |
|
286 raise ReaderError(self.stream_name, self.parser.problem_offset, |
|
287 self.parser.problem_value, '?', self.parser.problem) |
|
288 elif self.parser.error == YAML_SCANNER_ERROR \ |
|
289 or self.parser.error == YAML_PARSER_ERROR: |
|
290 context_mark = None |
|
291 problem_mark = None |
|
292 if self.parser.context != NULL: |
|
293 context_mark = Mark(self.stream_name, |
|
294 self.parser.context_mark.index, |
|
295 self.parser.context_mark.line, |
|
296 self.parser.context_mark.column, None, None) |
|
297 if self.parser.problem != NULL: |
|
298 problem_mark = Mark(self.stream_name, |
|
299 self.parser.problem_mark.index, |
|
300 self.parser.problem_mark.line, |
|
301 self.parser.problem_mark.column, None, None) |
|
302 if self.parser.error == YAML_SCANNER_ERROR: |
|
303 if self.parser.context != NULL: |
|
304 return ScannerError(self.parser.context, context_mark, |
|
305 self.parser.problem, problem_mark) |
|
306 else: |
|
307 return ScannerError(None, None, |
|
308 self.parser.problem, problem_mark) |
|
309 else: |
|
310 if self.parser.context != NULL: |
|
311 return ParserError(self.parser.context, context_mark, |
|
312 self.parser.problem, problem_mark) |
|
313 else: |
|
314 return ParserError(None, None, |
|
315 self.parser.problem, problem_mark) |
|
316 raise ValueError("no parser error") |
|
317 |
|
318 def raw_scan(self): |
|
319 cdef yaml_token_t token |
|
320 cdef int done |
|
321 cdef int count |
|
322 count = 0 |
|
323 done = 0 |
|
324 while done == 0: |
|
325 if yaml_parser_scan(&self.parser, &token) == 0: |
|
326 error = self._parser_error() |
|
327 raise error |
|
328 if token.type == YAML_NO_TOKEN: |
|
329 done = 1 |
|
330 else: |
|
331 count = count+1 |
|
332 yaml_token_delete(&token) |
|
333 return count |
|
334 |
|
335 cdef object _scan(self): |
|
336 cdef yaml_token_t token |
|
337 if yaml_parser_scan(&self.parser, &token) == 0: |
|
338 error = self._parser_error() |
|
339 raise error |
|
340 token_object = self._token_to_object(&token) |
|
341 yaml_token_delete(&token) |
|
342 return token_object |
|
343 |
|
344 cdef object _token_to_object(self, yaml_token_t *token): |
|
345 start_mark = Mark(self.stream_name, |
|
346 token.start_mark.index, |
|
347 token.start_mark.line, |
|
348 token.start_mark.column, |
|
349 None, None) |
|
350 end_mark = Mark(self.stream_name, |
|
351 token.end_mark.index, |
|
352 token.end_mark.line, |
|
353 token.end_mark.column, |
|
354 None, None) |
|
355 if token.type == YAML_NO_TOKEN: |
|
356 return None |
|
357 elif token.type == YAML_STREAM_START_TOKEN: |
|
358 encoding = None |
|
359 if token.data.stream_start.encoding == YAML_UTF8_ENCODING: |
|
360 encoding = "utf-8" |
|
361 elif token.data.stream_start.encoding == YAML_UTF16LE_ENCODING: |
|
362 encoding = "utf-16-le" |
|
363 elif token.data.stream_start.encoding == YAML_UTF16BE_ENCODING: |
|
364 encoding = "utf-16-be" |
|
365 return StreamStartToken(start_mark, end_mark, encoding) |
|
366 elif token.type == YAML_STREAM_END_TOKEN: |
|
367 return StreamEndToken(start_mark, end_mark) |
|
368 elif token.type == YAML_VERSION_DIRECTIVE_TOKEN: |
|
369 return DirectiveToken("YAML", |
|
370 (token.data.version_directive.major, |
|
371 token.data.version_directive.minor), |
|
372 start_mark, end_mark) |
|
373 elif token.type == YAML_TAG_DIRECTIVE_TOKEN: |
|
374 return DirectiveToken("TAG", |
|
375 (token.data.tag_directive.handle, |
|
376 token.data.tag_directive.prefix), |
|
377 start_mark, end_mark) |
|
378 elif token.type == YAML_DOCUMENT_START_TOKEN: |
|
379 return DocumentStartToken(start_mark, end_mark) |
|
380 elif token.type == YAML_DOCUMENT_END_TOKEN: |
|
381 return DocumentEndToken(start_mark, end_mark) |
|
382 elif token.type == YAML_BLOCK_SEQUENCE_START_TOKEN: |
|
383 return BlockSequenceStartToken(start_mark, end_mark) |
|
384 elif token.type == YAML_BLOCK_MAPPING_START_TOKEN: |
|
385 return BlockMappingStartToken(start_mark, end_mark) |
|
386 elif token.type == YAML_BLOCK_END_TOKEN: |
|
387 return BlockEndToken(start_mark, end_mark) |
|
388 elif token.type == YAML_FLOW_SEQUENCE_START_TOKEN: |
|
389 return FlowSequenceStartToken(start_mark, end_mark) |
|
390 elif token.type == YAML_FLOW_SEQUENCE_END_TOKEN: |
|
391 return FlowSequenceEndToken(start_mark, end_mark) |
|
392 elif token.type == YAML_FLOW_MAPPING_START_TOKEN: |
|
393 return FlowMappingStartToken(start_mark, end_mark) |
|
394 elif token.type == YAML_FLOW_MAPPING_END_TOKEN: |
|
395 return FlowMappingEndToken(start_mark, end_mark) |
|
396 elif token.type == YAML_BLOCK_ENTRY_TOKEN: |
|
397 return BlockEntryToken(start_mark, end_mark) |
|
398 elif token.type == YAML_FLOW_ENTRY_TOKEN: |
|
399 return FlowEntryToken(start_mark, end_mark) |
|
400 elif token.type == YAML_KEY_TOKEN: |
|
401 return KeyToken(start_mark, end_mark) |
|
402 elif token.type == YAML_VALUE_TOKEN: |
|
403 return ValueToken(start_mark, end_mark) |
|
404 elif token.type == YAML_ALIAS_TOKEN: |
|
405 value = PyUnicode_DecodeUTF8(token.data.alias.value, |
|
406 strlen(token.data.alias.value), 'strict') |
|
407 return AliasToken(value, start_mark, end_mark) |
|
408 elif token.type == YAML_ANCHOR_TOKEN: |
|
409 value = PyUnicode_DecodeUTF8(token.data.anchor.value, |
|
410 strlen(token.data.anchor.value), 'strict') |
|
411 return AnchorToken(value, start_mark, end_mark) |
|
412 elif token.type == YAML_TAG_TOKEN: |
|
413 handle = PyUnicode_DecodeUTF8(token.data.tag.handle, |
|
414 strlen(token.data.tag.handle), 'strict') |
|
415 suffix = PyUnicode_DecodeUTF8(token.data.tag.suffix, |
|
416 strlen(token.data.tag.suffix), 'strict') |
|
417 if not handle: |
|
418 handle = None |
|
419 return TagToken((handle, suffix), start_mark, end_mark) |
|
420 elif token.type == YAML_SCALAR_TOKEN: |
|
421 value = PyUnicode_DecodeUTF8(token.data.scalar.value, |
|
422 token.data.scalar.length, 'strict') |
|
423 plain = False |
|
424 style = None |
|
425 if token.data.scalar.style == YAML_PLAIN_SCALAR_STYLE: |
|
426 plain = True |
|
427 style = '' |
|
428 elif token.data.scalar.style == YAML_SINGLE_QUOTED_SCALAR_STYLE: |
|
429 style = '\'' |
|
430 elif token.data.scalar.style == YAML_DOUBLE_QUOTED_SCALAR_STYLE: |
|
431 style = '"' |
|
432 elif token.data.scalar.style == YAML_LITERAL_SCALAR_STYLE: |
|
433 style = '|' |
|
434 elif token.data.scalar.style == YAML_FOLDED_SCALAR_STYLE: |
|
435 style = '>' |
|
436 return ScalarToken(value, plain, |
|
437 start_mark, end_mark, style) |
|
438 else: |
|
439 raise ValueError("unknown token type") |
|
440 |
|
441 def get_token(self): |
|
442 if self.current_token is not None: |
|
443 value = self.current_token |
|
444 self.current_token = None |
|
445 else: |
|
446 value = self._scan() |
|
447 return value |
|
448 |
|
449 def peek_token(self): |
|
450 if self.current_token is None: |
|
451 self.current_token = self._scan() |
|
452 return self.current_token |
|
453 |
|
454 def check_token(self, *choices): |
|
455 if self.current_token is None: |
|
456 self.current_token = self._scan() |
|
457 if self.current_token is None: |
|
458 return False |
|
459 if not choices: |
|
460 return True |
|
461 token_class = self.current_token.__class__ |
|
462 for choice in choices: |
|
463 if token_class is choice: |
|
464 return True |
|
465 return False |
|
466 |
|
467 def raw_parse(self): |
|
468 cdef yaml_event_t event |
|
469 cdef int done |
|
470 cdef int count |
|
471 count = 0 |
|
472 done = 0 |
|
473 while done == 0: |
|
474 if yaml_parser_parse(&self.parser, &event) == 0: |
|
475 error = self._parser_error() |
|
476 raise error |
|
477 if event.type == YAML_NO_EVENT: |
|
478 done = 1 |
|
479 else: |
|
480 count = count+1 |
|
481 yaml_event_delete(&event) |
|
482 return count |
|
483 |
|
484 cdef object _parse(self): |
|
485 cdef yaml_event_t event |
|
486 if yaml_parser_parse(&self.parser, &event) == 0: |
|
487 error = self._parser_error() |
|
488 raise error |
|
489 event_object = self._event_to_object(&event) |
|
490 yaml_event_delete(&event) |
|
491 return event_object |
|
492 |
|
493 cdef object _event_to_object(self, yaml_event_t *event): |
|
494 cdef yaml_tag_directive_t *tag_directive |
|
495 start_mark = Mark(self.stream_name, |
|
496 event.start_mark.index, |
|
497 event.start_mark.line, |
|
498 event.start_mark.column, |
|
499 None, None) |
|
500 end_mark = Mark(self.stream_name, |
|
501 event.end_mark.index, |
|
502 event.end_mark.line, |
|
503 event.end_mark.column, |
|
504 None, None) |
|
505 if event.type == YAML_NO_EVENT: |
|
506 return None |
|
507 elif event.type == YAML_STREAM_START_EVENT: |
|
508 encoding = None |
|
509 if event.data.stream_start.encoding == YAML_UTF8_ENCODING: |
|
510 encoding = "utf-8" |
|
511 elif event.data.stream_start.encoding == YAML_UTF16LE_ENCODING: |
|
512 encoding = "utf-16-le" |
|
513 elif event.data.stream_start.encoding == YAML_UTF16BE_ENCODING: |
|
514 encoding = "utf-16-be" |
|
515 return StreamStartEvent(start_mark, end_mark, encoding) |
|
516 elif event.type == YAML_STREAM_END_EVENT: |
|
517 return StreamEndEvent(start_mark, end_mark) |
|
518 |
|
519 elif event.type == YAML_DOCUMENT_START_EVENT: |
|
520 explicit = False |
|
521 if event.data.document_start.implicit == 0: |
|
522 explicit = True |
|
523 version = None |
|
524 if event.data.document_start.version_directive != NULL: |
|
525 version = (event.data.document_start.version_directive.major, |
|
526 event.data.document_start.version_directive.minor) |
|
527 tags = None |
|
528 if event.data.document_start.tag_directives.start != NULL: |
|
529 tags = {} |
|
530 tag_directive = event.data.document_start.tag_directives.start |
|
531 while tag_directive != event.data.document_start.tag_directives.end: |
|
532 handle = PyUnicode_DecodeUTF8(tag_directive.handle, |
|
533 strlen(tag_directive.handle), 'strict') |
|
534 prefix = PyUnicode_DecodeUTF8(tag_directive.prefix, |
|
535 strlen(tag_directive.prefix), 'strict') |
|
536 tags[handle] = prefix |
|
537 tag_directive = tag_directive+1 |
|
538 return DocumentStartEvent(start_mark, end_mark, |
|
539 explicit, version, tags) |
|
540 elif event.type == YAML_DOCUMENT_END_EVENT: |
|
541 explicit = False |
|
542 if event.data.document_end.implicit == 0: |
|
543 explicit = True |
|
544 return DocumentEndEvent(start_mark, end_mark, explicit) |
|
545 elif event.type == YAML_ALIAS_EVENT: |
|
546 anchor = PyUnicode_DecodeUTF8(event.data.alias.anchor, |
|
547 strlen(event.data.alias.anchor), 'strict') |
|
548 return AliasEvent(anchor, start_mark, end_mark) |
|
549 elif event.type == YAML_SCALAR_EVENT: |
|
550 anchor = None |
|
551 if event.data.scalar.anchor != NULL: |
|
552 anchor = PyUnicode_DecodeUTF8(event.data.scalar.anchor, |
|
553 strlen(event.data.scalar.anchor), 'strict') |
|
554 tag = None |
|
555 if event.data.scalar.tag != NULL: |
|
556 tag = PyUnicode_DecodeUTF8(event.data.scalar.tag, |
|
557 strlen(event.data.scalar.tag), 'strict') |
|
558 value = PyUnicode_DecodeUTF8(event.data.scalar.value, |
|
559 event.data.scalar.length, 'strict') |
|
560 plain_implicit = False |
|
561 if event.data.scalar.plain_implicit == 1: |
|
562 plain_implicit = True |
|
563 quoted_implicit = False |
|
564 if event.data.scalar.quoted_implicit == 1: |
|
565 quoted_implicit = True |
|
566 style = None |
|
567 if event.data.scalar.style == YAML_PLAIN_SCALAR_STYLE: |
|
568 style = '' |
|
569 elif event.data.scalar.style == YAML_SINGLE_QUOTED_SCALAR_STYLE: |
|
570 style = '\'' |
|
571 elif event.data.scalar.style == YAML_DOUBLE_QUOTED_SCALAR_STYLE: |
|
572 style = '"' |
|
573 elif event.data.scalar.style == YAML_LITERAL_SCALAR_STYLE: |
|
574 style = '|' |
|
575 elif event.data.scalar.style == YAML_FOLDED_SCALAR_STYLE: |
|
576 style = '>' |
|
577 return ScalarEvent(anchor, tag, |
|
578 (plain_implicit, quoted_implicit), |
|
579 value, start_mark, end_mark, style) |
|
580 elif event.type == YAML_SEQUENCE_START_EVENT: |
|
581 anchor = None |
|
582 if event.data.sequence_start.anchor != NULL: |
|
583 anchor = PyUnicode_DecodeUTF8(event.data.sequence_start.anchor, |
|
584 strlen(event.data.sequence_start.anchor), 'strict') |
|
585 tag = None |
|
586 if event.data.sequence_start.tag != NULL: |
|
587 tag = PyUnicode_DecodeUTF8(event.data.sequence_start.tag, |
|
588 strlen(event.data.sequence_start.tag), 'strict') |
|
589 implicit = False |
|
590 if event.data.sequence_start.implicit == 1: |
|
591 implicit = True |
|
592 flow_style = None |
|
593 if event.data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE: |
|
594 flow_style = True |
|
595 elif event.data.sequence_start.style == YAML_BLOCK_SEQUENCE_STYLE: |
|
596 flow_style = False |
|
597 return SequenceStartEvent(anchor, tag, implicit, |
|
598 start_mark, end_mark, flow_style) |
|
599 elif event.type == YAML_MAPPING_START_EVENT: |
|
600 anchor = None |
|
601 if event.data.mapping_start.anchor != NULL: |
|
602 anchor = PyUnicode_DecodeUTF8(event.data.mapping_start.anchor, |
|
603 strlen(event.data.mapping_start.anchor), 'strict') |
|
604 tag = None |
|
605 if event.data.mapping_start.tag != NULL: |
|
606 tag = PyUnicode_DecodeUTF8(event.data.mapping_start.tag, |
|
607 strlen(event.data.mapping_start.tag), 'strict') |
|
608 implicit = False |
|
609 if event.data.mapping_start.implicit == 1: |
|
610 implicit = True |
|
611 flow_style = None |
|
612 if event.data.mapping_start.style == YAML_FLOW_SEQUENCE_STYLE: |
|
613 flow_style = True |
|
614 elif event.data.mapping_start.style == YAML_BLOCK_SEQUENCE_STYLE: |
|
615 flow_style = False |
|
616 return MappingStartEvent(anchor, tag, implicit, |
|
617 start_mark, end_mark, flow_style) |
|
618 elif event.type == YAML_SEQUENCE_END_EVENT: |
|
619 return SequenceEndEvent(start_mark, end_mark) |
|
620 elif event.type == YAML_MAPPING_END_EVENT: |
|
621 return MappingEndEvent(start_mark, end_mark) |
|
622 |
|
623 else: |
|
624 raise ValueError("unknown token type") |
|
625 |
|
626 def get_event(self): |
|
627 if self.current_event is not None: |
|
628 value = self.current_event |
|
629 self.current_event = None |
|
630 else: |
|
631 value = self._parse() |
|
632 return value |
|
633 |
|
634 def peek_event(self): |
|
635 if self.current_event is None: |
|
636 self.current_event = self._parse() |
|
637 return self.current_event |
|
638 |
|
639 def check_event(self, *choices): |
|
640 if self.current_event is None: |
|
641 self.current_event = self._parse() |
|
642 if self.current_event is None: |
|
643 return False |
|
644 if not choices: |
|
645 return True |
|
646 event_class = self.current_event.__class__ |
|
647 for choice in choices: |
|
648 if event_class is choice: |
|
649 return True |
|
650 return False |
|
651 |
|
652 def check_node(self): |
|
653 self._parse_next_event() |
|
654 if self.parsed_event.type == YAML_STREAM_START_EVENT: |
|
655 yaml_event_delete(&self.parsed_event) |
|
656 self._parse_next_event() |
|
657 if self.parsed_event.type != YAML_STREAM_END_EVENT: |
|
658 return True |
|
659 return False |
|
660 |
|
661 def get_node(self): |
|
662 self._parse_next_event() |
|
663 if self.parsed_event.type != YAML_STREAM_END_EVENT: |
|
664 return self._compose_document() |
|
665 |
|
666 cdef object _compose_document(self): |
|
667 yaml_event_delete(&self.parsed_event) |
|
668 node = self._compose_node(None, None) |
|
669 self._parse_next_event() |
|
670 yaml_event_delete(&self.parsed_event) |
|
671 self.anchors = {} |
|
672 return node |
|
673 |
|
674 cdef object _compose_node(self, object parent, object index): |
|
675 self._parse_next_event() |
|
676 if self.parsed_event.type == YAML_ALIAS_EVENT: |
|
677 anchor = PyUnicode_DecodeUTF8(self.parsed_event.data.alias.anchor, |
|
678 strlen(self.parsed_event.data.alias.anchor), 'strict') |
|
679 if anchor not in self.anchors: |
|
680 mark = Mark(self.stream_name, |
|
681 self.parsed_event.start_mark.index, |
|
682 self.parsed_event.start_mark.line, |
|
683 self.parsed_event.start_mark.column, |
|
684 None, None) |
|
685 raise ComposerError(None, None, "found undefined alias", mark) |
|
686 yaml_event_delete(&self.parsed_event) |
|
687 return self.anchors[anchor] |
|
688 anchor = None |
|
689 if self.parsed_event.type == YAML_SCALAR_EVENT \ |
|
690 and self.parsed_event.data.scalar.anchor != NULL: |
|
691 anchor = PyUnicode_DecodeUTF8(self.parsed_event.data.scalar.anchor, |
|
692 strlen(self.parsed_event.data.scalar.anchor), 'strict') |
|
693 elif self.parsed_event.type == YAML_SEQUENCE_START_EVENT \ |
|
694 and self.parsed_event.data.sequence_start.anchor != NULL: |
|
695 anchor = PyUnicode_DecodeUTF8(self.parsed_event.data.sequence_start.anchor, |
|
696 strlen(self.parsed_event.data.sequence_start.anchor), 'strict') |
|
697 elif self.parsed_event.type == YAML_MAPPING_START_EVENT \ |
|
698 and self.parsed_event.data.mapping_start.anchor != NULL: |
|
699 anchor = PyUnicode_DecodeUTF8(self.parsed_event.data.mapping_start.anchor, |
|
700 strlen(self.parsed_event.data.mapping_start.anchor), 'strict') |
|
701 if anchor is not None: |
|
702 if anchor in self.anchors: |
|
703 mark = Mark(self.stream_name, |
|
704 self.parsed_event.start_mark.index, |
|
705 self.parsed_event.start_mark.line, |
|
706 self.parsed_event.start_mark.column, |
|
707 None, None) |
|
708 raise ComposerError("found duplicate anchor; first occurence", |
|
709 self.anchors[anchor].start_mark, "second occurence", mark) |
|
710 self.descend_resolver(parent, index) |
|
711 if self.parsed_event.type == YAML_SCALAR_EVENT: |
|
712 node = self._compose_scalar_node(anchor) |
|
713 elif self.parsed_event.type == YAML_SEQUENCE_START_EVENT: |
|
714 node = self._compose_sequence_node(anchor) |
|
715 elif self.parsed_event.type == YAML_MAPPING_START_EVENT: |
|
716 node = self._compose_mapping_node(anchor) |
|
717 self.ascend_resolver() |
|
718 return node |
|
719 |
|
720 cdef _compose_scalar_node(self, object anchor): |
|
721 start_mark = Mark(self.stream_name, |
|
722 self.parsed_event.start_mark.index, |
|
723 self.parsed_event.start_mark.line, |
|
724 self.parsed_event.start_mark.column, |
|
725 None, None) |
|
726 end_mark = Mark(self.stream_name, |
|
727 self.parsed_event.end_mark.index, |
|
728 self.parsed_event.end_mark.line, |
|
729 self.parsed_event.end_mark.column, |
|
730 None, None) |
|
731 value = PyUnicode_DecodeUTF8(self.parsed_event.data.scalar.value, |
|
732 self.parsed_event.data.scalar.length, 'strict') |
|
733 plain_implicit = False |
|
734 if self.parsed_event.data.scalar.plain_implicit == 1: |
|
735 plain_implicit = True |
|
736 quoted_implicit = False |
|
737 if self.parsed_event.data.scalar.quoted_implicit == 1: |
|
738 quoted_implicit = True |
|
739 if self.parsed_event.data.scalar.tag == NULL \ |
|
740 or (self.parsed_event.data.scalar.tag[0] == c'!' |
|
741 and self.parsed_event.data.scalar.tag[1] == c'\0'): |
|
742 tag = self.resolve(ScalarNode, value, (plain_implicit, quoted_implicit)) |
|
743 else: |
|
744 tag = PyUnicode_DecodeUTF8(self.parsed_event.data.scalar.tag, |
|
745 strlen(self.parsed_event.data.scalar.tag), 'strict') |
|
746 style = None |
|
747 if self.parsed_event.data.scalar.style == YAML_PLAIN_SCALAR_STYLE: |
|
748 style = '' |
|
749 elif self.parsed_event.data.scalar.style == YAML_SINGLE_QUOTED_SCALAR_STYLE: |
|
750 style = '\'' |
|
751 elif self.parsed_event.data.scalar.style == YAML_DOUBLE_QUOTED_SCALAR_STYLE: |
|
752 style = '"' |
|
753 elif self.parsed_event.data.scalar.style == YAML_LITERAL_SCALAR_STYLE: |
|
754 style = '|' |
|
755 elif self.parsed_event.data.scalar.style == YAML_FOLDED_SCALAR_STYLE: |
|
756 style = '>' |
|
757 node = ScalarNode(tag, value, start_mark, end_mark, style) |
|
758 if anchor is not None: |
|
759 self.anchors[anchor] = node |
|
760 yaml_event_delete(&self.parsed_event) |
|
761 return node |
|
762 |
|
763 cdef _compose_sequence_node(self, object anchor): |
|
764 cdef int index |
|
765 start_mark = Mark(self.stream_name, |
|
766 self.parsed_event.start_mark.index, |
|
767 self.parsed_event.start_mark.line, |
|
768 self.parsed_event.start_mark.column, |
|
769 None, None) |
|
770 implicit = False |
|
771 if self.parsed_event.data.sequence_start.implicit == 1: |
|
772 implicit = True |
|
773 if self.parsed_event.data.sequence_start.tag == NULL \ |
|
774 or (self.parsed_event.data.sequence_start.tag[0] == c'!' |
|
775 and self.parsed_event.data.sequence_start.tag[1] == c'\0'): |
|
776 tag = self.resolve(SequenceNode, None, implicit) |
|
777 else: |
|
778 tag = PyUnicode_DecodeUTF8(self.parsed_event.data.sequence_start.tag, |
|
779 strlen(self.parsed_event.data.sequence_start.tag), 'strict') |
|
780 flow_style = None |
|
781 if self.parsed_event.data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE: |
|
782 flow_style = True |
|
783 elif self.parsed_event.data.sequence_start.style == YAML_BLOCK_SEQUENCE_STYLE: |
|
784 flow_style = False |
|
785 value = [] |
|
786 node = SequenceNode(tag, value, start_mark, None, flow_style) |
|
787 if anchor is not None: |
|
788 self.anchors[anchor] = node |
|
789 yaml_event_delete(&self.parsed_event) |
|
790 index = 0 |
|
791 self._parse_next_event() |
|
792 while self.parsed_event.type != YAML_SEQUENCE_END_EVENT: |
|
793 value.append(self._compose_node(node, index)) |
|
794 index = index+1 |
|
795 self._parse_next_event() |
|
796 node.end_mark = Mark(self.stream_name, |
|
797 self.parsed_event.end_mark.index, |
|
798 self.parsed_event.end_mark.line, |
|
799 self.parsed_event.end_mark.column, |
|
800 None, None) |
|
801 yaml_event_delete(&self.parsed_event) |
|
802 return node |
|
803 |
|
804 cdef _compose_mapping_node(self, object anchor): |
|
805 start_mark = Mark(self.stream_name, |
|
806 self.parsed_event.start_mark.index, |
|
807 self.parsed_event.start_mark.line, |
|
808 self.parsed_event.start_mark.column, |
|
809 None, None) |
|
810 implicit = False |
|
811 if self.parsed_event.data.mapping_start.implicit == 1: |
|
812 implicit = True |
|
813 if self.parsed_event.data.mapping_start.tag == NULL \ |
|
814 or (self.parsed_event.data.mapping_start.tag[0] == c'!' |
|
815 and self.parsed_event.data.mapping_start.tag[1] == c'\0'): |
|
816 tag = self.resolve(MappingNode, None, implicit) |
|
817 else: |
|
818 tag = PyUnicode_DecodeUTF8(self.parsed_event.data.mapping_start.tag, |
|
819 strlen(self.parsed_event.data.mapping_start.tag), 'strict') |
|
820 flow_style = None |
|
821 if self.parsed_event.data.mapping_start.style == YAML_FLOW_MAPPING_STYLE: |
|
822 flow_style = True |
|
823 elif self.parsed_event.data.mapping_start.style == YAML_BLOCK_MAPPING_STYLE: |
|
824 flow_style = False |
|
825 value = [] |
|
826 node = MappingNode(tag, value, start_mark, None, flow_style) |
|
827 if anchor is not None: |
|
828 self.anchors[anchor] = node |
|
829 yaml_event_delete(&self.parsed_event) |
|
830 self._parse_next_event() |
|
831 while self.parsed_event.type != YAML_MAPPING_END_EVENT: |
|
832 item_key = self._compose_node(node, None) |
|
833 item_value = self._compose_node(node, item_key) |
|
834 value.append((item_key, item_value)) |
|
835 self._parse_next_event() |
|
836 node.end_mark = Mark(self.stream_name, |
|
837 self.parsed_event.end_mark.index, |
|
838 self.parsed_event.end_mark.line, |
|
839 self.parsed_event.end_mark.column, |
|
840 None, None) |
|
841 yaml_event_delete(&self.parsed_event) |
|
842 return node |
|
843 |
|
844 cdef int _parse_next_event(self) except 0: |
|
845 if self.parsed_event.type == YAML_NO_EVENT: |
|
846 if yaml_parser_parse(&self.parser, &self.parsed_event) == 0: |
|
847 error = self._parser_error() |
|
848 raise error |
|
849 return 1 |
|
850 |
|
851 cdef int input_handler(void *data, char *buffer, int size, int *read) except 0: |
|
852 cdef CParser parser |
|
853 parser = <CParser>data |
|
854 value = parser.stream.read(size) |
|
855 if PyString_CheckExact(value) == 0: |
|
856 raise TypeError("a string value is expected") |
|
857 if PyString_GET_SIZE(value) > size: |
|
858 raise ValueError("a string value it too long") |
|
859 memcpy(buffer, PyString_AS_STRING(value), PyString_GET_SIZE(value)) |
|
860 read[0] = PyString_GET_SIZE(value) |
|
861 return 1 |
|
862 |
|
863 cdef class CEmitter: |
|
864 |
|
865 cdef yaml_emitter_t emitter |
|
866 |
|
867 cdef object stream |
|
868 |
|
869 cdef yaml_encoding_t use_encoding |
|
870 cdef int document_start_implicit |
|
871 cdef int document_end_implicit |
|
872 cdef object use_version |
|
873 cdef object use_tags |
|
874 |
|
875 cdef object serialized_nodes |
|
876 cdef object anchors |
|
877 cdef int last_alias_id |
|
878 cdef int closed |
|
879 |
|
880 def __init__(self, stream, canonical=None, indent=None, width=None, |
|
881 allow_unicode=None, line_break=None, encoding=None, |
|
882 explicit_start=None, explicit_end=None, version=None, tags=None): |
|
883 if yaml_emitter_initialize(&self.emitter) == 0: |
|
884 raise MemoryError |
|
885 self.stream = stream |
|
886 yaml_emitter_set_output(&self.emitter, output_handler, <void *>self) |
|
887 if canonical is not None: |
|
888 yaml_emitter_set_canonical(&self.emitter, 1) |
|
889 if indent is not None: |
|
890 yaml_emitter_set_indent(&self.emitter, indent) |
|
891 if width is not None: |
|
892 yaml_emitter_set_width(&self.emitter, width) |
|
893 if allow_unicode is not None: |
|
894 yaml_emitter_set_unicode(&self.emitter, 1) |
|
895 if line_break is not None: |
|
896 if line_break == '\r': |
|
897 yaml_emitter_set_break(&self.emitter, YAML_CR_BREAK) |
|
898 elif line_break == '\n': |
|
899 yaml_emitter_set_break(&self.emitter, YAML_LN_BREAK) |
|
900 elif line_break == '\r\n': |
|
901 yaml_emitter_set_break(&self.emitter, YAML_CRLN_BREAK) |
|
902 if encoding == 'utf-16-le': |
|
903 self.use_encoding = YAML_UTF16LE_ENCODING |
|
904 elif encoding == 'utf-16-be': |
|
905 self.use_encoding = YAML_UTF16BE_ENCODING |
|
906 else: |
|
907 self.use_encoding = YAML_UTF8_ENCODING |
|
908 self.document_start_implicit = 1 |
|
909 if explicit_start: |
|
910 self.document_start_implicit = 0 |
|
911 self.document_end_implicit = 1 |
|
912 if explicit_end: |
|
913 self.document_end_implicit = 0 |
|
914 self.use_version = version |
|
915 self.use_tags = tags |
|
916 self.serialized_nodes = {} |
|
917 self.anchors = {} |
|
918 self.last_alias_id = 0 |
|
919 self.closed = -1 |
|
920 |
|
921 def __dealloc__(self): |
|
922 yaml_emitter_delete(&self.emitter) |
|
923 |
|
924 cdef object _emitter_error(self): |
|
925 if self.emitter.error == YAML_MEMORY_ERROR: |
|
926 return MemoryError |
|
927 elif self.emitter.error == YAML_EMITTER_ERROR: |
|
928 return EmitterError(self.emitter.problem) |
|
929 raise ValueError("no emitter error") |
|
930 |
|
931 cdef int _object_to_event(self, object event_object, yaml_event_t *event) except 0: |
|
932 cdef yaml_encoding_t encoding |
|
933 cdef yaml_version_directive_t version_directive_value |
|
934 cdef yaml_version_directive_t *version_directive |
|
935 cdef yaml_tag_directive_t tag_directives_value[128] |
|
936 cdef yaml_tag_directive_t *tag_directives_start |
|
937 cdef yaml_tag_directive_t *tag_directives_end |
|
938 cdef int implicit |
|
939 cdef int plain_implicit |
|
940 cdef int quoted_implicit |
|
941 cdef char *anchor |
|
942 cdef char *tag |
|
943 cdef char *value |
|
944 cdef int length |
|
945 cdef yaml_scalar_style_t scalar_style |
|
946 cdef yaml_sequence_style_t sequence_style |
|
947 cdef yaml_mapping_style_t mapping_style |
|
948 event_class = event_object.__class__ |
|
949 if event_class is StreamStartEvent: |
|
950 encoding = YAML_UTF8_ENCODING |
|
951 if event_object.encoding == 'utf-16-le': |
|
952 encoding = YAML_UTF16LE_ENCODING |
|
953 elif event_object.encoding == 'utf-16-be': |
|
954 encoding = YAML_UTF16BE_ENCODING |
|
955 yaml_stream_start_event_initialize(event, encoding) |
|
956 elif event_class is StreamEndEvent: |
|
957 yaml_stream_end_event_initialize(event) |
|
958 elif event_class is DocumentStartEvent: |
|
959 version_directive = NULL |
|
960 if event_object.version: |
|
961 version_directive_value.major = event_object.version[0] |
|
962 version_directive_value.minor = event_object.version[1] |
|
963 version_directive = &version_directive_value |
|
964 tag_directives_start = NULL |
|
965 tag_directives_end = NULL |
|
966 if event_object.tags: |
|
967 if len(event_object.tags) > 128: |
|
968 raise ValueError("too many tags") |
|
969 tag_directives_start = tag_directives_value |
|
970 tag_directives_end = tag_directives_value |
|
971 cache = [] |
|
972 for handle in event_object.tags: |
|
973 prefix = event_object.tags[handle] |
|
974 if PyUnicode_CheckExact(handle): |
|
975 handle = PyUnicode_AsUTF8String(handle) |
|
976 cache.append(handle) |
|
977 if not PyString_CheckExact(handle): |
|
978 raise TypeError("tag handle must be a string") |
|
979 tag_directives_end.handle = PyString_AS_STRING(handle) |
|
980 if PyUnicode_CheckExact(prefix): |
|
981 prefix = PyUnicode_AsUTF8String(prefix) |
|
982 cache.append(prefix) |
|
983 if not PyString_CheckExact(prefix): |
|
984 raise TypeError("tag prefix must be a string") |
|
985 tag_directives_end.prefix = PyString_AS_STRING(prefix) |
|
986 tag_directives_end = tag_directives_end+1 |
|
987 implicit = 1 |
|
988 if event_object.explicit: |
|
989 implicit = 0 |
|
990 if yaml_document_start_event_initialize(event, version_directive, |
|
991 tag_directives_start, tag_directives_end, implicit) == 0: |
|
992 raise MemoryError |
|
993 elif event_class is DocumentEndEvent: |
|
994 implicit = 1 |
|
995 if event_object.explicit: |
|
996 implicit = 0 |
|
997 yaml_document_end_event_initialize(event, implicit) |
|
998 elif event_class is AliasEvent: |
|
999 anchor = NULL |
|
1000 anchor_object = event_object.anchor |
|
1001 if PyUnicode_CheckExact(anchor_object): |
|
1002 anchor_object = PyUnicode_AsUTF8String(anchor_object) |
|
1003 if not PyString_CheckExact(anchor_object): |
|
1004 raise TypeError("anchor must be a string") |
|
1005 anchor = PyString_AS_STRING(anchor_object) |
|
1006 if yaml_alias_event_initialize(event, anchor) == 0: |
|
1007 raise MemoryError |
|
1008 elif event_class is ScalarEvent: |
|
1009 anchor = NULL |
|
1010 anchor_object = event_object.anchor |
|
1011 if anchor_object is not None: |
|
1012 if PyUnicode_CheckExact(anchor_object): |
|
1013 anchor_object = PyUnicode_AsUTF8String(anchor_object) |
|
1014 if not PyString_CheckExact(anchor_object): |
|
1015 raise TypeError("anchor must be a string") |
|
1016 anchor = PyString_AS_STRING(anchor_object) |
|
1017 tag = NULL |
|
1018 tag_object = event_object.tag |
|
1019 if tag_object is not None: |
|
1020 if PyUnicode_CheckExact(tag_object): |
|
1021 tag_object = PyUnicode_AsUTF8String(tag_object) |
|
1022 if not PyString_CheckExact(tag_object): |
|
1023 raise TypeError("tag must be a string") |
|
1024 tag = PyString_AS_STRING(tag_object) |
|
1025 value_object = event_object.value |
|
1026 if PyUnicode_CheckExact(value_object): |
|
1027 value_object = PyUnicode_AsUTF8String(value_object) |
|
1028 if not PyString_CheckExact(value_object): |
|
1029 raise TypeError("value must be a string") |
|
1030 value = PyString_AS_STRING(value_object) |
|
1031 length = PyString_GET_SIZE(value_object) |
|
1032 plain_implicit = 0 |
|
1033 quoted_implicit = 0 |
|
1034 if event_object.implicit is not None: |
|
1035 plain_implicit = event_object.implicit[0] |
|
1036 quoted_implicit = event_object.implicit[1] |
|
1037 style_object = event_object.style |
|
1038 scalar_style = YAML_PLAIN_SCALAR_STYLE |
|
1039 if style_object == "'": |
|
1040 scalar_style = YAML_SINGLE_QUOTED_SCALAR_STYLE |
|
1041 elif style_object == "\"": |
|
1042 scalar_style = YAML_DOUBLE_QUOTED_SCALAR_STYLE |
|
1043 elif style_object == "|": |
|
1044 scalar_style = YAML_LITERAL_SCALAR_STYLE |
|
1045 elif style_object == ">": |
|
1046 scalar_style = YAML_FOLDED_SCALAR_STYLE |
|
1047 if yaml_scalar_event_initialize(event, anchor, tag, value, length, |
|
1048 plain_implicit, quoted_implicit, scalar_style) == 0: |
|
1049 raise MemoryError |
|
1050 elif event_class is SequenceStartEvent: |
|
1051 anchor = NULL |
|
1052 anchor_object = event_object.anchor |
|
1053 if anchor_object is not None: |
|
1054 if PyUnicode_CheckExact(anchor_object): |
|
1055 anchor_object = PyUnicode_AsUTF8String(anchor_object) |
|
1056 if not PyString_CheckExact(anchor_object): |
|
1057 raise TypeError("anchor must be a string") |
|
1058 anchor = PyString_AS_STRING(anchor_object) |
|
1059 tag = NULL |
|
1060 tag_object = event_object.tag |
|
1061 if tag_object is not None: |
|
1062 if PyUnicode_CheckExact(tag_object): |
|
1063 tag_object = PyUnicode_AsUTF8String(tag_object) |
|
1064 if not PyString_CheckExact(tag_object): |
|
1065 raise TypeError("tag must be a string") |
|
1066 tag = PyString_AS_STRING(tag_object) |
|
1067 implicit = 0 |
|
1068 if event_object.implicit: |
|
1069 implicit = 1 |
|
1070 sequence_style = YAML_BLOCK_SEQUENCE_STYLE |
|
1071 if event_object.flow_style: |
|
1072 sequence_style = YAML_FLOW_SEQUENCE_STYLE |
|
1073 if yaml_sequence_start_event_initialize(event, anchor, tag, |
|
1074 implicit, sequence_style) == 0: |
|
1075 raise MemoryError |
|
1076 elif event_class is MappingStartEvent: |
|
1077 anchor = NULL |
|
1078 anchor_object = event_object.anchor |
|
1079 if anchor_object is not None: |
|
1080 if PyUnicode_CheckExact(anchor_object): |
|
1081 anchor_object = PyUnicode_AsUTF8String(anchor_object) |
|
1082 if not PyString_CheckExact(anchor_object): |
|
1083 raise TypeError("anchor must be a string") |
|
1084 anchor = PyString_AS_STRING(anchor_object) |
|
1085 tag = NULL |
|
1086 tag_object = event_object.tag |
|
1087 if tag_object is not None: |
|
1088 if PyUnicode_CheckExact(tag_object): |
|
1089 tag_object = PyUnicode_AsUTF8String(tag_object) |
|
1090 if not PyString_CheckExact(tag_object): |
|
1091 raise TypeError("tag must be a string") |
|
1092 tag = PyString_AS_STRING(tag_object) |
|
1093 implicit = 0 |
|
1094 if event_object.implicit: |
|
1095 implicit = 1 |
|
1096 mapping_style = YAML_BLOCK_MAPPING_STYLE |
|
1097 if event_object.flow_style: |
|
1098 mapping_style = YAML_FLOW_MAPPING_STYLE |
|
1099 if yaml_mapping_start_event_initialize(event, anchor, tag, |
|
1100 implicit, mapping_style) == 0: |
|
1101 raise MemoryError |
|
1102 elif event_class is SequenceEndEvent: |
|
1103 yaml_sequence_end_event_initialize(event) |
|
1104 elif event_class is MappingEndEvent: |
|
1105 yaml_mapping_end_event_initialize(event) |
|
1106 else: |
|
1107 raise TypeError("invalid event %s" % event_object) |
|
1108 return 1 |
|
1109 |
|
1110 def emit(self, event_object): |
|
1111 cdef yaml_event_t event |
|
1112 self._object_to_event(event_object, &event) |
|
1113 if yaml_emitter_emit(&self.emitter, &event) == 0: |
|
1114 error = self._emitter_error() |
|
1115 raise error |
|
1116 |
|
1117 def open(self): |
|
1118 cdef yaml_event_t event |
|
1119 if self.closed == -1: |
|
1120 yaml_stream_start_event_initialize(&event, self.use_encoding) |
|
1121 if yaml_emitter_emit(&self.emitter, &event) == 0: |
|
1122 error = self._emitter_error() |
|
1123 raise error |
|
1124 self.closed = 0 |
|
1125 elif self.closed == 1: |
|
1126 raise SerializerError("serializer is closed") |
|
1127 else: |
|
1128 raise SerializerError("serializer is already opened") |
|
1129 |
|
1130 def close(self): |
|
1131 cdef yaml_event_t event |
|
1132 if self.closed == -1: |
|
1133 raise SerializerError("serializer is not opened") |
|
1134 elif self.closed == 0: |
|
1135 yaml_stream_end_event_initialize(&event) |
|
1136 if yaml_emitter_emit(&self.emitter, &event) == 0: |
|
1137 error = self._emitter_error() |
|
1138 raise error |
|
1139 self.closed = 1 |
|
1140 |
|
1141 def serialize(self, node): |
|
1142 cdef yaml_event_t event |
|
1143 cdef yaml_version_directive_t version_directive_value |
|
1144 cdef yaml_version_directive_t *version_directive |
|
1145 cdef yaml_tag_directive_t tag_directives_value[128] |
|
1146 cdef yaml_tag_directive_t *tag_directives_start |
|
1147 cdef yaml_tag_directive_t *tag_directives_end |
|
1148 if self.closed == -1: |
|
1149 raise SerializerError("serializer is not opened") |
|
1150 elif self.closed == 1: |
|
1151 raise SerializerError("serializer is closed") |
|
1152 cache = [] |
|
1153 version_directive = NULL |
|
1154 if self.use_version: |
|
1155 version_directive_value.major = self.use_version[0] |
|
1156 version_directive_value.minor = self.use_version[1] |
|
1157 version_directive = &version_directive_value |
|
1158 tag_directives_start = NULL |
|
1159 tag_directives_end = NULL |
|
1160 if self.use_tags: |
|
1161 if len(self.use_tags) > 128: |
|
1162 raise ValueError("too many tags") |
|
1163 tag_directives_start = tag_directives_value |
|
1164 tag_directives_end = tag_directives_value |
|
1165 for handle in self.use_tags: |
|
1166 prefix = self.use_tags[handle] |
|
1167 if PyUnicode_CheckExact(handle): |
|
1168 handle = PyUnicode_AsUTF8String(handle) |
|
1169 cache.append(handle) |
|
1170 if not PyString_CheckExact(handle): |
|
1171 raise TypeError("tag handle must be a string") |
|
1172 tag_directives_end.handle = PyString_AS_STRING(handle) |
|
1173 if PyUnicode_CheckExact(prefix): |
|
1174 prefix = PyUnicode_AsUTF8String(prefix) |
|
1175 cache.append(prefix) |
|
1176 if not PyString_CheckExact(prefix): |
|
1177 raise TypeError("tag prefix must be a string") |
|
1178 tag_directives_end.prefix = PyString_AS_STRING(prefix) |
|
1179 tag_directives_end = tag_directives_end+1 |
|
1180 if yaml_document_start_event_initialize(&event, version_directive, |
|
1181 tag_directives_start, tag_directives_end, |
|
1182 self.document_start_implicit) == 0: |
|
1183 raise MemoryError |
|
1184 if yaml_emitter_emit(&self.emitter, &event) == 0: |
|
1185 error = self._emitter_error() |
|
1186 raise error |
|
1187 self._anchor_node(node) |
|
1188 self._serialize_node(node, None, None) |
|
1189 yaml_document_end_event_initialize(&event, self.document_end_implicit) |
|
1190 if yaml_emitter_emit(&self.emitter, &event) == 0: |
|
1191 error = self._emitter_error() |
|
1192 raise error |
|
1193 self.serialized_nodes = {} |
|
1194 self.anchors = {} |
|
1195 self.last_alias_id = 0 |
|
1196 |
|
1197 cdef int _anchor_node(self, object node) except 0: |
|
1198 if node in self.anchors: |
|
1199 if self.anchors[node] is None: |
|
1200 self.last_alias_id = self.last_alias_id+1 |
|
1201 self.anchors[node] = "id%03d" % self.last_alias_id |
|
1202 else: |
|
1203 self.anchors[node] = None |
|
1204 node_class = node.__class__ |
|
1205 if node_class is SequenceNode: |
|
1206 for item in node.value: |
|
1207 self._anchor_node(item) |
|
1208 elif node_class is MappingNode: |
|
1209 for key, value in node.value: |
|
1210 self._anchor_node(key) |
|
1211 self._anchor_node(value) |
|
1212 return 1 |
|
1213 |
|
1214 cdef int _serialize_node(self, object node, object parent, object index) except 0: |
|
1215 cdef yaml_event_t event |
|
1216 cdef int implicit |
|
1217 cdef int plain_implicit |
|
1218 cdef int quoted_implicit |
|
1219 cdef char *anchor |
|
1220 cdef char *tag |
|
1221 cdef char *value |
|
1222 cdef int length |
|
1223 cdef int item_index |
|
1224 cdef yaml_scalar_style_t scalar_style |
|
1225 cdef yaml_sequence_style_t sequence_style |
|
1226 cdef yaml_mapping_style_t mapping_style |
|
1227 anchor_object = self.anchors[node] |
|
1228 anchor = NULL |
|
1229 if anchor_object is not None: |
|
1230 anchor = PyString_AS_STRING(anchor_object) |
|
1231 if node in self.serialized_nodes: |
|
1232 if yaml_alias_event_initialize(&event, anchor) == 0: |
|
1233 raise MemoryError |
|
1234 if yaml_emitter_emit(&self.emitter, &event) == 0: |
|
1235 error = self._emitter_error() |
|
1236 raise error |
|
1237 else: |
|
1238 node_class = node.__class__ |
|
1239 self.serialized_nodes[node] = True |
|
1240 self.descend_resolver(parent, index) |
|
1241 if node_class is ScalarNode: |
|
1242 plain_implicit = 0 |
|
1243 quoted_implicit = 0 |
|
1244 tag_object = node.tag |
|
1245 if self.resolve(ScalarNode, node.value, (True, False)) == tag_object: |
|
1246 plain_implicit = 1 |
|
1247 if self.resolve(ScalarNode, node.value, (False, True)) == tag_object: |
|
1248 quoted_implicit = 1 |
|
1249 tag = NULL |
|
1250 if tag_object is not None: |
|
1251 if PyUnicode_CheckExact(tag_object): |
|
1252 tag_object = PyUnicode_AsUTF8String(tag_object) |
|
1253 if not PyString_CheckExact(tag_object): |
|
1254 raise TypeError("tag must be a string") |
|
1255 tag = PyString_AS_STRING(tag_object) |
|
1256 value_object = node.value |
|
1257 if PyUnicode_CheckExact(value_object): |
|
1258 value_object = PyUnicode_AsUTF8String(value_object) |
|
1259 if not PyString_CheckExact(value_object): |
|
1260 raise TypeError("value must be a string") |
|
1261 value = PyString_AS_STRING(value_object) |
|
1262 length = PyString_GET_SIZE(value_object) |
|
1263 style_object = node.style |
|
1264 scalar_style = YAML_PLAIN_SCALAR_STYLE |
|
1265 if style_object == "'": |
|
1266 scalar_style = YAML_SINGLE_QUOTED_SCALAR_STYLE |
|
1267 elif style_object == "\"": |
|
1268 scalar_style = YAML_DOUBLE_QUOTED_SCALAR_STYLE |
|
1269 elif style_object == "|": |
|
1270 scalar_style = YAML_LITERAL_SCALAR_STYLE |
|
1271 elif style_object == ">": |
|
1272 scalar_style = YAML_FOLDED_SCALAR_STYLE |
|
1273 if yaml_scalar_event_initialize(&event, anchor, tag, value, length, |
|
1274 plain_implicit, quoted_implicit, scalar_style) == 0: |
|
1275 raise MemoryError |
|
1276 if yaml_emitter_emit(&self.emitter, &event) == 0: |
|
1277 error = self._emitter_error() |
|
1278 raise error |
|
1279 elif node_class is SequenceNode: |
|
1280 implicit = 0 |
|
1281 tag_object = node.tag |
|
1282 if self.resolve(SequenceNode, node.value, True) == tag_object: |
|
1283 implicit = 1 |
|
1284 tag = NULL |
|
1285 if tag_object is not None: |
|
1286 if PyUnicode_CheckExact(tag_object): |
|
1287 tag_object = PyUnicode_AsUTF8String(tag_object) |
|
1288 if not PyString_CheckExact(tag_object): |
|
1289 raise TypeError("tag must be a string") |
|
1290 tag = PyString_AS_STRING(tag_object) |
|
1291 sequence_style = YAML_BLOCK_SEQUENCE_STYLE |
|
1292 if node.flow_style: |
|
1293 sequence_style = YAML_FLOW_SEQUENCE_STYLE |
|
1294 if yaml_sequence_start_event_initialize(&event, anchor, tag, |
|
1295 implicit, sequence_style) == 0: |
|
1296 raise MemoryError |
|
1297 if yaml_emitter_emit(&self.emitter, &event) == 0: |
|
1298 error = self._emitter_error() |
|
1299 raise error |
|
1300 item_index = 0 |
|
1301 for item in node.value: |
|
1302 self._serialize_node(item, node, item_index) |
|
1303 item_index = item_index+1 |
|
1304 yaml_sequence_end_event_initialize(&event) |
|
1305 if yaml_emitter_emit(&self.emitter, &event) == 0: |
|
1306 error = self._emitter_error() |
|
1307 raise error |
|
1308 elif node_class is MappingNode: |
|
1309 implicit = 0 |
|
1310 tag_object = node.tag |
|
1311 if self.resolve(MappingNode, node.value, True) == tag_object: |
|
1312 implicit = 1 |
|
1313 tag = NULL |
|
1314 if tag_object is not None: |
|
1315 if PyUnicode_CheckExact(tag_object): |
|
1316 tag_object = PyUnicode_AsUTF8String(tag_object) |
|
1317 if not PyString_CheckExact(tag_object): |
|
1318 raise TypeError("tag must be a string") |
|
1319 tag = PyString_AS_STRING(tag_object) |
|
1320 mapping_style = YAML_BLOCK_MAPPING_STYLE |
|
1321 if node.flow_style: |
|
1322 mapping_style = YAML_FLOW_MAPPING_STYLE |
|
1323 if yaml_mapping_start_event_initialize(&event, anchor, tag, |
|
1324 implicit, mapping_style) == 0: |
|
1325 raise MemoryError |
|
1326 if yaml_emitter_emit(&self.emitter, &event) == 0: |
|
1327 error = self._emitter_error() |
|
1328 raise error |
|
1329 for item_key, item_value in node.value: |
|
1330 self._serialize_node(item_key, node, None) |
|
1331 self._serialize_node(item_value, node, item_key) |
|
1332 yaml_mapping_end_event_initialize(&event) |
|
1333 if yaml_emitter_emit(&self.emitter, &event) == 0: |
|
1334 error = self._emitter_error() |
|
1335 raise error |
|
1336 return 1 |
|
1337 |
|
1338 cdef int output_handler(void *data, char *buffer, int size) except 0: |
|
1339 cdef CEmitter emitter |
|
1340 emitter = <CEmitter>data |
|
1341 value = PyString_FromStringAndSize(buffer, size) |
|
1342 emitter.stream.write(value) |
|
1343 return 1 |
|
1344 |