Mercurial > embed
comparison yaml/src/writer.c @ 1:4d89bd8a3f7f
yaml: import 0.1.5
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 24 Feb 2016 20:50:29 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:0047655db1aa | 1:4d89bd8a3f7f |
---|---|
1 | |
2 #include "yaml_private.h" | |
3 | |
4 /* | |
5 * Declarations. | |
6 */ | |
7 | |
8 static int | |
9 yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem); | |
10 | |
11 YAML_DECLARE(int) | |
12 yaml_emitter_flush(yaml_emitter_t *emitter); | |
13 | |
14 /* | |
15 * Set the writer error and return 0. | |
16 */ | |
17 | |
18 static int | |
19 yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem) | |
20 { | |
21 emitter->error = YAML_WRITER_ERROR; | |
22 emitter->problem = problem; | |
23 | |
24 return 0; | |
25 } | |
26 | |
27 /* | |
28 * Flush the output buffer. | |
29 */ | |
30 | |
31 YAML_DECLARE(int) | |
32 yaml_emitter_flush(yaml_emitter_t *emitter) | |
33 { | |
34 int low, high; | |
35 | |
36 assert(emitter); /* Non-NULL emitter object is expected. */ | |
37 assert(emitter->write_handler); /* Write handler must be set. */ | |
38 assert(emitter->encoding); /* Output encoding must be set. */ | |
39 | |
40 emitter->buffer.last = emitter->buffer.pointer; | |
41 emitter->buffer.pointer = emitter->buffer.start; | |
42 | |
43 /* Check if the buffer is empty. */ | |
44 | |
45 if (emitter->buffer.start == emitter->buffer.last) { | |
46 return 1; | |
47 } | |
48 | |
49 /* If the output encoding is UTF-8, we don't need to recode the buffer. */ | |
50 | |
51 if (emitter->encoding == YAML_UTF8_ENCODING) | |
52 { | |
53 if (emitter->write_handler(emitter->write_handler_data, | |
54 emitter->buffer.start, | |
55 emitter->buffer.last - emitter->buffer.start)) { | |
56 emitter->buffer.last = emitter->buffer.start; | |
57 emitter->buffer.pointer = emitter->buffer.start; | |
58 return 1; | |
59 } | |
60 else { | |
61 return yaml_emitter_set_writer_error(emitter, "write error"); | |
62 } | |
63 } | |
64 | |
65 /* Recode the buffer into the raw buffer. */ | |
66 | |
67 low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1); | |
68 high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0); | |
69 | |
70 while (emitter->buffer.pointer != emitter->buffer.last) | |
71 { | |
72 unsigned char octet; | |
73 unsigned int width; | |
74 unsigned int value; | |
75 size_t k; | |
76 | |
77 /* | |
78 * See the "reader.c" code for more details on UTF-8 encoding. Note | |
79 * that we assume that the buffer contains a valid UTF-8 sequence. | |
80 */ | |
81 | |
82 /* Read the next UTF-8 character. */ | |
83 | |
84 octet = emitter->buffer.pointer[0]; | |
85 | |
86 width = (octet & 0x80) == 0x00 ? 1 : | |
87 (octet & 0xE0) == 0xC0 ? 2 : | |
88 (octet & 0xF0) == 0xE0 ? 3 : | |
89 (octet & 0xF8) == 0xF0 ? 4 : 0; | |
90 | |
91 value = (octet & 0x80) == 0x00 ? octet & 0x7F : | |
92 (octet & 0xE0) == 0xC0 ? octet & 0x1F : | |
93 (octet & 0xF0) == 0xE0 ? octet & 0x0F : | |
94 (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; | |
95 | |
96 for (k = 1; k < width; k ++) { | |
97 octet = emitter->buffer.pointer[k]; | |
98 value = (value << 6) + (octet & 0x3F); | |
99 } | |
100 | |
101 emitter->buffer.pointer += width; | |
102 | |
103 /* Write the character. */ | |
104 | |
105 if (value < 0x10000) | |
106 { | |
107 emitter->raw_buffer.last[high] = value >> 8; | |
108 emitter->raw_buffer.last[low] = value & 0xFF; | |
109 | |
110 emitter->raw_buffer.last += 2; | |
111 } | |
112 else | |
113 { | |
114 /* Write the character using a surrogate pair (check "reader.c"). */ | |
115 | |
116 value -= 0x10000; | |
117 emitter->raw_buffer.last[high] = 0xD8 + (value >> 18); | |
118 emitter->raw_buffer.last[low] = (value >> 10) & 0xFF; | |
119 emitter->raw_buffer.last[high+2] = 0xDC + ((value >> 8) & 0xFF); | |
120 emitter->raw_buffer.last[low+2] = value & 0xFF; | |
121 | |
122 emitter->raw_buffer.last += 4; | |
123 } | |
124 } | |
125 | |
126 /* Write the raw buffer. */ | |
127 | |
128 if (emitter->write_handler(emitter->write_handler_data, | |
129 emitter->raw_buffer.start, | |
130 emitter->raw_buffer.last - emitter->raw_buffer.start)) { | |
131 emitter->buffer.last = emitter->buffer.start; | |
132 emitter->buffer.pointer = emitter->buffer.start; | |
133 emitter->raw_buffer.last = emitter->raw_buffer.start; | |
134 emitter->raw_buffer.pointer = emitter->raw_buffer.start; | |
135 return 1; | |
136 } | |
137 else { | |
138 return yaml_emitter_set_writer_error(emitter, "write error"); | |
139 } | |
140 } | |
141 |