Ruby  2.0.0p353(2013-11-22revision43784)
writer.c
Go to the documentation of this file.
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)
13 
14 /*
15  * Set the writer error and return 0.
16  */
17 
18 static int
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)
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 
static int yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem)
Definition: writer.c:19
The UTF-16-LE encoding with BOM.
Definition: yaml.h:103
The emitter structure.
Definition: yaml.h:1525
#define YAML_DECLARE(type)
The public API declaration.
Definition: yaml.h:38
#define const
Definition: strftime.c:102
yaml_emitter_flush(yaml_emitter_t *emitter)
Flush the accumulated characters to the output.
Definition: writer.c:32
The default UTF-8 encoding.
Definition: yaml.h:101
Cannot write to the output stream.
Definition: yaml.h:139
#define assert(condition)
Definition: ossl.h:45