source: trunk/packages/libyaml/src/writer.c @ 898

Last change on this file since 898 was 898, checked in by hartmans, 16 years ago

Add pyyaml and libyaml packages
backported from lenny.
There is discussion about how these should go in the repository; these are added in this form
in order to make forward progress.

File size: 4.0 KB
Line 
1
2#include "yaml_private.h"
3
4/*
5 * Declarations.
6 */
7
8static int
9yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem);
10
11YAML_DECLARE(int)
12yaml_emitter_flush(yaml_emitter_t *emitter);
13
14/*
15 * Set the writer error and return 0.
16 */
17
18static int
19yaml_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
31YAML_DECLARE(int)
32yaml_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
Note: See TracBrowser for help on using the repository browser.