source: pyyaml/trunk/ext/_yaml.pyx @ 366

Revision 366, 63.1 KB checked in by xi, 5 years ago (diff)

Fixed another encoding issue.

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