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