github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/encoding/kmgYaml/yaml_emitter.go (about) 1 package kmgYaml 2 3 import ( 4 "bytes" 5 ) 6 7 // Set an emitter error and return false. 8 func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool { 9 emitter.error = yaml_EMITTER_ERROR 10 emitter.problem = problem 11 return false 12 } 13 14 // Check if we need to accumulate more events before emitting. 15 // 16 // We accumulate extra 17 // - 1 event for DOCUMENT-START 18 // - 2 events for SEQUENCE-START 19 // - 3 events for MAPPING-START 20 // 21 func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool { 22 if emitter.events_head == len(emitter.events) { 23 return true 24 } 25 var accumulate int 26 switch emitter.events[emitter.events_head].typ { 27 case yaml_DOCUMENT_START_EVENT: 28 accumulate = 1 29 break 30 case yaml_SEQUENCE_START_EVENT: 31 accumulate = 2 32 break 33 case yaml_MAPPING_START_EVENT: 34 accumulate = 3 35 break 36 default: 37 return false 38 } 39 if len(emitter.events)-emitter.events_head > accumulate { 40 return false 41 } 42 var level int 43 for i := emitter.events_head; i < len(emitter.events); i++ { 44 switch emitter.events[i].typ { 45 case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT: 46 level++ 47 case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT: 48 level-- 49 } 50 if level == 0 { 51 return false 52 } 53 } 54 return true 55 } 56 57 // Append a directive to the directives stack. 58 func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool { 59 for i := 0; i < len(emitter.tag_directives); i++ { 60 if bytes.Equal(value.handle, emitter.tag_directives[i].handle) { 61 if allow_duplicates { 62 return true 63 } 64 return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive") 65 } 66 } 67 68 // [Go] Do we actually need to copy this given garbage collection 69 // and the lack of deallocating destructors? 70 tag_copy := yaml_tag_directive_t{ 71 handle: make([]byte, len(value.handle)), 72 prefix: make([]byte, len(value.prefix)), 73 } 74 copy(tag_copy.handle, value.handle) 75 copy(tag_copy.prefix, value.prefix) 76 emitter.tag_directives = append(emitter.tag_directives, tag_copy) 77 return true 78 } 79 80 // Increase the indentation level. 81 func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool { 82 emitter.indents = append(emitter.indents, emitter.indent) 83 if emitter.indent < 0 { 84 if flow { 85 emitter.indent = emitter.best_indent 86 } else { 87 emitter.indent = 0 88 } 89 } else if !indentless { 90 emitter.indent += emitter.best_indent 91 } 92 return true 93 } 94 95 // State dispatcher. 96 func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool { 97 switch emitter.state { 98 default: 99 case yaml_EMIT_STREAM_START_STATE: 100 return yaml_emitter_emit_stream_start(emitter, event) 101 102 case yaml_EMIT_FIRST_DOCUMENT_START_STATE: 103 return yaml_emitter_emit_document_start(emitter, event, true) 104 105 case yaml_EMIT_DOCUMENT_START_STATE: 106 return yaml_emitter_emit_document_start(emitter, event, false) 107 108 case yaml_EMIT_DOCUMENT_CONTENT_STATE: 109 return yaml_emitter_emit_document_content(emitter, event) 110 111 case yaml_EMIT_DOCUMENT_END_STATE: 112 return yaml_emitter_emit_document_end(emitter, event) 113 114 case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: 115 return yaml_emitter_emit_flow_sequence_item(emitter, event, true) 116 117 case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE: 118 return yaml_emitter_emit_flow_sequence_item(emitter, event, false) 119 120 case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: 121 return yaml_emitter_emit_flow_mapping_key(emitter, event, true) 122 123 case yaml_EMIT_FLOW_MAPPING_KEY_STATE: 124 return yaml_emitter_emit_flow_mapping_key(emitter, event, false) 125 126 case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: 127 return yaml_emitter_emit_flow_mapping_value(emitter, event, true) 128 129 case yaml_EMIT_FLOW_MAPPING_VALUE_STATE: 130 return yaml_emitter_emit_flow_mapping_value(emitter, event, false) 131 132 case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: 133 return yaml_emitter_emit_block_sequence_item(emitter, event, true) 134 135 case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE: 136 return yaml_emitter_emit_block_sequence_item(emitter, event, false) 137 138 case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: 139 return yaml_emitter_emit_block_mapping_key(emitter, event, true) 140 141 case yaml_EMIT_BLOCK_MAPPING_KEY_STATE: 142 return yaml_emitter_emit_block_mapping_key(emitter, event, false) 143 144 case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: 145 return yaml_emitter_emit_block_mapping_value(emitter, event, true) 146 147 case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE: 148 return yaml_emitter_emit_block_mapping_value(emitter, event, false) 149 150 case yaml_EMIT_END_STATE: 151 return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END") 152 } 153 panic("invalid emitter state") 154 } 155 156 // Determine an acceptable scalar style. 157 func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool { 158 159 no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 160 if no_tag && !event.implicit && !event.quoted_implicit { 161 return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified") 162 } 163 164 style := event.scalar_style() 165 if style == yaml_ANY_SCALAR_STYLE { 166 style = yaml_PLAIN_SCALAR_STYLE 167 } 168 if emitter.canonical { 169 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 170 } 171 if emitter.simple_key_context && emitter.scalar_data.multiline { 172 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 173 } 174 175 if style == yaml_PLAIN_SCALAR_STYLE { 176 if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed { 177 style = yaml_SINGLE_QUOTED_SCALAR_STYLE 178 } 179 if emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed { 180 style = yaml_SINGLE_QUOTED_SCALAR_STYLE 181 } 182 if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) { 183 style = yaml_SINGLE_QUOTED_SCALAR_STYLE 184 } 185 if no_tag && !event.implicit { 186 style = yaml_SINGLE_QUOTED_SCALAR_STYLE 187 } 188 } 189 if style == yaml_SINGLE_QUOTED_SCALAR_STYLE { 190 if !emitter.scalar_data.single_quoted_allowed { 191 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 192 } 193 } 194 if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE { 195 if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context { 196 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 197 } 198 } 199 200 if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE { 201 emitter.tag_data.handle = []byte{'!'} 202 } 203 emitter.scalar_data.style = style 204 return true 205 }