Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

 

__all__ = ['Serializer', 'SerializerError'] 

 

from error import YAMLError 

from events import * 

from nodes import * 

 

class SerializerError(YAMLError): 

    pass 

 

class Serializer(object): 

 

    ANCHOR_TEMPLATE = u'id%03d' 

 

    def __init__(self, encoding=None, 

            explicit_start=None, explicit_end=None, version=None, tags=None): 

        self.use_encoding = encoding 

        self.use_explicit_start = explicit_start 

        self.use_explicit_end = explicit_end 

        self.use_version = version 

        self.use_tags = tags 

        self.serialized_nodes = {} 

        self.anchors = {} 

        self.last_anchor_id = 0 

        self.closed = None 

 

    def open(self): 

        if self.closed is None: 

            self.emit(StreamStartEvent(encoding=self.use_encoding)) 

            self.closed = False 

        elif self.closed: 

            raise SerializerError("serializer is closed") 

        else: 

            raise SerializerError("serializer is already opened") 

 

    def close(self): 

        if self.closed is None: 

            raise SerializerError("serializer is not opened") 

        elif not self.closed: 

            self.emit(StreamEndEvent()) 

            self.closed = True 

 

    #def __del__(self): 

    #    self.close() 

 

    def serialize(self, node): 

        if self.closed is None: 

            raise SerializerError("serializer is not opened") 

        elif self.closed: 

            raise SerializerError("serializer is closed") 

        self.emit(DocumentStartEvent(explicit=self.use_explicit_start, 

            version=self.use_version, tags=self.use_tags)) 

        self.anchor_node(node) 

        self.serialize_node(node, None, None) 

        self.emit(DocumentEndEvent(explicit=self.use_explicit_end)) 

        self.serialized_nodes = {} 

        self.anchors = {} 

        self.last_anchor_id = 0 

 

    def anchor_node(self, node): 

        if node in self.anchors: 

            if self.anchors[node] is None: 

                self.anchors[node] = self.generate_anchor(node) 

        else: 

            self.anchors[node] = None 

            if isinstance(node, SequenceNode): 

                for item in node.value: 

                    self.anchor_node(item) 

            elif isinstance(node, MappingNode): 

                for key, value in node.value: 

                    self.anchor_node(key) 

                    self.anchor_node(value) 

 

    def generate_anchor(self, node): 

        self.last_anchor_id += 1 

        return self.ANCHOR_TEMPLATE % self.last_anchor_id 

 

    def serialize_node(self, node, parent, index): 

        alias = self.anchors[node] 

        if node in self.serialized_nodes: 

            self.emit(AliasEvent(alias)) 

        else: 

            self.serialized_nodes[node] = True 

            self.descend_resolver(parent, index) 

            if isinstance(node, ScalarNode): 

                detected_tag = self.resolve(ScalarNode, node.value, (True, False)) 

                default_tag = self.resolve(ScalarNode, node.value, (False, True)) 

                implicit = (node.tag == detected_tag), (node.tag == default_tag) 

                self.emit(ScalarEvent(alias, node.tag, implicit, node.value, 

                    style=node.style)) 

            elif isinstance(node, SequenceNode): 

                implicit = (node.tag 

                            == self.resolve(SequenceNode, node.value, True)) 

                self.emit(SequenceStartEvent(alias, node.tag, implicit, 

                    flow_style=node.flow_style)) 

                index = 0 

                for item in node.value: 

                    self.serialize_node(item, node, index) 

                    index += 1 

                self.emit(SequenceEndEvent()) 

            elif isinstance(node, MappingNode): 

                implicit = (node.tag 

                            == self.resolve(MappingNode, node.value, True)) 

                self.emit(MappingStartEvent(alias, node.tag, implicit, 

                    flow_style=node.flow_style)) 

                for key, value in node.value: 

                    self.serialize_node(key, node, None) 

                    self.serialize_node(value, node, key) 

                self.emit(MappingEndEvent()) 

            self.ascend_resolver()