David K. Bainbridge | 528b318 | 2017-01-23 08:51:59 -0800 | [diff] [blame^] | 1 | package yaml |
| 2 | |
| 3 | // Set the writer error and return false. |
| 4 | func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool { |
| 5 | emitter.error = yaml_WRITER_ERROR |
| 6 | emitter.problem = problem |
| 7 | return false |
| 8 | } |
| 9 | |
| 10 | // Flush the output buffer. |
| 11 | func yaml_emitter_flush(emitter *yaml_emitter_t) bool { |
| 12 | if emitter.write_handler == nil { |
| 13 | panic("write handler not set") |
| 14 | } |
| 15 | |
| 16 | // Check if the buffer is empty. |
| 17 | if emitter.buffer_pos == 0 { |
| 18 | return true |
| 19 | } |
| 20 | |
| 21 | // If the output encoding is UTF-8, we don't need to recode the buffer. |
| 22 | if emitter.encoding == yaml_UTF8_ENCODING { |
| 23 | if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil { |
| 24 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) |
| 25 | } |
| 26 | emitter.buffer_pos = 0 |
| 27 | return true |
| 28 | } |
| 29 | |
| 30 | // Recode the buffer into the raw buffer. |
| 31 | var low, high int |
| 32 | if emitter.encoding == yaml_UTF16LE_ENCODING { |
| 33 | low, high = 0, 1 |
| 34 | } else { |
| 35 | high, low = 1, 0 |
| 36 | } |
| 37 | |
| 38 | pos := 0 |
| 39 | for pos < emitter.buffer_pos { |
| 40 | // See the "reader.c" code for more details on UTF-8 encoding. Note |
| 41 | // that we assume that the buffer contains a valid UTF-8 sequence. |
| 42 | |
| 43 | // Read the next UTF-8 character. |
| 44 | octet := emitter.buffer[pos] |
| 45 | |
| 46 | var w int |
| 47 | var value rune |
| 48 | switch { |
| 49 | case octet&0x80 == 0x00: |
| 50 | w, value = 1, rune(octet&0x7F) |
| 51 | case octet&0xE0 == 0xC0: |
| 52 | w, value = 2, rune(octet&0x1F) |
| 53 | case octet&0xF0 == 0xE0: |
| 54 | w, value = 3, rune(octet&0x0F) |
| 55 | case octet&0xF8 == 0xF0: |
| 56 | w, value = 4, rune(octet&0x07) |
| 57 | } |
| 58 | for k := 1; k < w; k++ { |
| 59 | octet = emitter.buffer[pos+k] |
| 60 | value = (value << 6) + (rune(octet) & 0x3F) |
| 61 | } |
| 62 | pos += w |
| 63 | |
| 64 | // Write the character. |
| 65 | if value < 0x10000 { |
| 66 | var b [2]byte |
| 67 | b[high] = byte(value >> 8) |
| 68 | b[low] = byte(value & 0xFF) |
| 69 | emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1]) |
| 70 | } else { |
| 71 | // Write the character using a surrogate pair (check "reader.c"). |
| 72 | var b [4]byte |
| 73 | value -= 0x10000 |
| 74 | b[high] = byte(0xD8 + (value >> 18)) |
| 75 | b[low] = byte((value >> 10) & 0xFF) |
| 76 | b[high+2] = byte(0xDC + ((value >> 8) & 0xFF)) |
| 77 | b[low+2] = byte(value & 0xFF) |
| 78 | emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3]) |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | // Write the raw buffer. |
| 83 | if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil { |
| 84 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) |
| 85 | } |
| 86 | emitter.buffer_pos = 0 |
| 87 | emitter.raw_buffer = emitter.raw_buffer[:0] |
| 88 | return true |
| 89 | } |