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