+ /* Move the unread characters to the beginning of the buffer. */
+
+ if (parser->buffer < parser->pointer
+ && parser->pointer < parser->buffer_end) {
+ size_t size = parser->buffer_end - parser->pointer;
+ memmove(parser->buffer, parser->pointer, size);
+ parser->pointer = parser->buffer;
+ parser->buffer_end -= size;
+ }
+ else if (parser->pointer == parser->buffer_end) {
+ parser->pointer = parser->buffer;
+ parser->buffer_end = parser->buffer;
+ }
+
+ /* Fill the buffer until it has enough characters. */
+
+ while (parser->unread < length)
+ {
+ /* Fill the raw buffer. */
+
+ if (!yaml_parser_update_raw_buffer(parser)) return 0;
+
+ /* Decode the raw buffer. */
+
+ while (parser->raw_unread)
+ {
+ unsigned int ch;
+ int incomplete = 0;
+
+ /* Decode the next character. */
+
+ switch (parser->encoding)
+ {
+ case YAML_UTF8_ENCODING:
+
+ unsigned int utf8_length = UTF8_LENGTH(parser->raw_pointer);
+ unsigned int utf8_chunk;
+
+ /* Check if the raw buffer contains an incomplete character. */
+
+ if (utf8_length > parser->raw_unread) {
+ if (parser->eof) {
+ parser->error = YAML_READER_ERROR;
+ return 0;
+ }
+ incomplete = 1;
+ }
+
+ /* Get the character checking it for validity. */
+
+ utf8_chunk = UTF8_FIRST_CHUNK(parser->raw_pointer ++);
+ if (utf8_chunk == 0xFF) {
+ parser->error = YAML_READER_ERROR;
+ return 0;
+ }
+ ch = utf8_chunk;
+ parser->raw_unread --;
+ while (-- utf8_length) {
+ utf8_chunk = UTF8_NEXT_CHUNK(parser->raw_pointer ++);
+ if (utf8_chunk == 0xFF) {
+ parser->error = YAML_READER_ERROR;
+ return 0;
+ }
+ ch = ch << 6 + utf8_chunk;
+ parser->raw_unread --;
+ }
+
+ break;
+
+ case YAML_UTF16LE_ENCODING:
+
+ /* Check if the raw buffer contains an incomplete character. */
+
+ if (parser->raw_unread < 2) {
+ if (parser->eof) {
+ parser->error = YAML_READER_ERROR;
+ return 0;
+ }
+ incomplete = 1;
+ }
+
+ /* Get the current character. */
+
+ ch = UTF16LE_CHAR(parser->raw_pointer);
+ parser->raw_pointer += 2;
+ parser->raw_unread -= 2;
+
+ break;
+
+ case YAML_UTF16BE_ENCODING:
+
+ /* Check if the raw buffer contains an incomplete character. */
+
+ if (parser->raw_unread < 2) {
+ if (parser->eof) {
+ parser->error = YAML_READER_ERROR;
+ return 0;
+ }
+ incomplete = 1;
+ }
+
+ /* Get the current character. */
+
+ ch = UTF16BE_CHAR(parser->raw_pointer);
+ parser->raw_pointer += 2;
+ parser->raw_unread -= 2;
+
+ break;
+ }
+
+ /*
+ * Check if the character is in the allowed range:
+ * #x9 | #xA | #xD | [#x20-#x7E] (8 bit)
+ * | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit)
+ * | [#x10000-#x10FFFF] (32 bit)
+ */
+
+ if (! (ch == 0x09 || ch == 0x0A || ch == 0x0D
+ || (ch >= 0x20 && ch <= 0x7E)
+ || (ch == 0x85) || (ch >= 0xA0 && ch <= 0xD7FF)
+ || (ch >= 0xE000 && ch <= 0xFFFD)
+ || (ch >= 0x10000 && ch <= 0x10FFFF))) {
+ parser->error = YAML_READER_ERROR;
+ return 0;
+ }
+
+ /* Finally put the character into the buffer. */
+
+ /* 0000 0000-0000 007F -> 0xxxxxxx */
+ if (ch <= 0x7F) {
+ *(parser->buffer_end++) = ch;
+ }
+ /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */
+ else if (ch <= 0x7FF) {
+ *(parser->buffer_end++) = 0xC0 + (ch >> 6) & 0x1F;
+ *(parser->buffer_end++) = 0x80 + ch & 0x3F;
+ }
+ /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
+ else if (ch <= 0xFFFF) {
+ *(parser->buffer_end++) = 0x80 + ch & 0x3F;
+ *(parser->buffer_end++) = 0xC0 + (ch >> 6) & 0x1F;
+
+ }
+ /* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+ else {
+ }