emitterc.go

   1package yaml
   2
   3import (
   4	"bytes"
   5	"fmt"
   6)
   7
   8// Flush the buffer if needed.
   9func flush(emitter *yaml_emitter_t) bool {
  10	if emitter.buffer_pos+5 >= len(emitter.buffer) {
  11		return yaml_emitter_flush(emitter)
  12	}
  13	return true
  14}
  15
  16// Put a character to the output buffer.
  17func put(emitter *yaml_emitter_t, value byte) bool {
  18	if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
  19		return false
  20	}
  21	emitter.buffer[emitter.buffer_pos] = value
  22	emitter.buffer_pos++
  23	emitter.column++
  24	return true
  25}
  26
  27// Put a line break to the output buffer.
  28func put_break(emitter *yaml_emitter_t) bool {
  29	if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
  30		return false
  31	}
  32	switch emitter.line_break {
  33	case yaml_CR_BREAK:
  34		emitter.buffer[emitter.buffer_pos] = '\r'
  35		emitter.buffer_pos += 1
  36	case yaml_LN_BREAK:
  37		emitter.buffer[emitter.buffer_pos] = '\n'
  38		emitter.buffer_pos += 1
  39	case yaml_CRLN_BREAK:
  40		emitter.buffer[emitter.buffer_pos+0] = '\r'
  41		emitter.buffer[emitter.buffer_pos+1] = '\n'
  42		emitter.buffer_pos += 2
  43	default:
  44		panic("unknown line break setting")
  45	}
  46	emitter.column = 0
  47	emitter.line++
  48	return true
  49}
  50
  51// Copy a character from a string into buffer.
  52func write(emitter *yaml_emitter_t, s []byte, i *int) bool {
  53	if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
  54		return false
  55	}
  56	p := emitter.buffer_pos
  57	w := width(s[*i])
  58	switch w {
  59	case 4:
  60		emitter.buffer[p+3] = s[*i+3]
  61		fallthrough
  62	case 3:
  63		emitter.buffer[p+2] = s[*i+2]
  64		fallthrough
  65	case 2:
  66		emitter.buffer[p+1] = s[*i+1]
  67		fallthrough
  68	case 1:
  69		emitter.buffer[p+0] = s[*i+0]
  70	default:
  71		panic("unknown character width")
  72	}
  73	emitter.column++
  74	emitter.buffer_pos += w
  75	*i += w
  76	return true
  77}
  78
  79// Write a whole string into buffer.
  80func write_all(emitter *yaml_emitter_t, s []byte) bool {
  81	for i := 0; i < len(s); {
  82		if !write(emitter, s, &i) {
  83			return false
  84		}
  85	}
  86	return true
  87}
  88
  89// Copy a line break character from a string into buffer.
  90func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool {
  91	if s[*i] == '\n' {
  92		if !put_break(emitter) {
  93			return false
  94		}
  95		*i++
  96	} else {
  97		if !write(emitter, s, i) {
  98			return false
  99		}
 100		emitter.column = 0
 101		emitter.line++
 102	}
 103	return true
 104}
 105
 106// Set an emitter error and return false.
 107func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool {
 108	emitter.error = yaml_EMITTER_ERROR
 109	emitter.problem = problem
 110	return false
 111}
 112
 113// Emit an event.
 114func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 115	emitter.events = append(emitter.events, *event)
 116	for !yaml_emitter_need_more_events(emitter) {
 117		event := &emitter.events[emitter.events_head]
 118		if !yaml_emitter_analyze_event(emitter, event) {
 119			return false
 120		}
 121		if !yaml_emitter_state_machine(emitter, event) {
 122			return false
 123		}
 124		yaml_event_delete(event)
 125		emitter.events_head++
 126	}
 127	return true
 128}
 129
 130// Check if we need to accumulate more events before emitting.
 131//
 132// We accumulate extra
 133//  - 1 event for DOCUMENT-START
 134//  - 2 events for SEQUENCE-START
 135//  - 3 events for MAPPING-START
 136//
 137func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {
 138	if emitter.events_head == len(emitter.events) {
 139		return true
 140	}
 141	var accumulate int
 142	switch emitter.events[emitter.events_head].typ {
 143	case yaml_DOCUMENT_START_EVENT:
 144		accumulate = 1
 145		break
 146	case yaml_SEQUENCE_START_EVENT:
 147		accumulate = 2
 148		break
 149	case yaml_MAPPING_START_EVENT:
 150		accumulate = 3
 151		break
 152	default:
 153		return false
 154	}
 155	if len(emitter.events)-emitter.events_head > accumulate {
 156		return false
 157	}
 158	var level int
 159	for i := emitter.events_head; i < len(emitter.events); i++ {
 160		switch emitter.events[i].typ {
 161		case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT:
 162			level++
 163		case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:
 164			level--
 165		}
 166		if level == 0 {
 167			return false
 168		}
 169	}
 170	return true
 171}
 172
 173// Append a directive to the directives stack.
 174func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool {
 175	for i := 0; i < len(emitter.tag_directives); i++ {
 176		if bytes.Equal(value.handle, emitter.tag_directives[i].handle) {
 177			if allow_duplicates {
 178				return true
 179			}
 180			return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive")
 181		}
 182	}
 183
 184	// [Go] Do we actually need to copy this given garbage collection
 185	// and the lack of deallocating destructors?
 186	tag_copy := yaml_tag_directive_t{
 187		handle: make([]byte, len(value.handle)),
 188		prefix: make([]byte, len(value.prefix)),
 189	}
 190	copy(tag_copy.handle, value.handle)
 191	copy(tag_copy.prefix, value.prefix)
 192	emitter.tag_directives = append(emitter.tag_directives, tag_copy)
 193	return true
 194}
 195
 196// Increase the indentation level.
 197func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {
 198	emitter.indents = append(emitter.indents, emitter.indent)
 199	if emitter.indent < 0 {
 200		if flow {
 201			emitter.indent = emitter.best_indent
 202		} else {
 203			emitter.indent = 0
 204		}
 205	} else if !indentless {
 206		emitter.indent += emitter.best_indent
 207	}
 208	return true
 209}
 210
 211// State dispatcher.
 212func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 213	switch emitter.state {
 214	default:
 215	case yaml_EMIT_STREAM_START_STATE:
 216		return yaml_emitter_emit_stream_start(emitter, event)
 217
 218	case yaml_EMIT_FIRST_DOCUMENT_START_STATE:
 219		return yaml_emitter_emit_document_start(emitter, event, true)
 220
 221	case yaml_EMIT_DOCUMENT_START_STATE:
 222		return yaml_emitter_emit_document_start(emitter, event, false)
 223
 224	case yaml_EMIT_DOCUMENT_CONTENT_STATE:
 225		return yaml_emitter_emit_document_content(emitter, event)
 226
 227	case yaml_EMIT_DOCUMENT_END_STATE:
 228		return yaml_emitter_emit_document_end(emitter, event)
 229
 230	case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
 231		return yaml_emitter_emit_flow_sequence_item(emitter, event, true)
 232
 233	case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:
 234		return yaml_emitter_emit_flow_sequence_item(emitter, event, false)
 235
 236	case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
 237		return yaml_emitter_emit_flow_mapping_key(emitter, event, true)
 238
 239	case yaml_EMIT_FLOW_MAPPING_KEY_STATE:
 240		return yaml_emitter_emit_flow_mapping_key(emitter, event, false)
 241
 242	case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
 243		return yaml_emitter_emit_flow_mapping_value(emitter, event, true)
 244
 245	case yaml_EMIT_FLOW_MAPPING_VALUE_STATE:
 246		return yaml_emitter_emit_flow_mapping_value(emitter, event, false)
 247
 248	case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
 249		return yaml_emitter_emit_block_sequence_item(emitter, event, true)
 250
 251	case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
 252		return yaml_emitter_emit_block_sequence_item(emitter, event, false)
 253
 254	case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
 255		return yaml_emitter_emit_block_mapping_key(emitter, event, true)
 256
 257	case yaml_EMIT_BLOCK_MAPPING_KEY_STATE:
 258		return yaml_emitter_emit_block_mapping_key(emitter, event, false)
 259
 260	case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
 261		return yaml_emitter_emit_block_mapping_value(emitter, event, true)
 262
 263	case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:
 264		return yaml_emitter_emit_block_mapping_value(emitter, event, false)
 265
 266	case yaml_EMIT_END_STATE:
 267		return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")
 268	}
 269	panic("invalid emitter state")
 270}
 271
 272// Expect STREAM-START.
 273func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 274	if event.typ != yaml_STREAM_START_EVENT {
 275		return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START")
 276	}
 277	if emitter.encoding == yaml_ANY_ENCODING {
 278		emitter.encoding = event.encoding
 279		if emitter.encoding == yaml_ANY_ENCODING {
 280			emitter.encoding = yaml_UTF8_ENCODING
 281		}
 282	}
 283	if emitter.best_indent < 2 || emitter.best_indent > 9 {
 284		emitter.best_indent = 2
 285	}
 286	if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {
 287		emitter.best_width = 80
 288	}
 289	if emitter.best_width < 0 {
 290		emitter.best_width = 1<<31 - 1
 291	}
 292	if emitter.line_break == yaml_ANY_BREAK {
 293		emitter.line_break = yaml_LN_BREAK
 294	}
 295
 296	emitter.indent = -1
 297	emitter.line = 0
 298	emitter.column = 0
 299	emitter.whitespace = true
 300	emitter.indention = true
 301
 302	if emitter.encoding != yaml_UTF8_ENCODING {
 303		if !yaml_emitter_write_bom(emitter) {
 304			return false
 305		}
 306	}
 307	emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE
 308	return true
 309}
 310
 311// Expect DOCUMENT-START or STREAM-END.
 312func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
 313
 314	if event.typ == yaml_DOCUMENT_START_EVENT {
 315
 316		if event.version_directive != nil {
 317			if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {
 318				return false
 319			}
 320		}
 321
 322		for i := 0; i < len(event.tag_directives); i++ {
 323			tag_directive := &event.tag_directives[i]
 324			if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) {
 325				return false
 326			}
 327			if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {
 328				return false
 329			}
 330		}
 331
 332		for i := 0; i < len(default_tag_directives); i++ {
 333			tag_directive := &default_tag_directives[i]
 334			if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) {
 335				return false
 336			}
 337		}
 338
 339		implicit := event.implicit
 340		if !first || emitter.canonical {
 341			implicit = false
 342		}
 343
 344		if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) {
 345			if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
 346				return false
 347			}
 348			if !yaml_emitter_write_indent(emitter) {
 349				return false
 350			}
 351		}
 352
 353		if event.version_directive != nil {
 354			implicit = false
 355			if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) {
 356				return false
 357			}
 358			if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) {
 359				return false
 360			}
 361			if !yaml_emitter_write_indent(emitter) {
 362				return false
 363			}
 364		}
 365
 366		if len(event.tag_directives) > 0 {
 367			implicit = false
 368			for i := 0; i < len(event.tag_directives); i++ {
 369				tag_directive := &event.tag_directives[i]
 370				if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) {
 371					return false
 372				}
 373				if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {
 374					return false
 375				}
 376				if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {
 377					return false
 378				}
 379				if !yaml_emitter_write_indent(emitter) {
 380					return false
 381				}
 382			}
 383		}
 384
 385		if yaml_emitter_check_empty_document(emitter) {
 386			implicit = false
 387		}
 388		if !implicit {
 389			if !yaml_emitter_write_indent(emitter) {
 390				return false
 391			}
 392			if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) {
 393				return false
 394			}
 395			if emitter.canonical {
 396				if !yaml_emitter_write_indent(emitter) {
 397					return false
 398				}
 399			}
 400		}
 401
 402		emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE
 403		return true
 404	}
 405
 406	if event.typ == yaml_STREAM_END_EVENT {
 407		if emitter.open_ended {
 408			if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
 409				return false
 410			}
 411			if !yaml_emitter_write_indent(emitter) {
 412				return false
 413			}
 414		}
 415		if !yaml_emitter_flush(emitter) {
 416			return false
 417		}
 418		emitter.state = yaml_EMIT_END_STATE
 419		return true
 420	}
 421
 422	return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END")
 423}
 424
 425// Expect the root node.
 426func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 427	emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE)
 428	return yaml_emitter_emit_node(emitter, event, true, false, false, false)
 429}
 430
 431// Expect DOCUMENT-END.
 432func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 433	if event.typ != yaml_DOCUMENT_END_EVENT {
 434		return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END")
 435	}
 436	if !yaml_emitter_write_indent(emitter) {
 437		return false
 438	}
 439	if !event.implicit {
 440		// [Go] Allocate the slice elsewhere.
 441		if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
 442			return false
 443		}
 444		if !yaml_emitter_write_indent(emitter) {
 445			return false
 446		}
 447	}
 448	if !yaml_emitter_flush(emitter) {
 449		return false
 450	}
 451	emitter.state = yaml_EMIT_DOCUMENT_START_STATE
 452	emitter.tag_directives = emitter.tag_directives[:0]
 453	return true
 454}
 455
 456// Expect a flow item node.
 457func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
 458	if first {
 459		if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {
 460			return false
 461		}
 462		if !yaml_emitter_increase_indent(emitter, true, false) {
 463			return false
 464		}
 465		emitter.flow_level++
 466	}
 467
 468	if event.typ == yaml_SEQUENCE_END_EVENT {
 469		emitter.flow_level--
 470		emitter.indent = emitter.indents[len(emitter.indents)-1]
 471		emitter.indents = emitter.indents[:len(emitter.indents)-1]
 472		if emitter.canonical && !first {
 473			if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
 474				return false
 475			}
 476			if !yaml_emitter_write_indent(emitter) {
 477				return false
 478			}
 479		}
 480		if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {
 481			return false
 482		}
 483		emitter.state = emitter.states[len(emitter.states)-1]
 484		emitter.states = emitter.states[:len(emitter.states)-1]
 485
 486		return true
 487	}
 488
 489	if !first {
 490		if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
 491			return false
 492		}
 493	}
 494
 495	if emitter.canonical || emitter.column > emitter.best_width {
 496		if !yaml_emitter_write_indent(emitter) {
 497			return false
 498		}
 499	}
 500	emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)
 501	return yaml_emitter_emit_node(emitter, event, false, true, false, false)
 502}
 503
 504// Expect a flow key node.
 505func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
 506	if first {
 507		if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {
 508			return false
 509		}
 510		if !yaml_emitter_increase_indent(emitter, true, false) {
 511			return false
 512		}
 513		emitter.flow_level++
 514	}
 515
 516	if event.typ == yaml_MAPPING_END_EVENT {
 517		emitter.flow_level--
 518		emitter.indent = emitter.indents[len(emitter.indents)-1]
 519		emitter.indents = emitter.indents[:len(emitter.indents)-1]
 520		if emitter.canonical && !first {
 521			if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
 522				return false
 523			}
 524			if !yaml_emitter_write_indent(emitter) {
 525				return false
 526			}
 527		}
 528		if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {
 529			return false
 530		}
 531		emitter.state = emitter.states[len(emitter.states)-1]
 532		emitter.states = emitter.states[:len(emitter.states)-1]
 533		return true
 534	}
 535
 536	if !first {
 537		if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
 538			return false
 539		}
 540	}
 541	if emitter.canonical || emitter.column > emitter.best_width {
 542		if !yaml_emitter_write_indent(emitter) {
 543			return false
 544		}
 545	}
 546
 547	if !emitter.canonical && yaml_emitter_check_simple_key(emitter) {
 548		emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)
 549		return yaml_emitter_emit_node(emitter, event, false, false, true, true)
 550	}
 551	if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {
 552		return false
 553	}
 554	emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)
 555	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
 556}
 557
 558// Expect a flow value node.
 559func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
 560	if simple {
 561		if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
 562			return false
 563		}
 564	} else {
 565		if emitter.canonical || emitter.column > emitter.best_width {
 566			if !yaml_emitter_write_indent(emitter) {
 567				return false
 568			}
 569		}
 570		if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {
 571			return false
 572		}
 573	}
 574	emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)
 575	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
 576}
 577
 578// Expect a block item node.
 579func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
 580	if first {
 581		if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) {
 582			return false
 583		}
 584	}
 585	if event.typ == yaml_SEQUENCE_END_EVENT {
 586		emitter.indent = emitter.indents[len(emitter.indents)-1]
 587		emitter.indents = emitter.indents[:len(emitter.indents)-1]
 588		emitter.state = emitter.states[len(emitter.states)-1]
 589		emitter.states = emitter.states[:len(emitter.states)-1]
 590		return true
 591	}
 592	if !yaml_emitter_write_indent(emitter) {
 593		return false
 594	}
 595	if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {
 596		return false
 597	}
 598	emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)
 599	return yaml_emitter_emit_node(emitter, event, false, true, false, false)
 600}
 601
 602// Expect a block key node.
 603func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
 604	if first {
 605		if !yaml_emitter_increase_indent(emitter, false, false) {
 606			return false
 607		}
 608	}
 609	if event.typ == yaml_MAPPING_END_EVENT {
 610		emitter.indent = emitter.indents[len(emitter.indents)-1]
 611		emitter.indents = emitter.indents[:len(emitter.indents)-1]
 612		emitter.state = emitter.states[len(emitter.states)-1]
 613		emitter.states = emitter.states[:len(emitter.states)-1]
 614		return true
 615	}
 616	if !yaml_emitter_write_indent(emitter) {
 617		return false
 618	}
 619	if yaml_emitter_check_simple_key(emitter) {
 620		emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)
 621		return yaml_emitter_emit_node(emitter, event, false, false, true, true)
 622	}
 623	if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {
 624		return false
 625	}
 626	emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)
 627	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
 628}
 629
 630// Expect a block value node.
 631func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
 632	if simple {
 633		if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
 634			return false
 635		}
 636	} else {
 637		if !yaml_emitter_write_indent(emitter) {
 638			return false
 639		}
 640		if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {
 641			return false
 642		}
 643	}
 644	emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)
 645	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
 646}
 647
 648// Expect a node.
 649func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
 650	root bool, sequence bool, mapping bool, simple_key bool) bool {
 651
 652	emitter.root_context = root
 653	emitter.sequence_context = sequence
 654	emitter.mapping_context = mapping
 655	emitter.simple_key_context = simple_key
 656
 657	switch event.typ {
 658	case yaml_ALIAS_EVENT:
 659		return yaml_emitter_emit_alias(emitter, event)
 660	case yaml_SCALAR_EVENT:
 661		return yaml_emitter_emit_scalar(emitter, event)
 662	case yaml_SEQUENCE_START_EVENT:
 663		return yaml_emitter_emit_sequence_start(emitter, event)
 664	case yaml_MAPPING_START_EVENT:
 665		return yaml_emitter_emit_mapping_start(emitter, event)
 666	default:
 667		return yaml_emitter_set_emitter_error(emitter,
 668			fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))
 669	}
 670}
 671
 672// Expect ALIAS.
 673func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 674	if !yaml_emitter_process_anchor(emitter) {
 675		return false
 676	}
 677	emitter.state = emitter.states[len(emitter.states)-1]
 678	emitter.states = emitter.states[:len(emitter.states)-1]
 679	return true
 680}
 681
 682// Expect SCALAR.
 683func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 684	if !yaml_emitter_select_scalar_style(emitter, event) {
 685		return false
 686	}
 687	if !yaml_emitter_process_anchor(emitter) {
 688		return false
 689	}
 690	if !yaml_emitter_process_tag(emitter) {
 691		return false
 692	}
 693	if !yaml_emitter_increase_indent(emitter, true, false) {
 694		return false
 695	}
 696	if !yaml_emitter_process_scalar(emitter) {
 697		return false
 698	}
 699	emitter.indent = emitter.indents[len(emitter.indents)-1]
 700	emitter.indents = emitter.indents[:len(emitter.indents)-1]
 701	emitter.state = emitter.states[len(emitter.states)-1]
 702	emitter.states = emitter.states[:len(emitter.states)-1]
 703	return true
 704}
 705
 706// Expect SEQUENCE-START.
 707func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 708	if !yaml_emitter_process_anchor(emitter) {
 709		return false
 710	}
 711	if !yaml_emitter_process_tag(emitter) {
 712		return false
 713	}
 714	if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE ||
 715		yaml_emitter_check_empty_sequence(emitter) {
 716		emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE
 717	} else {
 718		emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE
 719	}
 720	return true
 721}
 722
 723// Expect MAPPING-START.
 724func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 725	if !yaml_emitter_process_anchor(emitter) {
 726		return false
 727	}
 728	if !yaml_emitter_process_tag(emitter) {
 729		return false
 730	}
 731	if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE ||
 732		yaml_emitter_check_empty_mapping(emitter) {
 733		emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE
 734	} else {
 735		emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE
 736	}
 737	return true
 738}
 739
 740// Check if the document content is an empty scalar.
 741func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool {
 742	return false // [Go] Huh?
 743}
 744
 745// Check if the next events represent an empty sequence.
 746func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool {
 747	if len(emitter.events)-emitter.events_head < 2 {
 748		return false
 749	}
 750	return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT &&
 751		emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT
 752}
 753
 754// Check if the next events represent an empty mapping.
 755func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool {
 756	if len(emitter.events)-emitter.events_head < 2 {
 757		return false
 758	}
 759	return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT &&
 760		emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT
 761}
 762
 763// Check if the next node can be expressed as a simple key.
 764func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool {
 765	length := 0
 766	switch emitter.events[emitter.events_head].typ {
 767	case yaml_ALIAS_EVENT:
 768		length += len(emitter.anchor_data.anchor)
 769	case yaml_SCALAR_EVENT:
 770		if emitter.scalar_data.multiline {
 771			return false
 772		}
 773		length += len(emitter.anchor_data.anchor) +
 774			len(emitter.tag_data.handle) +
 775			len(emitter.tag_data.suffix) +
 776			len(emitter.scalar_data.value)
 777	case yaml_SEQUENCE_START_EVENT:
 778		if !yaml_emitter_check_empty_sequence(emitter) {
 779			return false
 780		}
 781		length += len(emitter.anchor_data.anchor) +
 782			len(emitter.tag_data.handle) +
 783			len(emitter.tag_data.suffix)
 784	case yaml_MAPPING_START_EVENT:
 785		if !yaml_emitter_check_empty_mapping(emitter) {
 786			return false
 787		}
 788		length += len(emitter.anchor_data.anchor) +
 789			len(emitter.tag_data.handle) +
 790			len(emitter.tag_data.suffix)
 791	default:
 792		return false
 793	}
 794	return length <= 128
 795}
 796
 797// Determine an acceptable scalar style.
 798func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 799
 800	no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0
 801	if no_tag && !event.implicit && !event.quoted_implicit {
 802		return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified")
 803	}
 804
 805	style := event.scalar_style()
 806	if style == yaml_ANY_SCALAR_STYLE {
 807		style = yaml_PLAIN_SCALAR_STYLE
 808	}
 809	if emitter.canonical {
 810		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
 811	}
 812	if emitter.simple_key_context && emitter.scalar_data.multiline {
 813		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
 814	}
 815
 816	if style == yaml_PLAIN_SCALAR_STYLE {
 817		if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed ||
 818			emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed {
 819			style = yaml_SINGLE_QUOTED_SCALAR_STYLE
 820		}
 821		if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) {
 822			style = yaml_SINGLE_QUOTED_SCALAR_STYLE
 823		}
 824		if no_tag && !event.implicit {
 825			style = yaml_SINGLE_QUOTED_SCALAR_STYLE
 826		}
 827	}
 828	if style == yaml_SINGLE_QUOTED_SCALAR_STYLE {
 829		if !emitter.scalar_data.single_quoted_allowed {
 830			style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
 831		}
 832	}
 833	if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE {
 834		if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context {
 835			style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
 836		}
 837	}
 838
 839	if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE {
 840		emitter.tag_data.handle = []byte{'!'}
 841	}
 842	emitter.scalar_data.style = style
 843	return true
 844}
 845
 846// Write an anchor.
 847func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
 848	if emitter.anchor_data.anchor == nil {
 849		return true
 850	}
 851	c := []byte{'&'}
 852	if emitter.anchor_data.alias {
 853		c[0] = '*'
 854	}
 855	if !yaml_emitter_write_indicator(emitter, c, true, false, false) {
 856		return false
 857	}
 858	return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor)
 859}
 860
 861// Write a tag.
 862func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool {
 863	if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 {
 864		return true
 865	}
 866	if len(emitter.tag_data.handle) > 0 {
 867		if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) {
 868			return false
 869		}
 870		if len(emitter.tag_data.suffix) > 0 {
 871			if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
 872				return false
 873			}
 874		}
 875	} else {
 876		// [Go] Allocate these slices elsewhere.
 877		if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) {
 878			return false
 879		}
 880		if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
 881			return false
 882		}
 883		if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) {
 884			return false
 885		}
 886	}
 887	return true
 888}
 889
 890// Write a scalar.
 891func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool {
 892	switch emitter.scalar_data.style {
 893	case yaml_PLAIN_SCALAR_STYLE:
 894		return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
 895
 896	case yaml_SINGLE_QUOTED_SCALAR_STYLE:
 897		return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
 898
 899	case yaml_DOUBLE_QUOTED_SCALAR_STYLE:
 900		return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
 901
 902	case yaml_LITERAL_SCALAR_STYLE:
 903		return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value)
 904
 905	case yaml_FOLDED_SCALAR_STYLE:
 906		return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value)
 907	}
 908	panic("unknown scalar style")
 909}
 910
 911// Check if a %YAML directive is valid.
 912func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool {
 913	if version_directive.major != 1 || version_directive.minor != 1 {
 914		return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive")
 915	}
 916	return true
 917}
 918
 919// Check if a %TAG directive is valid.
 920func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool {
 921	handle := tag_directive.handle
 922	prefix := tag_directive.prefix
 923	if len(handle) == 0 {
 924		return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty")
 925	}
 926	if handle[0] != '!' {
 927		return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'")
 928	}
 929	if handle[len(handle)-1] != '!' {
 930		return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'")
 931	}
 932	for i := 1; i < len(handle)-1; i += width(handle[i]) {
 933		if !is_alpha(handle, i) {
 934			return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only")
 935		}
 936	}
 937	if len(prefix) == 0 {
 938		return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty")
 939	}
 940	return true
 941}
 942
 943// Check if an anchor is valid.
 944func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool {
 945	if len(anchor) == 0 {
 946		problem := "anchor value must not be empty"
 947		if alias {
 948			problem = "alias value must not be empty"
 949		}
 950		return yaml_emitter_set_emitter_error(emitter, problem)
 951	}
 952	for i := 0; i < len(anchor); i += width(anchor[i]) {
 953		if !is_alpha(anchor, i) {
 954			problem := "anchor value must contain alphanumerical characters only"
 955			if alias {
 956				problem = "alias value must contain alphanumerical characters only"
 957			}
 958			return yaml_emitter_set_emitter_error(emitter, problem)
 959		}
 960	}
 961	emitter.anchor_data.anchor = anchor
 962	emitter.anchor_data.alias = alias
 963	return true
 964}
 965
 966// Check if a tag is valid.
 967func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {
 968	if len(tag) == 0 {
 969		return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")
 970	}
 971	for i := 0; i < len(emitter.tag_directives); i++ {
 972		tag_directive := &emitter.tag_directives[i]
 973		if bytes.HasPrefix(tag, tag_directive.prefix) {
 974			emitter.tag_data.handle = tag_directive.handle
 975			emitter.tag_data.suffix = tag[len(tag_directive.prefix):]
 976			return true
 977		}
 978	}
 979	emitter.tag_data.suffix = tag
 980	return true
 981}
 982
 983// Check if a scalar is valid.
 984func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 985	var (
 986		block_indicators   = false
 987		flow_indicators    = false
 988		line_breaks        = false
 989		special_characters = false
 990
 991		leading_space  = false
 992		leading_break  = false
 993		trailing_space = false
 994		trailing_break = false
 995		break_space    = false
 996		space_break    = false
 997
 998		preceded_by_whitespace = false
 999		followed_by_whitespace = false
1000		previous_space         = false
1001		previous_break         = false
1002	)
1003
1004	emitter.scalar_data.value = value
1005
1006	if len(value) == 0 {
1007		emitter.scalar_data.multiline = false
1008		emitter.scalar_data.flow_plain_allowed = false
1009		emitter.scalar_data.block_plain_allowed = true
1010		emitter.scalar_data.single_quoted_allowed = true
1011		emitter.scalar_data.block_allowed = false
1012		return true
1013	}
1014
1015	if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) {
1016		block_indicators = true
1017		flow_indicators = true
1018	}
1019
1020	preceded_by_whitespace = true
1021	for i, w := 0, 0; i < len(value); i += w {
1022		w = width(value[i])
1023		followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
1024
1025		if i == 0 {
1026			switch value[i] {
1027			case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`':
1028				flow_indicators = true
1029				block_indicators = true
1030			case '?', ':':
1031				flow_indicators = true
1032				if followed_by_whitespace {
1033					block_indicators = true
1034				}
1035			case '-':
1036				if followed_by_whitespace {
1037					flow_indicators = true
1038					block_indicators = true
1039				}
1040			}
1041		} else {
1042			switch value[i] {
1043			case ',', '?', '[', ']', '{', '}':
1044				flow_indicators = true
1045			case ':':
1046				flow_indicators = true
1047				if followed_by_whitespace {
1048					block_indicators = true
1049				}
1050			case '#':
1051				if preceded_by_whitespace {
1052					flow_indicators = true
1053					block_indicators = true
1054				}
1055			}
1056		}
1057
1058		if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode {
1059			special_characters = true
1060		}
1061		if is_space(value, i) {
1062			if i == 0 {
1063				leading_space = true
1064			}
1065			if i+width(value[i]) == len(value) {
1066				trailing_space = true
1067			}
1068			if previous_break {
1069				break_space = true
1070			}
1071			previous_space = true
1072			previous_break = false
1073		} else if is_break(value, i) {
1074			line_breaks = true
1075			if i == 0 {
1076				leading_break = true
1077			}
1078			if i+width(value[i]) == len(value) {
1079				trailing_break = true
1080			}
1081			if previous_space {
1082				space_break = true
1083			}
1084			previous_space = false
1085			previous_break = true
1086		} else {
1087			previous_space = false
1088			previous_break = false
1089		}
1090
1091		// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
1092		preceded_by_whitespace = is_blankz(value, i)
1093	}
1094
1095	emitter.scalar_data.multiline = line_breaks
1096	emitter.scalar_data.flow_plain_allowed = true
1097	emitter.scalar_data.block_plain_allowed = true
1098	emitter.scalar_data.single_quoted_allowed = true
1099	emitter.scalar_data.block_allowed = true
1100
1101	if leading_space || leading_break || trailing_space || trailing_break {
1102		emitter.scalar_data.flow_plain_allowed = false
1103		emitter.scalar_data.block_plain_allowed = false
1104	}
1105	if trailing_space {
1106		emitter.scalar_data.block_allowed = false
1107	}
1108	if break_space {
1109		emitter.scalar_data.flow_plain_allowed = false
1110		emitter.scalar_data.block_plain_allowed = false
1111		emitter.scalar_data.single_quoted_allowed = false
1112	}
1113	if space_break || special_characters {
1114		emitter.scalar_data.flow_plain_allowed = false
1115		emitter.scalar_data.block_plain_allowed = false
1116		emitter.scalar_data.single_quoted_allowed = false
1117		emitter.scalar_data.block_allowed = false
1118	}
1119	if line_breaks {
1120		emitter.scalar_data.flow_plain_allowed = false
1121		emitter.scalar_data.block_plain_allowed = false
1122	}
1123	if flow_indicators {
1124		emitter.scalar_data.flow_plain_allowed = false
1125	}
1126	if block_indicators {
1127		emitter.scalar_data.block_plain_allowed = false
1128	}
1129	return true
1130}
1131
1132// Check if the event data is valid.
1133func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {
1134
1135	emitter.anchor_data.anchor = nil
1136	emitter.tag_data.handle = nil
1137	emitter.tag_data.suffix = nil
1138	emitter.scalar_data.value = nil
1139
1140	switch event.typ {
1141	case yaml_ALIAS_EVENT:
1142		if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) {
1143			return false
1144		}
1145
1146	case yaml_SCALAR_EVENT:
1147		if len(event.anchor) > 0 {
1148			if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
1149				return false
1150			}
1151		}
1152		if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) {
1153			if !yaml_emitter_analyze_tag(emitter, event.tag) {
1154				return false
1155			}
1156		}
1157		if !yaml_emitter_analyze_scalar(emitter, event.value) {
1158			return false
1159		}
1160
1161	case yaml_SEQUENCE_START_EVENT:
1162		if len(event.anchor) > 0 {
1163			if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
1164				return false
1165			}
1166		}
1167		if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
1168			if !yaml_emitter_analyze_tag(emitter, event.tag) {
1169				return false
1170			}
1171		}
1172
1173	case yaml_MAPPING_START_EVENT:
1174		if len(event.anchor) > 0 {
1175			if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
1176				return false
1177			}
1178		}
1179		if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
1180			if !yaml_emitter_analyze_tag(emitter, event.tag) {
1181				return false
1182			}
1183		}
1184	}
1185	return true
1186}
1187
1188// Write the BOM character.
1189func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {
1190	if !flush(emitter) {
1191		return false
1192	}
1193	pos := emitter.buffer_pos
1194	emitter.buffer[pos+0] = '\xEF'
1195	emitter.buffer[pos+1] = '\xBB'
1196	emitter.buffer[pos+2] = '\xBF'
1197	emitter.buffer_pos += 3
1198	return true
1199}
1200
1201func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {
1202	indent := emitter.indent
1203	if indent < 0 {
1204		indent = 0
1205	}
1206	if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {
1207		if !put_break(emitter) {
1208			return false
1209		}
1210	}
1211	for emitter.column < indent {
1212		if !put(emitter, ' ') {
1213			return false
1214		}
1215	}
1216	emitter.whitespace = true
1217	emitter.indention = true
1218	return true
1219}
1220
1221func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool {
1222	if need_whitespace && !emitter.whitespace {
1223		if !put(emitter, ' ') {
1224			return false
1225		}
1226	}
1227	if !write_all(emitter, indicator) {
1228		return false
1229	}
1230	emitter.whitespace = is_whitespace
1231	emitter.indention = (emitter.indention && is_indention)
1232	emitter.open_ended = false
1233	return true
1234}
1235
1236func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {
1237	if !write_all(emitter, value) {
1238		return false
1239	}
1240	emitter.whitespace = false
1241	emitter.indention = false
1242	return true
1243}
1244
1245func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {
1246	if !emitter.whitespace {
1247		if !put(emitter, ' ') {
1248			return false
1249		}
1250	}
1251	if !write_all(emitter, value) {
1252		return false
1253	}
1254	emitter.whitespace = false
1255	emitter.indention = false
1256	return true
1257}
1258
1259func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool {
1260	if need_whitespace && !emitter.whitespace {
1261		if !put(emitter, ' ') {
1262			return false
1263		}
1264	}
1265	for i := 0; i < len(value); {
1266		var must_write bool
1267		switch value[i] {
1268		case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']':
1269			must_write = true
1270		default:
1271			must_write = is_alpha(value, i)
1272		}
1273		if must_write {
1274			if !write(emitter, value, &i) {
1275				return false
1276			}
1277		} else {
1278			w := width(value[i])
1279			for k := 0; k < w; k++ {
1280				octet := value[i]
1281				i++
1282				if !put(emitter, '%') {
1283					return false
1284				}
1285
1286				c := octet >> 4
1287				if c < 10 {
1288					c += '0'
1289				} else {
1290					c += 'A' - 10
1291				}
1292				if !put(emitter, c) {
1293					return false
1294				}
1295
1296				c = octet & 0x0f
1297				if c < 10 {
1298					c += '0'
1299				} else {
1300					c += 'A' - 10
1301				}
1302				if !put(emitter, c) {
1303					return false
1304				}
1305			}
1306		}
1307	}
1308	emitter.whitespace = false
1309	emitter.indention = false
1310	return true
1311}
1312
1313func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
1314	if !emitter.whitespace {
1315		if !put(emitter, ' ') {
1316			return false
1317		}
1318	}
1319
1320	spaces := false
1321	breaks := false
1322	for i := 0; i < len(value); {
1323		if is_space(value, i) {
1324			if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) {
1325				if !yaml_emitter_write_indent(emitter) {
1326					return false
1327				}
1328				i += width(value[i])
1329			} else {
1330				if !write(emitter, value, &i) {
1331					return false
1332				}
1333			}
1334			spaces = true
1335		} else if is_break(value, i) {
1336			if !breaks && value[i] == '\n' {
1337				if !put_break(emitter) {
1338					return false
1339				}
1340			}
1341			if !write_break(emitter, value, &i) {
1342				return false
1343			}
1344			emitter.indention = true
1345			breaks = true
1346		} else {
1347			if breaks {
1348				if !yaml_emitter_write_indent(emitter) {
1349					return false
1350				}
1351			}
1352			if !write(emitter, value, &i) {
1353				return false
1354			}
1355			emitter.indention = false
1356			spaces = false
1357			breaks = false
1358		}
1359	}
1360
1361	emitter.whitespace = false
1362	emitter.indention = false
1363	if emitter.root_context {
1364		emitter.open_ended = true
1365	}
1366
1367	return true
1368}
1369
1370func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
1371
1372	if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) {
1373		return false
1374	}
1375
1376	spaces := false
1377	breaks := false
1378	for i := 0; i < len(value); {
1379		if is_space(value, i) {
1380			if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) {
1381				if !yaml_emitter_write_indent(emitter) {
1382					return false
1383				}
1384				i += width(value[i])
1385			} else {
1386				if !write(emitter, value, &i) {
1387					return false
1388				}
1389			}
1390			spaces = true
1391		} else if is_break(value, i) {
1392			if !breaks && value[i] == '\n' {
1393				if !put_break(emitter) {
1394					return false
1395				}
1396			}
1397			if !write_break(emitter, value, &i) {
1398				return false
1399			}
1400			emitter.indention = true
1401			breaks = true
1402		} else {
1403			if breaks {
1404				if !yaml_emitter_write_indent(emitter) {
1405					return false
1406				}
1407			}
1408			if value[i] == '\'' {
1409				if !put(emitter, '\'') {
1410					return false
1411				}
1412			}
1413			if !write(emitter, value, &i) {
1414				return false
1415			}
1416			emitter.indention = false
1417			spaces = false
1418			breaks = false
1419		}
1420	}
1421	if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) {
1422		return false
1423	}
1424	emitter.whitespace = false
1425	emitter.indention = false
1426	return true
1427}
1428
1429func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
1430	spaces := false
1431	if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) {
1432		return false
1433	}
1434
1435	for i := 0; i < len(value); {
1436		if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) ||
1437			is_bom(value, i) || is_break(value, i) ||
1438			value[i] == '"' || value[i] == '\\' {
1439
1440			octet := value[i]
1441
1442			var w int
1443			var v rune
1444			switch {
1445			case octet&0x80 == 0x00:
1446				w, v = 1, rune(octet&0x7F)
1447			case octet&0xE0 == 0xC0:
1448				w, v = 2, rune(octet&0x1F)
1449			case octet&0xF0 == 0xE0:
1450				w, v = 3, rune(octet&0x0F)
1451			case octet&0xF8 == 0xF0:
1452				w, v = 4, rune(octet&0x07)
1453			}
1454			for k := 1; k < w; k++ {
1455				octet = value[i+k]
1456				v = (v << 6) + (rune(octet) & 0x3F)
1457			}
1458			i += w
1459
1460			if !put(emitter, '\\') {
1461				return false
1462			}
1463
1464			var ok bool
1465			switch v {
1466			case 0x00:
1467				ok = put(emitter, '0')
1468			case 0x07:
1469				ok = put(emitter, 'a')
1470			case 0x08:
1471				ok = put(emitter, 'b')
1472			case 0x09:
1473				ok = put(emitter, 't')
1474			case 0x0A:
1475				ok = put(emitter, 'n')
1476			case 0x0b:
1477				ok = put(emitter, 'v')
1478			case 0x0c:
1479				ok = put(emitter, 'f')
1480			case 0x0d:
1481				ok = put(emitter, 'r')
1482			case 0x1b:
1483				ok = put(emitter, 'e')
1484			case 0x22:
1485				ok = put(emitter, '"')
1486			case 0x5c:
1487				ok = put(emitter, '\\')
1488			case 0x85:
1489				ok = put(emitter, 'N')
1490			case 0xA0:
1491				ok = put(emitter, '_')
1492			case 0x2028:
1493				ok = put(emitter, 'L')
1494			case 0x2029:
1495				ok = put(emitter, 'P')
1496			default:
1497				if v <= 0xFF {
1498					ok = put(emitter, 'x')
1499					w = 2
1500				} else if v <= 0xFFFF {
1501					ok = put(emitter, 'u')
1502					w = 4
1503				} else {
1504					ok = put(emitter, 'U')
1505					w = 8
1506				}
1507				for k := (w - 1) * 4; ok && k >= 0; k -= 4 {
1508					digit := byte((v >> uint(k)) & 0x0F)
1509					if digit < 10 {
1510						ok = put(emitter, digit+'0')
1511					} else {
1512						ok = put(emitter, digit+'A'-10)
1513					}
1514				}
1515			}
1516			if !ok {
1517				return false
1518			}
1519			spaces = false
1520		} else if is_space(value, i) {
1521			if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 {
1522				if !yaml_emitter_write_indent(emitter) {
1523					return false
1524				}
1525				if is_space(value, i+1) {
1526					if !put(emitter, '\\') {
1527						return false
1528					}
1529				}
1530				i += width(value[i])
1531			} else if !write(emitter, value, &i) {
1532				return false
1533			}
1534			spaces = true
1535		} else {
1536			if !write(emitter, value, &i) {
1537				return false
1538			}
1539			spaces = false
1540		}
1541	}
1542	if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) {
1543		return false
1544	}
1545	emitter.whitespace = false
1546	emitter.indention = false
1547	return true
1548}
1549
1550func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool {
1551	if is_space(value, 0) || is_break(value, 0) {
1552		indent_hint := []byte{'0' + byte(emitter.best_indent)}
1553		if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) {
1554			return false
1555		}
1556	}
1557
1558	emitter.open_ended = false
1559
1560	var chomp_hint [1]byte
1561	if len(value) == 0 {
1562		chomp_hint[0] = '-'
1563	} else {
1564		i := len(value) - 1
1565		for value[i]&0xC0 == 0x80 {
1566			i--
1567		}
1568		if !is_break(value, i) {
1569			chomp_hint[0] = '-'
1570		} else if i == 0 {
1571			chomp_hint[0] = '+'
1572			emitter.open_ended = true
1573		} else {
1574			i--
1575			for value[i]&0xC0 == 0x80 {
1576				i--
1577			}
1578			if is_break(value, i) {
1579				chomp_hint[0] = '+'
1580				emitter.open_ended = true
1581			}
1582		}
1583	}
1584	if chomp_hint[0] != 0 {
1585		if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {
1586			return false
1587		}
1588	}
1589	return true
1590}
1591
1592func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {
1593	if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {
1594		return false
1595	}
1596	if !yaml_emitter_write_block_scalar_hints(emitter, value) {
1597		return false
1598	}
1599	if !put_break(emitter) {
1600		return false
1601	}
1602	emitter.indention = true
1603	emitter.whitespace = true
1604	breaks := true
1605	for i := 0; i < len(value); {
1606		if is_break(value, i) {
1607			if !write_break(emitter, value, &i) {
1608				return false
1609			}
1610			emitter.indention = true
1611			breaks = true
1612		} else {
1613			if breaks {
1614				if !yaml_emitter_write_indent(emitter) {
1615					return false
1616				}
1617			}
1618			if !write(emitter, value, &i) {
1619				return false
1620			}
1621			emitter.indention = false
1622			breaks = false
1623		}
1624	}
1625
1626	return true
1627}
1628
1629func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {
1630	if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {
1631		return false
1632	}
1633	if !yaml_emitter_write_block_scalar_hints(emitter, value) {
1634		return false
1635	}
1636
1637	if !put_break(emitter) {
1638		return false
1639	}
1640	emitter.indention = true
1641	emitter.whitespace = true
1642
1643	breaks := true
1644	leading_spaces := true
1645	for i := 0; i < len(value); {
1646		if is_break(value, i) {
1647			if !breaks && !leading_spaces && value[i] == '\n' {
1648				k := 0
1649				for is_break(value, k) {
1650					k += width(value[k])
1651				}
1652				if !is_blankz(value, k) {
1653					if !put_break(emitter) {
1654						return false
1655					}
1656				}
1657			}
1658			if !write_break(emitter, value, &i) {
1659				return false
1660			}
1661			emitter.indention = true
1662			breaks = true
1663		} else {
1664			if breaks {
1665				if !yaml_emitter_write_indent(emitter) {
1666					return false
1667				}
1668				leading_spaces = is_blank(value, i)
1669			}
1670			if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {
1671				if !yaml_emitter_write_indent(emitter) {
1672					return false
1673				}
1674				i += width(value[i])
1675			} else {
1676				if !write(emitter, value, &i) {
1677					return false
1678				}
1679			}
1680			emitter.indention = false
1681			breaks = false
1682		}
1683	}
1684	return true
1685}