yaml/writerc.go (68 lines of code) (raw):

/** * This file is a Go port of its corresponding C file in libyaml. This port * was was copied from the yaml.v2 library. This file is licensed as follows: * * Copyright (c) 2006 Kirill Simonov * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ package yaml // Set the writer error and return false. func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool { emitter.error = yaml_WRITER_ERROR emitter.problem = problem return false } // Flush the output buffer. func yaml_emitter_flush(emitter *yaml_emitter_t) bool { if emitter.write_handler == nil { panic("write handler not set") } // Check if the buffer is empty. if emitter.buffer_pos == 0 { return true } // If the output encoding is UTF-8, we don't need to recode the buffer. if emitter.encoding == yaml_UTF8_ENCODING { if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil { return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) } emitter.buffer_pos = 0 return true } // Recode the buffer into the raw buffer. var low, high int if emitter.encoding == yaml_UTF16LE_ENCODING { low, high = 0, 1 } else { high, low = 1, 0 } pos := 0 for pos < emitter.buffer_pos { // See the "reader.c" code for more details on UTF-8 encoding. Note // that we assume that the buffer contains a valid UTF-8 sequence. // Read the next UTF-8 character. octet := emitter.buffer[pos] var w int var value rune switch { case octet&0x80 == 0x00: w, value = 1, rune(octet&0x7F) case octet&0xE0 == 0xC0: w, value = 2, rune(octet&0x1F) case octet&0xF0 == 0xE0: w, value = 3, rune(octet&0x0F) case octet&0xF8 == 0xF0: w, value = 4, rune(octet&0x07) } for k := 1; k < w; k++ { octet = emitter.buffer[pos+k] value = (value << 6) + (rune(octet) & 0x3F) } pos += w // Write the character. if value < 0x10000 { var b [2]byte b[high] = byte(value >> 8) b[low] = byte(value & 0xFF) emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1]) } else { // Write the character using a surrogate pair (check "reader.c"). var b [4]byte value -= 0x10000 b[high] = byte(0xD8 + (value >> 18)) b[low] = byte((value >> 10) & 0xFF) b[high+2] = byte(0xDC + ((value >> 8) & 0xFF)) b[low+2] = byte(value & 0xFF) emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3]) } } // Write the raw buffer. if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil { return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) } emitter.buffer_pos = 0 emitter.raw_buffer = emitter.raw_buffer[:0] return true }