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