source: pyyaml/trunk/lib/yaml/serializer.py @ 136

Revision 136, 4.3 KB checked in by xi, 8 years ago (diff)

Major refactoring.

Line 
1
2__all__ = ['Serializer', 'SerializerError']
3
4from error import YAMLError
5from events import *
6from nodes import *
7
8class SerializerError(YAMLError):
9    pass
10
11class Serializer:
12
13    ANCHOR_TEMPLATE = u'id%03d'
14
15    def __init__(self, encoding=None,
16            explicit_start=None, explicit_end=None, version=None, tags=None):
17        self.use_encoding = encoding
18        self.use_explicit_start = explicit_start
19        self.use_explicit_end = explicit_end
20        self.use_version = version
21        self.use_tags = tags
22        self.serialized_nodes = {}
23        self.anchors = {}
24        self.last_anchor_id = 0
25        self.closed = None
26
27    def open(self):
28        if self.closed is None:
29            self.emit(StreamStartEvent(encoding=self.use_encoding))
30            self.closed = False
31        elif self.closed:
32            raise SerializerError("serializer is closed")
33        else:
34            raise SerializerError("serializer is already opened")
35
36    def close(self):
37        if self.closed is None:
38            raise SerializerError("serializer is not opened")
39        elif not self.closed:
40            self.emit(StreamEndEvent())
41            self.closed = True
42
43    #def __del__(self):
44    #    self.close()
45
46    def serialize(self, node):
47        if self.closed is None:
48            raise SerializerError("serializer is not opened")
49        elif self.closed:
50            raise SerializerError("serializer is closed")
51        self.emit(DocumentStartEvent(explicit=self.use_explicit_start,
52            version=self.use_version, tags=self.use_tags))
53        self.anchor_node(node)
54        self.serialize_node(node)
55        self.emit(DocumentEndEvent(explicit=self.use_explicit_end))
56        self.serialized_nodes = {}
57        self.anchors = {}
58        self.last_alias_id = 0
59
60    def anchor_node(self, node):
61        if node in self.anchors:
62            if self.anchors[node] is None:
63                self.anchors[node] = self.generate_anchor(node)
64        else:
65            self.anchors[node] = None
66            if isinstance(node, SequenceNode):
67                for item in node.value:
68                    self.anchor_node(item)
69            elif isinstance(node, MappingNode):
70                for key in node.value:
71                    self.anchor_node(key)
72                    self.anchor_node(node.value[key])
73
74    def generate_anchor(self, node):
75        self.last_anchor_id += 1
76        return self.ANCHOR_TEMPLATE % self.last_anchor_id
77
78    def serialize_node(self, node):
79        alias = self.anchors[node]
80        if node in self.serialized_nodes:
81            self.emit(AliasEvent(alias))
82        else:
83            self.serialized_nodes[node] = True
84            if isinstance(node, ScalarNode):
85                detected_tag = self.detect(node.value)
86                implicit = (node.tag == self.detect(node.value)
87                        or (node.tag == self.DEFAULT_SCALAR_TAG
88                            and detected_tag is None))
89                self.emit(ScalarEvent(alias, node.tag, implicit, node.value,
90                    style=node.style))
91            elif isinstance(node, SequenceNode):
92                # TODO:
93                # 1) Check the current path in the Resolver.
94                # 2) Add the implicit flag to the SequenceStartEvent and
95                # MappingStartEvent.
96                tag = node.tag
97                if tag == self.DEFAULT_SEQUENCE_TAG and not self.canonical:
98                    tag = None
99                self.emit(SequenceStartEvent(alias, tag,
100                    flow_style=node.flow_style))
101                for item in node.value:
102                    self.serialize_node(item)
103                self.emit(SequenceEndEvent())
104            elif isinstance(node, MappingNode):
105                tag = node.tag
106                if tag == self.DEFAULT_MAPPING_TAG and not self.canonical:
107                    tag = None
108                self.emit(MappingStartEvent(alias, tag,
109                    flow_style=node.flow_style))
110                if hasattr(node.value, 'keys'):
111                    for key in node.value.keys():
112                        self.serialize_node(key)
113                        self.serialize_node(node.value[key])
114                else:
115                    for key, value in node.value:
116                        self.serialize_node(key)
117                        self.serialize_node(value)
118                self.emit(MappingEndEvent())
119
Note: See TracBrowser for help on using the repository browser.