source: libyaml/trunk/src/writer.c @ 264

Revision 264, 3.6 KB checked in by xi, 6 years ago (diff)

Another round of API update.

Line 
1
2#include "yaml_private.h"
3
4/*
5 * Declarations.
6 */
7
8YAML_DECLARE(int)
9yaml_emitter_flush(yaml_emitter_t *emitter);
10
11/*
12 * Flush the output buffer.
13 */
14
15YAML_DECLARE(int)
16yaml_emitter_flush(yaml_emitter_t *emitter)
17{
18    int low, high;
19
20    assert(emitter);    /* Non-NULL emitter object is expected. */
21    assert(emitter->writer);    /* Write handler must be set. */
22    assert(emitter->encoding);  /* Output encoding must be set. */
23
24    /* Check if the buffer is empty. */
25
26    if (!emitter->output.pointer) {
27        return 1;
28    }
29
30    /* Switch the buffer into the input mode. */
31
32    emitter->output.length = emitter->output.pointer;
33    emitter->output.pointer = 0;
34
35    /* If the output encoding is UTF-8, we don't need to recode the buffer. */
36
37    if (emitter->encoding == YAML_UTF8_ENCODING)
38    {
39        if (emitter->writer(emitter->writer_data,
40                    emitter->output.buffer, emitter->output.length)) {
41            emitter->offset += emitter->output.length;
42            emitter->output.length = 0;
43            return 1;
44        }
45        else {
46            return WRITER_ERROR_INIT(emitter,
47                    "write handler error", emitter->offset);
48        }
49    }
50
51    /* Recode the buffer into the raw buffer. */
52
53    low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
54    high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
55
56    while (emitter->output.pointer < emitter->output.length)
57    {
58        unsigned char octet;
59        unsigned int width;
60        unsigned int value;
61        size_t idx;
62
63        /*
64         * See the "reader.c" code for more details on UTF-8 encoding.  Note
65         * that we assume that the buffer contains a valid UTF-8 sequence.
66         */
67
68        /* Read the next UTF-8 character. */
69
70        octet = OCTET(emitter->output);
71
72        width = (octet & 0x80) == 0x00 ? 1 :
73                (octet & 0xE0) == 0xC0 ? 2 :
74                (octet & 0xF0) == 0xE0 ? 3 :
75                (octet & 0xF8) == 0xF0 ? 4 : 0;
76
77        value = (octet & 0x80) == 0x00 ? octet & 0x7F :
78                (octet & 0xE0) == 0xC0 ? octet & 0x1F :
79                (octet & 0xF0) == 0xE0 ? octet & 0x0F :
80                (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
81
82        for (idx = 1; idx < width; idx ++) {
83            octet = OCTET_AT(emitter->output, idx);
84            value = (value << 6) + (octet & 0x3F);
85        }
86
87        emitter->output.pointer += width;
88
89        /* Write the character. */
90
91        if (value < 0x10000)
92        {
93            OCTET_AT(emitter->raw_output, high) = value >> 8;
94            OCTET_AT(emitter->raw_output, low) = value & 0xFF;
95
96            emitter->raw_output.pointer += 2;
97        }
98        else
99        {
100            /* Write the character using a surrogate pair (check "reader.c"). */
101
102            value -= 0x10000;
103            OCTET_AT(emitter->raw_output, high) = 0xD8 + (value >> 18);
104            OCTET_AT(emitter->raw_output, low) = (value >> 10) & 0xFF;
105            OCTET_AT(emitter->raw_output, high+2) = 0xDC + ((value >> 8) & 0xFF);
106            OCTET_AT(emitter->raw_output, low+2) = value & 0xFF;
107
108            emitter->raw_output.pointer += 4;
109        }
110    }
111
112    /* Write the raw buffer. */
113
114    if (emitter->writer(emitter->writer_data,
115                emitter->raw_output.buffer, emitter->raw_output.pointer)) {
116        emitter->output.pointer = 0;
117        emitter->output.length = 0;
118        emitter->offset += emitter->raw_output.pointer;
119        emitter->raw_output.pointer = 0;
120        return 1;
121    }
122    else {
123        return WRITER_ERROR_INIT(emitter,
124                "write handler error", emitter->offset);
125    }
126}
127
Note: See TracBrowser for help on using the repository browser.