#endif
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
/**
* @defgroup version Version Information
YAML_UTF16BE_ENCODING
} yaml_encoding_t;
-/** @} */
-
-/*
-
+/** Many bad things could happen with the parser and emitter. */
typedef enum {
YAML_NO_ERROR,
YAML_EMITTER_ERROR
} yaml_error_type_t;
+/** @} */
+
+/*
+
typedef enum {
YAML_ANY_SCALAR_STYLE,
YAML_PLAIN_SCALAR_STYLE,
* source. The handler should write not more than @a size bytes to the @a
* buffer. The number of written bytes should be set to the @a length variable.
*
- * @param[in] ext A pointer to an application data specified by
- * @c yaml_parser_set_read_handler.
- * @param[out] buffer The buffer to write the data from the source.
- * @param[in] size The size of the buffer.
- * @param[out] length The actual number of bytes read from the source.
+ * @param[in] ext A pointer to an application data specified by
+ * @c yaml_parser_set_read_handler.
+ * @param[out] buffer The buffer to write the data from the source.
+ * @param[in] size The size of the buffer.
+ * @param[out] size_read The actual number of bytes read from the source.
*
* @returns On success, the handler should return @c 1. If the handler failed,
* the returned value should be @c 0. On EOF, the handler should set the
* @a length to @c 0 and return @c 1.
*/
-typedef int yaml_read_handler_t(void *ext, yaml_char_t *buffer, size_t size,
- size_t *length);
-
+typedef int yaml_read_handler_t(void *ext, unsigned char *buffer, size_t size,
+ size_t *size_read);
/**
* The parser structure.
typedef struct {
+ /**
+ * @name Error handling
+ * @{
+ */
+
+ error_type_t error;
+
+ /**
+ * @}
+ */
+
/**
* @name Reader stuff
* @{
*/
/** Read handler */
- yaml_read_handler_t *reader;
+ yaml_read_handler_t *read_handler;
/** A pointer for passing to the read handler. */
- void *reader_ext;
+ void *read_handler_data;
/** EOF flag */
int eof;
/** The pointer to the beginning of the working buffer. */
yaml_char_t *buffer;
+ /** The size of the buffer (in bytes). */
+ size_t buffer_size;
+
/** The pointer to the current character in the working buffer. */
- yaml_char_t *pointer;
+ yaml_char_t *buffer_pointer;
+
+ /** The number of unread characters in the buffer (in characters). */
+ size_t buffer_length;
/** The remaining undecoded characters. */
unsigned char *raw_buffer;
- /** The size of the raw buffer. */
+ /** The size of the raw buffer (in bytes). */
size_t raw_buffer_size;
+ /** Is the application responsible for freeing the raw buffer? */
+ int raw_buffer_foreign;
+
/** The input encoding. */
yaml_encoding_t encoding;
+ /** The offset of the current position (in bytes). */
+ size_t offset;
+
+ /** The index of the current position (in characters). */
+ size_t index;
+
+ /** The line of the current position (starting from @c 0). */
+ size_t line;
+
+ /** The column of the current position (starting from @c 0). */
+ size_t column;
+
/**
* @}
*/
void
yaml_parser_delete(yaml_parser_t *parser);
+/**
+ * Set a string input.
+ *
+ * Note that the @a input pointer must be valid while the @a parser object
+ * exists. The application is responsible for destroing @a input after
+ * destroying the @a parser.
+ *
+ * @param[in] parser A parser object.
+ * @param[in] input A source data.
+ * @param[in] length The length of the source data in bytes.
+ */
+
+void
+yaml_parser_set_input_string(yaml_parser_t *parser,
+ unsigned char *input, size_t size);
+
+
+/**
+ * Set a file input.
+ *
+ * @a file should be a file object open for reading. The application is
+ * responsible for closing the @a file.
+ *
+ * @param[in] parser A parser object.
+ * @param[in] file An open file.
+ */
+
+void
+yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file);
+
+/**
+ * Set a generic input handler.
+ *
+ * @param[in] parser A parser object.
+ * @param[in] handler A read handler.
+ * @param[in] data Any application data for passing to the read handler.
+ */
+
+void
+yaml_parser_set_input(yaml_parser_t *parser,
+ yaml_read_handler_t *handler, void *data);
+
+/**
+ * Set the source encoding.
+ *
+ * @param[in] encoding The source encoding.
+ */
+
+void
+yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding);
+
/** @} */
/*
} yaml_emitter_t;
*/
+/**
+ * @defgroup internal Internal Definitions
+ * @{
+ */
+
+/**
+ * Allocate a dynamic memory block.
+ *
+ * @param[in] size Size of a memory block, \c 0 is valid.
+ *
+ * @returns @c yaml_malloc returns a pointer to a newly allocated memory block,
+ * or @c NULL if it failed.
+ */
+
+void *
+yaml_malloc(size_t size);
+
+/**
+ * Reallocate a dynamic memory block.
+ *
+ * @param[in] ptr A pointer to an existing memory block, \c NULL is
+ * valid.
+ * @param[in] size A size of a new block, \c 0 is valid.
+ *
+ * @returns @c yaml_realloc returns a pointer to a reallocated memory block,
+ * or @c NULL if it failed.
+ */
+
+void *
+yaml_realloc(void *ptr, size_t size);
+
+/**
+ * Free a dynamic memory block.
+ *
+ * @param[in] ptr A pointer to an existing memory block, \c NULL is
+ * valid.
+ */
+
+void
+yaml_free(void *ptr);
+
+/** @} */
+
+
#ifdef __cplusplus
}
#endif
AM_CPPFLAGS = -I$(top_srcdir)/include
lib_LTLIBRARIES = libyaml.la
-libyaml_la_SOURCES = version.c api.c
+libyaml_la_SOURCES = version.c api.c reader.c
libyaml_la_LDFLAGS = -release $(YAML_LT_RELEASE) -version-info $(YAML_LT_CURRENT):$(YAML_LT_REVISION):$(YAML_LT_AGE)
#include <yaml/yaml.h>
+#include <assert.h>
+
+/*
+ * Allocate a dynamic memory block.
+ */
+
+void *
+yaml_malloc(size_t size)
+{
+ return malloc(size ? size : 1);
+}
+
+/*
+ * Reallocate a dynamic memory block.
+ */
+
+void *
+yaml_realloc(void *ptr, size_t size)
+{
+ return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1);
+}
+
/*
- * Create a new parser.
+ * Free a dynamic memory block.
+ */
+
+void
+yaml_free(void *ptr)
+{
+ if (ptr) free(ptr);
+}
+
+/*
+ * Create a new parser object.
*/
yaml_parser_t *
{
yaml_parser_t *parser;
- parser = malloc(sizeof(yaml_parser_t));
+ parser = yaml_malloc(sizeof(yaml_parser_t));
if (!parser) return NULL;
memset(parser, 0, sizeof(yaml_parser_t));
void
yaml_parser_delete(yaml_parser_t *parser)
{
- free(parser);
+ assert(parser); /* Non-NULL parser object expected. */
+
+ yaml_free(parser->buffer);
+ if (!parser->raw_buffer_foreign)
+ yaml_free(parser->raw_buffer);
+
+ memset(parser, 0, sizeof(yaml_parser_t));
+
+ yaml_free(parser);
+}
+
+/*
+ * String read handler (always returns error).
+ */
+
+static int
+yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
+ size_t *size_read)
+{
+ *size_read = 0;
+ return 1;
+}
+
+/*
+ * File read handler.
+ */
+
+static int
+yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
+ size_t *size_read)
+{
+ *size_read = fread(buffer, 1, size, (FILE *)ext);
+ return !ferror((FILE *)ext);
+}
+
+/*
+ * Set a string input.
+ */
+
+void
+yaml_parser_set_input_string(yaml_parser_t *parser,
+ unsigned char *input, size_t size)
+{
+ assert(parser); /* Non-NULL parser object expected. */
+ assert(!parser->reader); /* You can set the source only once. */
+ assert(input); /* Non-NULL input string expected. */
+
+ parser->read_handler = yaml_string_read_handler;
+ parser->read_handler_data = NULL;
+
+ /* We use the input string as a raw (undecoded) buffer. */
+ parser->raw_buffer = input;
+ parser->raw_buffer_size = size;
+ parser->raw_buffer_foreign = 1;
+}
+
+/*
+ * Set a file input.
+ */
+
+void
+yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
+{
+ assert(parser); /* Non-NULL parser object expected. */
+ assert(!parser->reader); /* You can set the source only once. */
+ assert(file); /* Non-NULL file object expected. */
+
+ parser->read_handler = yaml_file_read_handler;
+ parser->read_handler_data = file;
+}
+
+/*
+ * Set a generic input.
+ */
+
+void
+yaml_parser_set_input(yaml_parser_t *parser,
+ yaml_read_handler_t *handler, void *data)
+{
+ assert(parser); /* Non-NULL parser object expected. */
+ assert(!parser->reader); /* You can set the source only once. */
+ assert(handler); /* Non-NULL read handler expected. */
+
+ parser->read_handler = handler;
+ parser->read_handler_data = data
+}
+
+/*
+ * Set the source encoding.
+ */
+
+void
+yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
+{
+ assert(parser); /* Non-NULL parser object expected. */
+ assert(!parser->encoding); /* Encoding is already set or detected. */
+
+ parser->encoding = encoding;
}
--- /dev/null
+
+#define RAW_BUFFER_SIZE 16384
+#define BUFFER_SIZE (RAW_BUFFER_SIZE*2) /* Should be enough for decoding
+ the whole raw buffer. */
+
+/*
+ * Ensure that the buffer contains at least length characters.
+ * Return 1 on success, 0 on failure.
+ */
+
+int
+yaml_parser_update_reader(yaml_parser_t *parser, size_t length)
+{
+ /* If the EOF flag is set, do nothing. */
+
+ if (parser->eof)
+ return 1;
+
+ /* First, let us check that the buffers are allocated. */
+
+ if (!parser->buffer) {
+ parser->buffer = yaml_malloc(BUFFER_SIZE);
+ if (!parser->buffer) {
+ parser->error = YAML_MEMORY_ERROR;
+ return 0;
+ }
+ parser->buffer_size = BUFFER_SIZE;
+ parser->buffer_pointer = parser->buffer;
+ parser->buffer_length = 0;
+ }
+
+ if (!parser->raw_buffer) {
+ parser->raw_buffer = yaml_malloc(RAW_BUFFER_SIZE);
+ if (!parser->raw_buffer) {
+ parser->error = YAML_MEMORY_ERROR;
+ return 0;
+ }
+ parser->raw_buffer_size = RAW_BUFFER_SIZE;
+ }
+
+ /* Next, determine the input encoding. */
+
+ if (!parser->encoding) {
+ if (!yaml_parser_determine_encoding(parser))
+ return 0;
+ }
+
+ /* more... */
+
+}
+
+
+