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