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