1247738Sbapt 2247738Sbapt#include "yaml_private.h" 3247738Sbapt 4247738Sbapt/* 5247738Sbapt * Declarations. 6247738Sbapt */ 7247738Sbapt 8247738Sbaptstatic int 9247738Sbaptyaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem); 10247738Sbapt 11247738SbaptYAML_DECLARE(int) 12247738Sbaptyaml_emitter_flush(yaml_emitter_t *emitter); 13247738Sbapt 14247738Sbapt/* 15247738Sbapt * Set the writer error and return 0. 16247738Sbapt */ 17247738Sbapt 18247738Sbaptstatic int 19247738Sbaptyaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem) 20247738Sbapt{ 21247738Sbapt emitter->error = YAML_WRITER_ERROR; 22247738Sbapt emitter->problem = problem; 23247738Sbapt 24247738Sbapt return 0; 25247738Sbapt} 26247738Sbapt 27247738Sbapt/* 28247738Sbapt * Flush the output buffer. 29247738Sbapt */ 30247738Sbapt 31247738SbaptYAML_DECLARE(int) 32247738Sbaptyaml_emitter_flush(yaml_emitter_t *emitter) 33247738Sbapt{ 34247738Sbapt int low, high; 35247738Sbapt 36247738Sbapt assert(emitter); /* Non-NULL emitter object is expected. */ 37247738Sbapt assert(emitter->write_handler); /* Write handler must be set. */ 38247738Sbapt assert(emitter->encoding); /* Output encoding must be set. */ 39247738Sbapt 40247738Sbapt emitter->buffer.last = emitter->buffer.pointer; 41247738Sbapt emitter->buffer.pointer = emitter->buffer.start; 42247738Sbapt 43247738Sbapt /* Check if the buffer is empty. */ 44247738Sbapt 45247738Sbapt if (emitter->buffer.start == emitter->buffer.last) { 46247738Sbapt return 1; 47247738Sbapt } 48247738Sbapt 49247738Sbapt /* If the output encoding is UTF-8, we don't need to recode the buffer. */ 50247738Sbapt 51247738Sbapt if (emitter->encoding == YAML_UTF8_ENCODING) 52247738Sbapt { 53247738Sbapt if (emitter->write_handler(emitter->write_handler_data, 54247738Sbapt emitter->buffer.start, 55247738Sbapt emitter->buffer.last - emitter->buffer.start)) { 56247738Sbapt emitter->buffer.last = emitter->buffer.start; 57247738Sbapt emitter->buffer.pointer = emitter->buffer.start; 58247738Sbapt return 1; 59247738Sbapt } 60247738Sbapt else { 61247738Sbapt return yaml_emitter_set_writer_error(emitter, "write error"); 62247738Sbapt } 63247738Sbapt } 64247738Sbapt 65247738Sbapt /* Recode the buffer into the raw buffer. */ 66247738Sbapt 67247738Sbapt low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1); 68247738Sbapt high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0); 69247738Sbapt 70247738Sbapt while (emitter->buffer.pointer != emitter->buffer.last) 71247738Sbapt { 72247738Sbapt unsigned char octet; 73247738Sbapt unsigned int width; 74247738Sbapt unsigned int value; 75247738Sbapt size_t k; 76247738Sbapt 77247738Sbapt /* 78247738Sbapt * See the "reader.c" code for more details on UTF-8 encoding. Note 79247738Sbapt * that we assume that the buffer contains a valid UTF-8 sequence. 80247738Sbapt */ 81247738Sbapt 82247738Sbapt /* Read the next UTF-8 character. */ 83247738Sbapt 84247738Sbapt octet = emitter->buffer.pointer[0]; 85247738Sbapt 86247738Sbapt width = (octet & 0x80) == 0x00 ? 1 : 87247738Sbapt (octet & 0xE0) == 0xC0 ? 2 : 88247738Sbapt (octet & 0xF0) == 0xE0 ? 3 : 89247738Sbapt (octet & 0xF8) == 0xF0 ? 4 : 0; 90247738Sbapt 91247738Sbapt value = (octet & 0x80) == 0x00 ? octet & 0x7F : 92247738Sbapt (octet & 0xE0) == 0xC0 ? octet & 0x1F : 93247738Sbapt (octet & 0xF0) == 0xE0 ? octet & 0x0F : 94247738Sbapt (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; 95247738Sbapt 96247738Sbapt for (k = 1; k < width; k ++) { 97247738Sbapt octet = emitter->buffer.pointer[k]; 98247738Sbapt value = (value << 6) + (octet & 0x3F); 99247738Sbapt } 100247738Sbapt 101247738Sbapt emitter->buffer.pointer += width; 102247738Sbapt 103247738Sbapt /* Write the character. */ 104247738Sbapt 105247738Sbapt if (value < 0x10000) 106247738Sbapt { 107247738Sbapt emitter->raw_buffer.last[high] = value >> 8; 108247738Sbapt emitter->raw_buffer.last[low] = value & 0xFF; 109247738Sbapt 110247738Sbapt emitter->raw_buffer.last += 2; 111247738Sbapt } 112247738Sbapt else 113247738Sbapt { 114247738Sbapt /* Write the character using a surrogate pair (check "reader.c"). */ 115247738Sbapt 116247738Sbapt value -= 0x10000; 117247738Sbapt emitter->raw_buffer.last[high] = 0xD8 + (value >> 18); 118247738Sbapt emitter->raw_buffer.last[low] = (value >> 10) & 0xFF; 119247738Sbapt emitter->raw_buffer.last[high+2] = 0xDC + ((value >> 8) & 0xFF); 120247738Sbapt emitter->raw_buffer.last[low+2] = value & 0xFF; 121247738Sbapt 122247738Sbapt emitter->raw_buffer.last += 4; 123247738Sbapt } 124247738Sbapt } 125247738Sbapt 126247738Sbapt /* Write the raw buffer. */ 127247738Sbapt 128247738Sbapt if (emitter->write_handler(emitter->write_handler_data, 129247738Sbapt emitter->raw_buffer.start, 130247738Sbapt emitter->raw_buffer.last - emitter->raw_buffer.start)) { 131247738Sbapt emitter->buffer.last = emitter->buffer.start; 132247738Sbapt emitter->buffer.pointer = emitter->buffer.start; 133247738Sbapt emitter->raw_buffer.last = emitter->raw_buffer.start; 134247738Sbapt emitter->raw_buffer.pointer = emitter->raw_buffer.start; 135247738Sbapt return 1; 136247738Sbapt } 137247738Sbapt else { 138247738Sbapt return yaml_emitter_set_writer_error(emitter, "write error"); 139247738Sbapt } 140247738Sbapt} 141247738Sbapt 142