You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
4.1 KiB

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